要生成正弦波,主要就是通过sin()函数用角度计算出每个点的值就行,下面看一下C代码的实现
#define PointMax 64
#define PI 3.1415926
unsigned int sinData[PointMax] = {0};
//point 一个周期内采样的点数
//生成一个周期正弦波 水平线为32 最大值为64 最小值为0
void get_sin_tab( unsigned int point )
{
unsigned int i = 0, j = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2;
hd = PI / j;
for( i = 0; i < point; i++ )
{
fz = j * sin( hd * i ) + j;
tem = ( unsigned int )fz;
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
int main()
{
get_sin_tab(64);
system("pause");
return 0;
}
复制代码
打印的数据如下:
32,35,38,41,44,47,49,52,54,56,58,60,61,62,63,63,64,63,63,62,
61,60,58,56,54,52,49,47,44,41,38,35,32,28,25,22,19,16,14,11,
9,7,5,3,2,1,0,0,0,0,0,1,2,3,5,7,9,11,14,16,19,22,25,28
生成的正弦波图形如下:
这种方法将点数的个数作为最大值,比如生成64个点,那么最大值就是64,如果生成128个点,最大值就是128.
下面再看一种可以设置点数和最大值的方法
int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = k * sin( hd * i ) + k; //i=0时sin(0)=0 起始点为最大值一半,也就是起始点是水平线位置 弧度值为π/2内每个点对应的弧度值
tem = ( unsigned int )(fz * 1.0); //通过系数可以调整输出有效值大小
sinData[i] = tem;
printf("%d\r\n",tem);
}
}
int main()
{
get_sin_tab1(64,800);
system("pause");
return 0;
}
复制代码
生成点如下:
400,439,478,516,553,588,622,653,682,709,732,752,769,782,792,798,800,798,792,782,
769,752,732,709,682,653,622,588,553,516,478,439,400,360,321,283,246,211,177,146,
117,90,67,47,30,17,7,1,0,1,7,17,30,47,67,90,117,146,177,211,246,283,321,360
生成图形如下
生成64个点,最大值为800.
下面改变一下波形的起始相位。
//point 一个周期内的点数
// 0为最小值 maxnum为最大值
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = k * sin( hd * (i + 180) ) + k; //i=0时 起点值为0
tem = ( unsigned int )(fz * 1.0); //通过系数可以调整输出有效值大小
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
生成数据如下:
30,47,67,90,117,146,177,211,246,283,321,360,400,439,478,516,553,588,622,653,682,
709,732,752,769,782,792,798,800,798,792,782,769,752,732,709,682,653,622,588,553,
516,478,439,400,360,321,283,246,211,177,146,117,90,67,47,30,17,7,1,0,1,7,17
波形为
继续改动一下计算公式
//point 一个周期内的点数
// 0为最小值 maxnum为最大值
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = k * sin( hd * (i + 270) ) + k; //i=0时 起点值最大
tem = ( unsigned int )(fz * 1.0); //通过系数可以调整输出有效值大小
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
数据:
792,798,800,798,792,782,769,752,732,709,682,653,622,588,553,516,478,439,400,360,
321,283,246,211,177,146,117,90,67,47,30,17,7,1,0,1,7,17,30,47,67,90,117,146,177,
211,246,283,321,360,399,439,478,516,553,588,622,653,682,709,732,752,769,782,
波形:
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = maxnum * sin( hd /2 * i ); //i=0时 sin(0)=0 起始点为0 也就是起点值为最小值 弧度值为π内每个点对应的弧度值
tem = ( unsigned int )(fz * 1.0); //通过系数可以调整输出有效值大小
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
数据
0,39,78,117,156,194,232,269,306,342,377,411,444,476,507,537,565,592,618,642,665,
686,705,723,739,753,765,776,784,791,796,799,800,799,796,791,784,776,765,753,739,
723,705,686,665,642,618,592,565,537,507,476,444,411,377,342,306,269,232,194,156,
117,78,39,
波形:
继续调整一下算法
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = maxnum - maxnum * sin( hd /2 * i );
tem = ( unsigned int )(fz * 1.0); //通过系数可以调整输出有效值大小
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
生成数据
800,760,721,682,643,605,567,530,493,457,422,388,355,323,292,262,234,207,181,157,
134,113,94,76,60,46,34,23,15,8,3,0,0,0,3,8,15,23,34,46,60,76,94,113,134,157,181,
207,234,262,292,323,355,388,422,457,493,530,567,605,643,682,721,760
生成图形
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = k * sin( hd * i ) + k;
tem = ( unsigned int )(fz * 1.0);
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
生成数据
400,439,478,516,553,588,622,653,682,709,732,752,769,782,792,798,800,798,792,782,
769,752,732,709,682,653,622,588,553,516,478,439,400,360,321,283,246,211,177,146,
117,90,67,47,30,17,7,1,0,1,7,17,30,47,67,90,117,146,177,211,246,283,321,360,
生成波形
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = k * sin( hd * i + PI / 2) + k;
tem = ( unsigned int )(fz * 1.0);
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
生成数据
800,798,792,782,769,752,732,709,682,653,622,588,553,516,478,439,400,360,321,283,
246,211,177,146,117,90,67,47,30,17,7,1,0,1,7,17,30,47,67,90,117,146,177,211,246,
283,321,360,400,439,478,516,553,588,622,653,682,709,732,752,769,782,792,798
生成波形
void get_sin_tab1( unsigned int point, unsigned int maxnum )
{
unsigned int i = 0, j = 0, k = 0;
float hd = 0.0; //弧度
float fz = 0.0; //峰值
unsigned int tem = 0;
j = point / 2; //水平线位置 单片机没有负电压 水平线为点值数量的一半
hd = PI / j; // π/2 内每一个点对应的弧度值
k = maxnum / 2; //最大值一半
for( i = 0; i < point; i++ )
{
fz = k * sin( hd * i + PI / 2 + PI ) + k;
tem = ( unsigned int )(fz * 1.0);
sinData[i] = tem;
printf("%d,",tem);
}
printf("\r\n");
}
复制代码
生成数据
0,1,7,17,30,47,67,90,117,146,177,211,246,283,321,360,399,439,478,516,553,588,622
,653,682,709,732,752,769,782,792,798,800,798,792,782,769,752,732,709,682,653,622
,588,553,516,478,439,400,360,321,283,246,211,177,146,117,90,67,47,30,17,7,1
生成图形
通过上面几种示例可以看出,不同的计算公式生成的数据也略有差异,但是本质还是对于弧度的转换。