蜂鸣器模块化编程 1000HZ 鸣响 ms 毫秒
//Buzzer.h
#ifndef __BUZZER_H__
#define __BUZZER_H__void Buzzer_Time(unsigned int ms);#endif
Buzzer.h
文件中只含有一个Buzzer_Time
函数,这个函数用来让蜂鸣器以1000HZ
固定频率发声ms
毫秒。
//Buzzer.c
#include <REGX52.H>
#include <INTRINS.H>//蜂鸣器端口:
sbit Buzzer=P1^5;/*** @brief 蜂鸣器私有延时函数,延时500us* @param 无* @retval 无*/
void Buzzer_Delay500us() //@12.000MHz
{unsigned char i;_nop_();i = 247;while (--i);
}/*** @brief 蜂鸣器发声* @param ms 发声的时长,范围:0~32767* @retval 无*/
void Buzzer_Time(unsigned int ms)
{unsigned int i;for(i=0;i<ms*2;i++){Buzzer=!Buzzer;Buzzer_Delay500us();}
}
蜂鸣器中BEEP
接口接入进电机中12
号引脚,P15
控制12
号引脚,也就是P15
高低电平控制蜂鸣器的高低电平。
如何让蜂鸣器响?首先我们要确定蜂鸣器的频率,也就是需要控制高电平低电平交替的周期。
for(i=0;i<ms*2;i++)
{
Buzzer=!Buzzer;
Buzzer_Delay500us();
}
这段函数控制了蜂鸣器以高电平低电平进行交替。高电平维持 500 微秒,低电平维持 500 微秒,一个周期就是 1 毫秒,频率则为 1s/1ms=1000HZ,秒/毫秒等价于乘以 1000。
//蜂鸣器端口:
sbit Buzzer=P1^5;
sbit
是用于定义特殊功能寄存器的位变量的关键字。在 C51 扩展的变量类型中,sbit
和bit
都是可以用来定义位操作的变量类型。通过使用sbit
关键字,可以为特定的端口上的位取一个名字,这样就可以直接通过这个名字来访问和操作这些位,而不需要知道它们在内存中的具体地址。例如,在代码中使用sbit P0_0=P0^0;
这样的语句,就是将P0_0
定义为P0
口的第1
位,这样做是为了便于进行位操作。
在给定的问题中,sbit Buzzer=P1^5;
的含义是定义了一个名为Buzzer
的变量,这个变量指向P1
口的第5
位。也就是P1_5
。
其次我们需要控制蜂鸣器的鸣响时间,也就是以确定的周期为单位运行的总时长。
for(i=0;i<ms*2;i++)
{
Buzzer=!Buzzer;
Buzzer_Delay500us();
}
我们已经固定了蜂鸣器的频率,为1000HZ
,我们控制蜂鸣器鸣响ms
毫秒,因此需要执行Delay500us
延时函数ms*2
次。
#include <INTRINS.H>
头文件,对应使用_nop_();
语句。
_nop_();
在编程中通常表示一个空操作(no-operation)。它是一个什么也不做的指令,用于占位或确保代码结构的完整性,而不产生任何效果。在单周期指令中,可以通过晶振频率计算出具体的延时时间,例如对于 12M 晶振,延时 1 微秒(uS)。
利用定时器让蜂鸣器以特定频率响 ms 毫秒
//Timer0.h
#ifndef __TIMER0_H__
#define __TIMER0_H__void Timer0Init(void);#endif
//Timer0.c
#include <REGX52.H>/*** @brief 定时器0初始化,1毫秒@12.000MHz* @param 无* @retval 无*/
void Timer0Init(void)
{TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0=1;EA=1;PT0=0;
}/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{static unsigned int T0Count;TL0 = 0x18; //设置定时初值TH0 = 0xFC; //设置定时初值T0Count++;if(T0Count>=1000){T0Count=0;}
}
*/
定时器初始化函数里面是定时器最基本的配置。
TR0 = 1
表示启动定时器,TR0 = 0
表示关闭定时器。
TL0 = 0x18;
TH0 = 0xFC;
两条语句是设置定时器开始计时的初值。
定时器启动之后,会从初值开始计时,直到超过65536us
,此时打断进程去执行中断函数。
也就是定时器最多计时65536us
。
如果想要记录1s
的时间,可以定义一个T0count
变量记录有多少个1ms
,1s=1000*1ms
。
也就是我们需要让计时器记录1ms
的时间,然后中断函数执行1000
次的时候就是1s
。
让定时器记录1ms
就需要改变定时器的初值,让初值等于64536us
,此时过1ms
之后定时器就会执行一次中断函数。
定时器每一次执行中断函数时,初值会默认置0
,所以我们可以在中断函数中维护初值为64536us
。
定义初值为64536us
,只需要TL0=64536%256;TH0=64536/256
即可。
TL0
表示低四位,TH0
表示高四位,对256
取余表示取低四位,除以256
表示取高四位。
//Delay.h
#ifndef __DELAY_H__
#define __DELAY_H__void Delay(unsigned int xms);#endif
//Delay.c
void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
//mian.c
#include <REGX52.H>
#include "Timer0.h"
#include "Delay.h"
//蜂鸣器端口定义
sbit Buzzer=P2^5;
int us=500;
void main(){Timer0Init();TR0=0;while(1){if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);TR0=1;TL0=(65536-us)%256;TH0=(65536-us)/256;Delay(100);TR0=0;}}
}void Timer0_Routine() interrupt 1{
// int us_max=65536;// int us_num=us_max-us;TL0=(65536-us)%256;TH0=(65536-us)/256;Buzzer=!Buzzer;
}
我们需要控制蜂鸣器的频率和持续时间,控制频率相当于控制翻转蜂鸣器 IO 口的周期。只需要控制定时器即可。
int us=500;
void Timer0_Routine() interrupt 1{
// int us_max=65536;
// int us_num=us_max-us;
TL0=(65536-us)%256;
TH0=(65536-us)/256;
Buzzer=!Buzzer;
}
定时器计时时长为500us
,也就是500us
翻转一次蜂鸣器IO
口,蜂鸣器周期为1ms
,频率为1s/1ms=1000HZ
。
以1000HZ
的频率让蜂鸣器响。
void main(){
Timer0Init();
TR0=0;
对定时器初始化之后先关闭定时器。 while(1){
if(P3_1==0){
Delay(20);
while(P3_1==0);
Delay(20);
TR0=1;
TL0=(65536-us)%256;
TH0=(65536-us)/256;
Delay(100);
TR0=0;
}
}
当我们按下K1
按键(对应P3_1=0
)并且抬起按键的时候,启动定时器,并且修改定时器的初值,此时我们延时100ms
,也就是让蜂鸣器以1000HZ
响100ms
。响完之后关闭定时器。
结尾
最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!