C51 使用定时器完成蜂鸣器,一秒响一声同时流水灯也一秒亮一下
时间: 2023-12-02 19:05:02 浏览: 169
关于定时器和蜂鸣器的配合
下面是使用C51单片机定时器完成蜂鸣器和流水灯的代码:
```c
#include <REGX52.H>
#define FREQ 11059200UL //定义晶振频率
#define TIMER_50MS_RELOAD (65536 - FREQ/12/20) //50ms定时器重载值
#define TIMER_500MS_RELOAD (65536 - FREQ/12/200) //500ms定时器重载值
sbit LED1 = P1^0; //流水灯LED1
sbit LED2 = P1^1; //流水灯LED2
sbit LED3 = P1^2; //流水灯LED3
sbit BEEP = P1^3; //蜂鸣器
void delay_ms(unsigned int ms); //延时函数
void timer0_init(); //50ms定时器初始化
void timer1_init(); //500ms定时器初始化
void main()
{
timer0_init(); //50ms定时器初始化
timer1_init(); //500ms定时器初始化
EA = 1; //开总中断
while(1)
{
//流水灯
LED1 = 1; LED2 = 0; LED3 = 0; delay_ms(1000);
LED1 = 0; LED2 = 1; LED3 = 0; delay_ms(1000);
LED1 = 0; LED2 = 0; LED3 = 1; delay_ms(1000);
//蜂鸣器
BEEP = 1; delay_ms(1000); BEEP = 0; delay_ms(1000);
}
}
void delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 114; j++); //大约延时1ms
}
void timer0_init()
{
TMOD &= 0xF0; //设置定时器0为模式1
TH0 = TIMER_50MS_RELOAD >> 8; //装载定时器初值
TL0 = TIMER_50MS_RELOAD & 0xFF;
ET0 = 1; //允许定时器0中断
TR0 = 1; //启动定时器0
}
void timer1_init()
{
TMOD &= 0x0F; //设置定时器1为模式1
TH1 = TIMER_500MS_RELOAD >> 8; //装载定时器初值
TL1 = TIMER_500MS_RELOAD & 0xFF;
ET1 = 1; //允许定时器1中断
TR1 = 1; //启动定时器1
}
void timer0_isr() interrupt 1
{
static unsigned char cnt = 0; //静态局部变量,用于计时
TH0 = TIMER_50MS_RELOAD >> 8; //重新装载定时器初值
TL0 = TIMER_50MS_RELOAD & 0xFF;
cnt++; //计时器加1
if(cnt >= 20) //50ms * 20 == 1s
{
cnt = 0; //计时器清零
BEEP = ~BEEP; //蜂鸣器状态翻转
}
}
void timer1_isr() interrupt 3
{
static unsigned char idx = 0; //静态局部变量,用于选择LED
TH1 = TIMER_500MS_RELOAD >> 8; //重新装载定时器初值
TL1 = TIMER_500MS_RELOAD & 0xFF;
idx++; //LED编号加1
if(idx > 3) idx = 1; //LED编号循环
switch(idx) //根据LED编号选择相应的LED
{
case 1: LED1 = ~LED1; break;
case 2: LED2 = ~LED2; break;
case 3: LED3 = ~LED3; break;
}
}
```
上面代码中,定时器0被设置为50ms模式1定时器,定时器1被设置为500ms模式1定时器。定时器0中断用于控制蜂鸣器的响声,定时器1中断用于控制流水灯的亮灭。
在主函数中,我们通过循环来控制流水灯和蜂鸣器的响声。注意,我们使用了延时函数`delay_ms()`来控制流水灯的亮灭,这个函数在定时器中断中不要使用,否则会影响定时器的工作。
当定时器0中断被触发时,蜂鸣器的状态会翻转,从而产生响声。当定时器1中断被触发时,LED的状态会翻转,从而实现流水灯的效果。在定时器中断中,我们使用了静态局部变量来记录计时器的值和LED的编号,从而实现了蜂鸣器和流水灯的控制。
阅读全文