51单片机使用P1口驱动3位7段共阴型数码管,使用P2.0-P2.2口选择用于显示的数码管,外部中断引脚INT0(P3.2)上连接了按键S1,用于中断计数,外部引脚P3.5(T1)上连接了按键S2,用于清零计数
时间: 2023-05-28 07:05:58 浏览: 85
。程序如下:
```c
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 数码管0-9显示表
uchar cnt = 0; // 计数器
uchar flag = 0; // 标志位,表示当前显示的是哪个数码管
void delay(uint t) // 延时函数
{
uint i, j;
for (i = 0; i < t; i++)
for (j = 0; j < 110; j++);
}
void display(uchar num) // 数码管显示函数
{
P1 = table[num]; // 将数码管显示的值写入P1口
}
void main()
{
TMOD = 0x05; // 定时器1工作在方式1,定时器0不用
TH1 = 0x3c; // 定时器1初值为0x3c
TL1 = 0xb0;
ET1 = 1; // 允许定时器1中断
EX0 = 1; // 允许外部中断0
IT0 = 1; // 外部中断0触发方式为下降沿触发
EA = 1; // 允许总中断
while (1)
{
if (flag == 0) // 当前显示的是第一个数码管
{
P2 = 0x01; // P2.0为低电平,选择第一个数码管
display(cnt / 100); // 显示百位数字
}
else if (flag == 1) // 当前显示的是第二个数码管
{
P2 = 0x02; // P2.1为低电平,选择第二个数码管
display(cnt % 100 / 10); // 显示十位数字
}
else // 当前显示的是第三个数码管
{
P2 = 0x04; // P2.2为低电平,选择第三个数码管
display(cnt % 10); // 显示个位数字
}
delay(5); // 延时一段时间,使数字更稳定
}
}
void timer1_isr() interrupt 3 // 定时器1中断服务函数,用于扫描数码管
{
TH1 = 0x3c; // 重新赋初值
TL1 = 0xb0;
flag++; // 切换到下一个数码管
if (flag >= 3) // 超过3个数码管则回到第一个数码管
flag = 0;
}
void ext0_isr() interrupt 0 // 外部中断0服务函数,用于计数
{
cnt++; // 计数器加1
}
void clear_cnt() // 清零计数函数
{
cnt = 0;
}
void keyscan() // 按键扫描函数
{
if (P3 & 0x20) // 检测按键S2是否按下
clear_cnt(); // 如果按下则清零计数
}
```
说明:
1. 使用定时器1扫描数码管,定时器1每次中断时会切换到下一个数码管进行显示。
2. 使用外部中断0计数,按下按键S1会触发外部中断0,计数器加1。
3. 使用外部引脚P3.5(T1)上的按键S2清零计数,检测P3.5口的状态,如果为高电平则表示按键未按下,如果为低电平则表示按键按下,此时调用清零计数函数。
4. 在主函数中循环显示计数器的值,根据flag的值选择显示哪个数码管的数字。
5. 定义延时函数delay,用于等待数字更稳定。
6. 定义数码管显示函数display,根据传入的数字在数码管上显示相应的数字。
阅读全文