仪器社区

51单片机信号发生器的正弦波程序

爱巴萨爱WT 2013-04-02
voidvout_sin(void)//输出正弦波{floatx;//用于正弦波发生器if(Voutsin())//“正弦波按键”被有效按下do{for(x=-3.1415;x<3.1415;x+=0.1)//正弦波发生器{vout=255*(1+sin(x))/2;//输出... void vout_sin(void) //输出正弦波
{ float x; //用于正弦波发生器
if(Voutsin()) //“正弦波按键”被有效按下
do{
for(x=-3.1415;x<3.1415;x+=0.1) //正弦波发生器
{ vout=255*(1+sin(x))/2; //输出值vout必须大于0
P1=vout;
delay_out();
} } while(P3_0==1&P3_1==1&P3_2==1&P3_4==1) } 此段程序中do{}内的内容不是很理解,希望好心网友帮忙解释一下,财富值不是很多,谢谢了。
评论
全部评论
370026575susu
首先,我要声明一点,单片机的浮点数处理能力非常弱的,你这个程序,基础可以用数组查表的方法来做,当然,你这么错不是不行,初学者可以用来做实验,但是高手可不会这么错。
言归正传,我来给你讲解一下这个do里面的思路。我们分步来看,先看sin(x),从 -3.1415---+3.1415
sin(x)的数值是多少?答案是0到-1再到0再到1再到0,这么个过程,这是高中的数学知识,如果你不明白,我就没有办法了。
搞明白了sin(x)的变化范围,我们就不难明白,如果不加以限制的,直接用 255*sin(x),那么,这个结果就会出现负数,变化范围是 0----(-255)---(0)----(255)---0,因为你需要把这个数值赋值给P1口,那么,你知道如果把一个负数赋值给 P1口是什么结果吗?因为负数在单片机里是用补码表示的,所以,把一个负数表示成无符号的数,它是很大的,所以P1口就会乱。
所以,为了避免负数,就要把sin(x)里产生的负数抵消去,怎么抵消?我们知道,sin(x)Z小值是 -1,所以,只要 (1 + sin(x)),那么,这个结果就永远不可能小于0,这个的变化范围是
1----0----1----2----1
Z大的数值是2,Z小的是0
然后乘以 255再给P1口送去,我们又知道,P1口Z大只能到 255,而你的式子(1 + sin(x))
Z大是2,(1 + sin(x))*255Z大得到的是 510,那为了不失真,所以,要把(1 + sin(x))*255再除以一个2,就得到你上面的结果了。
如果你是用的DA转换器,通过示波器,你可以看到一个如下公式的波形:
f = 2.5*sin(2*3.1415926*f) + 2.5
这样的函数波形。
18 0 2017-09-21 0条评论 回复
appless0083
这是典型do while语句啊
do表示先执行这其中的语句,当
while中的P3_0==1&P3_1==1&P3_2==1&P3_4==1 为真就输出正弦波,当P3_0==1&P3_1==1&P3_2==1&P3_4==1 只要其中一个不为1的话,正弦波输出不了
13 0 2013-04-03 0条评论 回复
宋依萍9
±π内的图像没隔0.1取一个点
1 0 2013-04-03 0条评论 回复
您可能感兴趣的社区主题
加载中...
发布 评论