我们现在要给单片机IO端口输出4khz的方波。
现在我们算出方波的周期:1/(4*1000)s=0.00025s=0.25ms
高电平时间:(0.25/2)ms=0.125ms 低电平时间:(0.25/2)ms=0.125ms
因为我们只写过最低延时1ms的函数,所以这里测试用“for(i=0;i<14;i++);”作为延时0.125ms,本节的单片机IO端口为开发板中的P1.6,无源蜂鸣器的硬件连接因为不像LED那样都接了很多其他器件来初始化,所以本节的代码就显得相当简短,下载进开发板蜂鸣器就一直鸣叫了
#include <reg52.h> sbit BEEP = P1^6; void main() { unsigned int i; while(1) { BEEP=1; for(i=0;i<14;i++);//延时接近0.125ms,给P1.6保持了0.125ms高电平时间 BEEP=0; for(i=0;i<14;i++);//低电平时间保持了0.125ms, 我们可以尝试把两个for语句里的14改大一点就会发现鸣叫的音调变得低沉一些了 } }
我们现在引入新的代码书写知识“BEEP=!BEEP;”。
“!BEEP”是把此时自身的值非一下,比如当还没执行“BEEP =!BEEP;”语句时,假设此时的BEEP是等于1的。
当执行到“BEEP =!BEEP;”时,“!BEEP”是等于上一次的状态1变为0。
那现在的这条“BEEP =!BEEP;”就跟“BEEP=0;”是一样的了。
下一次再执行“BEEP =!BEEP;”时同理变为了“BEEP=1;”。
所以该语句实现的是来回变换赋给BEEP的值(0或1)。
这样我们就可以把上面的代码中while(1)部分简写为
while(1) { BEEP=!BEEP; for(i=0;i<14;i++);//只需改变一次for语句中的14就可以实现不同音调的鸣叫了 }
大家也可以回到第二章的第五讲改写为“LED2=!LED2”同样也可以实现LED闪烁的。
有同学会问,单片机的其他IO端口在程序里没有给0或1时,它们初始时是输出高电平还是低电平呢?
STC89C52RC这款芯片的P1,P2,P3这一共24个IO端口由于内部硬件的原因上电的时候都是输出高电平的,而P0一开始是一种不确定的状态(有时是高有时是低),但我们用的开发板已经把P0端口接了上拉电阻,所以开发板的P0.0~P0.7初始时也是输出高电平的(可参考《手把手教你学51单片机》文档2.4.1节的复位值和9.1节、9.2节的上下拉电阻了解一下,了解不了可暂时放一下,继续往下学)。
这也就解释了,当初点亮一盏灯的时候,代码没有写过P0.1,P0.2···这些内容,对应的这些灯都没有亮,只有在程序中写让P0.1输出0时灯才亮,所以其他灯不亮是因为IO端口已经默认输出了高电平。
这里我们先记住:所有的IO端口在程序初始时没有给0则全都是输出高电平这样的概念先。
本文固定URL:https://www.dotcpp.com/course/188