admin 2025-11-15 09:36:43 养成攻略

蜂鸣器模块化编程 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

#include

//蜂鸣器端口:

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

{

Buzzer=!Buzzer;

Buzzer_Delay500us();

}

}

蜂鸣器中BEEP接口接入进电机中12号引脚,P15控制12号引脚,也就是P15高低电平控制蜂鸣器的高低电平。

如何让蜂鸣器响?首先我们要确定蜂鸣器的频率,也就是需要控制高电平低电平交替的周期。

for(i=0;i

这段函数控制了蜂鸣器以高电平低电平进行交替。高电平维持 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

我们已经固定了蜂鸣器的频率,为1000HZ,我们控制蜂鸣器鸣响ms毫秒,因此需要执行Delay500us延时函数ms*2次。

#include 头文件,对应使用_nop_();语句。

_nop_();在编程中通常表示一个空操作(no-operation)。它是一个什么也不做的指令,用于占位或确保代码结构的完整性,而不产生任何效果。在单周期指令中,可以通过晶振频率计算出具体的延时时间,例如对于 12M 晶振,延时 1 微秒(uS)。

利用定时器让蜂鸣器以特定频率响 ms 毫秒

//Timer0.h

#ifndef __TIMER0_H__

#define __TIMER0_H__

void Timer0Init(void);

#endif

//Timer0.c

#include

/**

* @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

#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。响完之后关闭定时器。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

作者:妖精七七_