51单片机编写完整代码,使小灯亮300ms灭1000ms的方式循环闪烁完整代码
时间: 2024-11-13 20:19:56 浏览: 3
51单片机使用定时器T0配合中断可以实现周期性的灯泡闪烁。这里以C语言和AT89S52作为示例,假设我们使用P1口的一个位来控制LED灯。以下是完整的代码:
```c
#include <reg52.h>
sbit LED = P1^0; // LED连接到P1.0口
// 计算300ms和1000ms对应的定时器计数值
unsigned int on_time = (65536 / 12) * 300; // 基于12MHz时钟,300ms约等于2048计数
unsigned int off_time = (65536 / 12) * 1000; // 1000ms约等于8192计数
void timer0_isr() interrupt 1 // 中断服务函数
{
TF0 = 0; // 清除溢出标志
if (TR0) { // 如果定时器正在运行
if (TH0 == 0 && TL0 == 0) { // 到达计数结束
TR0 = 0; // 停止定时器
LED = !LED; // 切换LED状态
} else { // 继续计数
TH0 = on_time >> 8;
TL0 = on_time & 0xFF;
}
}
}
void delay(unsigned int us) // 微秒级延时函数
{
unsigned long start = SystemCoreClock / 128; // 获取当前系统的主频并除以128
for (; us > 0; us -= start) {
__asm__ volatile("NOP"); // 添加空指令以减慢速度
}
}
int main(void)
{
EA = 1; // 开启全局中断
EINT(); // 关闭所有外设中断
ET0 = 1; // 开启T0中断
TR0 = 1; // 启动定时器T0
while(1) {
timer0_isr(); // 初始化定时器T0
delay(off_time); // 灯灭的时间
}
return 0;
}
```
在这个代码里,当定时器溢出时,中断服务函数会切换LED的状态(亮或灭),然后重新设置定时器计数。通过改变计数时间,实现了300ms亮、1000ms灭的循环闪烁。
阅读全文