某公司预设计一款倒计时产品+要求如下+按钮开关接在51单片机的非外部中断口+按钮开关按下+数码管从9开始倒计时+时间间隔为1S+到0后停止+并一直显示0+再次按下又从9开始倒计时
时间: 2023-11-19 15:04:09 浏览: 31
这是一个简单的倒计时器设计,可以使用51单片机和数码管来实现。具体实现步骤如下:
1. 首先需要连接数码管和51单片机,可以使用74HC595芯片来扩展IO口,控制数码管的显示。
2. 将按钮开关接在51单片机的非外部中断口,当按钮按下时触发中断,开始倒计时。
3. 在中断服务函数中,使用定时器来控制时间间隔为1S,每次定时器中断时将数码管的值减1,并显示在数码管上。
4. 当数码管的值减到0时,停止倒计时,并一直显示0。
5. 再次按下按钮时,重新开始倒计时,从9开始倒计时。
相关问题
51单片机 数码管显示,倒计时十分钟,一个按键按下,用串口中断将倒计时时间发送给电脑
好的,我可以为您解答这个问题。
首先,您需要连接一个 4 位共阴数码管到 51 单片机上。然后,您需要编写程序,使用定时器来倒计时 10 分钟,并将剩余时间显示在数码管上。
接下来,您需要连接一个按键到单片机上,并通过外部中断来检测按键的按下事件。当按键被按下时,您需要使用串口通信将剩余时间发送到电脑上。
以下是一个示例程序,实现了这个功能:
```
#include <reg51.h>
#define FREQ 11059200UL // 单片机时钟频率
#define BAUD 9600 // 串口波特率
sbit KEY = P3^2; // 按键引脚
sbit DIO = P0^0; // 数码管数据引脚
sbit CLK = P0^1; // 数码管时钟引脚
unsigned char second = 600; // 倒计时时间,初始值为 10 分钟
void delay(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < FREQ / 12000; j++);
}
}
void send_byte(unsigned char byte) {
unsigned char i;
for (i = 0; i < 8; i++) {
DIO = byte >> i & 0x01;
CLK = 1;
CLK = 0;
}
}
void display(unsigned char num) {
static unsigned char code[] = {
0x3f, 0x06, 0x5b, 0x4f, 0x66,
0x6d, 0x7d, 0x07, 0x7f, 0x6f
};
send_byte(code[num]);
}
void timer0_isr() interrupt 1 {
TH0 = 0xfc;
TL0 = 0x67;
display(second / 60 / 10 % 10);
delay(5);
display(second / 60 % 10);
delay(5);
display(second % 60 / 10);
delay(5);
display(second % 60 % 10);
delay(5);
second--;
}
void uart_init() {
TMOD |= 0x20; // 定时器1工作在方式2
TH1 = 256 - FREQ / 32 / BAUD; // 计算波特率
TL1 = TH1;
TR1 = 1; // 启动定时器1
SCON = 0x50; // 串口工作在方式1
ES = 1; // 允许串口中断
EA = 1; // 允许总中断
}
void uart_send(unsigned char byte) {
SBUF = byte;
while (!TI);
TI = 0;
}
void uart_isr() interrupt 4 {
if (RI) {
RI = 0;
}
if (TI) {
TI = 0;
}
}
void main() {
TMOD |= 0x01; // 定时器0工作在方式1
TH0 = 0xfc;
TL0 = 0x67;
ET0 = 1; // 允许定时器0中断
TR0 = 1; // 启动定时器0
uart_init();
while (1) {
if (!KEY) {
delay(20); // 去抖动
if (!KEY) {
uart_send(second);
}
while (!KEY);
}
}
}
```
在这个程序中,我们使用定时器0来每秒更新数码管上的倒计时时间,并且使用外部中断来检测按键的按下事件。当按键被按下时,我们通过串口通信将剩余时间发送到电脑上。
请注意,这个程序只是一个示例,您需要根据您的具体硬件和需求进行修改和优化。
给我写一个通过外部中断实现C51单片机控制的东南西北交通灯,并且在7段数码管上显示倒计时
好的,以下是一个简单的程序,实现了通过外部中断控制东南西北四个方向的交通灯,同时使用7段数码管显示倒计时。
```c
#include <reg51.h>
// 定义端口
sbit LED_NS = P2^0; // NS方向交通灯
sbit LED_EW = P2^1; // EW方向交通灯
sbit KEY = P3^2; // 外部中断按键
sbit DIO = P1^0; // 74HC595数据线
sbit CLK = P1^1; // 74HC595时钟线
sbit STB = P1^2; // 74HC595锁存线
// 定义变量
unsigned char time = 30; // 倒计时时间,初始值为30秒
// 延时函数
void delay(unsigned int t) {
unsigned int i, j;
for (i = 0; i < t; i++)
for (j = 0; j < 125; j++);
}
// 在7段数码管上显示数字
void display(unsigned char num) {
unsigned char i;
unsigned char code table[] = { // 数码管编码表
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f // 9
};
for (i = 0; i < 8; i++) {
DIO = ((table[num] >> i) & 0x01);
CLK = 1;
CLK = 0;
}
STB = 1;
STB = 0;
}
// 中断服务函数
void interrupt_0() interrupt 0 {
delay(10); // 延时去抖动
if (KEY == 0) { // 检测按键是否按下
time = 30; // 按下按键,重新设置倒计时时间为30秒
}
}
// 主函数
void main() {
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xfc; // 定时器0计时初值
TL0 = 0x66; // 定时器0计时初值
TR0 = 1; // 启动定时器0
ET0 = 1; // 开启定时器0中断
EA = 1; // 开启总中断
IT0 = 1; // 设置外部中断0触发方式为下降沿触发
EX0 = 1; // 开启外部中断0
while (1) {
LED_NS = 0; // NS方向绿灯亮
LED_EW = 1; // EW方向红灯亮
display(time); // 显示倒计时时间
while (time > 0) { // 倒计时
delay(1000);
time--;
display(time);
}
LED_NS = 1; // NS方向黄灯亮
delay(2000);
LED_NS = 0; // NS方向红灯亮
LED_EW = 1; // EW方向绿灯亮
display(time); // 显示倒计时时间
while (time > 0) { // 倒计时
delay(1000);
time--;
display(time);
}
LED_EW = 0; // EW方向黄灯亮
delay(2000);
LED_EW = 1; // EW方向红灯亮
}
}
```
说明:
1. 程序使用定时器0来实现倒计时功能,定时器0的计时初值为65536-50000=15536,计时时间为50ms,即每50ms中断一次,中断服务函数中检测外部中断按键是否按下,如果按下则重新设置倒计时时间为30秒。
2. 在主函数中,先点亮NS方向绿灯,EW方向红灯,然后显示倒计时时间,每隔1秒减1,直到倒计时时间为0。然后点亮NS方向黄灯2秒,再点亮NS方向红灯,EW方向绿灯,重复之前的操作。```display()```函数用于在7段数码管上显示数字,使用74HC595芯片进行驱动,详见代码注释。
注意:以上代码仅供参考,具体实现可根据硬件情况进行修改。