使用C语言产生正弦波数据

要生成正弦波,主要就是通过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

生成图形

通过上面几种示例可以看出,不同的计算公式生成的数据也略有差异,但是本质还是对于弧度的转换。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值