帮我写一个C51的程序,用中断延时函数实现一个按键控制静态数码管加,另一个按键实现led流水灯加蜂鸣器
时间: 2024-05-07 13:19:04 浏览: 104
好的,以下是基于C51的程序实现:
```c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
// 数码管段码对应表
uchar code segTable[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90
};
// 数码管位选对应表
uchar code digTable[] = {
0xFE, 0xFD, 0xFB, 0xF7
};
// 延时函数
void delay(uint ms)
{
uint i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 125; j++);
}
}
// 按键检测函数
uchar keyScan()
{
if (P3 != 0xFF) { // 检测是否有按键按下
delay(10); // 延时消除抖动
if (P3 != 0xFF) { // 再次检测是否有按键按下
switch (P3) {
case 0xFE: return 1; // 返回按下的按键编号
case 0xFD: return 2;
case 0xFB: return 3;
case 0xF7: return 4;
default: return 0; // 没有按键按下
}
}
}
return 0; // 没有按键按下
}
// 数码管显示函数
void display(uchar num)
{
P2 = segTable[num % 10]; // 显示个位
P1 = digTable[0]; delay(5); // 位选第1位
P2 = segTable[num / 10]; // 显示十位
P1 = digTable[1]; delay(5); // 位选第2位
}
// LED流水灯函数
void ledFlow()
{
uchar led = 0x01;
uchar i;
for (i = 0; i < 8; i++) {
P0 = led; // 点亮当前LED
led <<= 1; // 左移一位,准备点亮下一个LED
delay(50); // 延时一段时间,控制流水灯速度
}
}
// 主函数
void main()
{
uchar num = 0; // 用于存储数码管显示的数字
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xFC; TL0 = 0x67; // 设置定时器初值,实现50ms的定时
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
TR0 = 1; // 启动定时器0
while (1) {
switch (keyScan()) { // 检测按键
case 1: num++; break; // 按键1,数码管数字加1
case 2: ledFlow(); break; // 按键2,LED流水灯
}
}
}
// 定时器0中断服务函数
void timer0() interrupt 1
{
static uchar count = 0;
TH0 = 0xFC; TL0 = 0x67; // 重新设置定时器初值
count++;
if (count == 20) { // 50ms * 20 = 1s
count = 0;
P0 = ~P0; // 翻转P0口电平,实现蜂鸣器响声
}
display(num); // 数码管显示当前数字
}
```
以上程序使用了定时器中断实现定时延时和LED流水灯的效果,同时使用按键检测函数实现按键控制数码管数字的加减和LED流水灯加蜂鸣器的开关控制。
阅读全文