51单片机做八位数码管可以显示当前的时间(时分秒各2位); 2)可以通过铵键设置时间;
时间: 2024-03-18 18:45:00 浏览: 15
好的,您需要用到的硬件有:51单片机、八位数码管、按键和电路连接线等;需要用到的软件有:Keil C51 编译器和 STC-ISP 下载软件。
首先,您需要将八位数码管连接到单片机的 IO 口上,并通过程序控制,实现数码管的显示功能;
其次,您需要编写程序,获取当前的时间,并将其显示在数码管上;
最后,您需要添加按键扫描程序,通过按键输入修改时间,并将修改后的时间存储在单片机的内部存储器中。
具体实现方法可以参考相关的单片机资料和代码示例,如有疑问可以继续咨询。
相关问题
编程实现51单片机做八位数码管可以显示当前的时间(时分秒各2位); 2)可以通过铵键设置时间;
好的,以下是一个简单的示例程序,可以实现您所需的功能。由于硬件连接方式不同,您可能需要根据自己的实际情况进行相应的调整。
```c
#include <reg52.h>
#include <intrins.h>
// 八位数码管共阴极接法
#define DIG1 P2_0
#define DIG2 P2_1
#define DIG3 P2_2
#define DIG4 P2_3
#define SEG P0
// 按键口定义
#define KEY P3
// 定时器0参数,用于1ms中断
#define T0RH 0xff
#define T0RL 0x06
// 定时器1参数,用于计时
#define T1RH 0x3c
#define T1RL 0xb0
// 定义全局变量,用于存储当前时间
unsigned char hour = 12;
unsigned char minute = 0;
unsigned char second = 0;
// 定义全局变量,用于存储按键状态
unsigned char key_state = 0;
// 数码管段码表
unsigned char code seg_table[] = {
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f, // 9
0x77, // A
0x7c, // b
0x39, // C
0x5e, // d
0x79, // E
0x71 // F
};
// 数码管位选表
unsigned char code dig_table[] = {
0x01, // 第1位
0x02, // 第2位
0x04, // 第3位
0x08 // 第4位
};
// 函数声明
void delay(unsigned int t);
void display(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4);
void key_scan(void);
void set_time(void);
// 主函数
void main(void) {
// 定时器0初始化,用于1ms中断
TMOD |= 0x01;
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1;
EA = 1;
TR0 = 1;
// 定时器1初始化,用于计时
TMOD |= 0x10;
TH1 = T1RH;
TL1 = T1RL;
ET1 = 1;
// 数码管位选口初始化
P2 = 0xf0;
while (1) {
key_scan(); // 按键扫描
display(hour / 10, hour % 10, minute / 10, minute % 10); // 显示时间
}
}
// 延时函数
void delay(unsigned int t) {
while (t--) {
_nop_();
_nop_();
_nop_();
_nop_();
}
}
// 数码管显示函数
void display(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4) {
unsigned char i;
unsigned char code *p = seg_table;
for (i = 0; i < 4; i++) {
DIG1 = DIG2 = DIG3 = DIG4 = 1; // 关闭所有位选
SEG = *p++; // 显示段码
switch (i) {
case 0: SEG |= dig_table[0]; DIG1 = 0; break; // 第1位,打开位选0
case 1: SEG |= dig_table[1]; DIG2 = 0; break; // 第2位,打开位选1
case 2: SEG |= dig_table[2]; DIG3 = 0; break; // 第3位,打开位选2
case 3: SEG |= dig_table[3]; DIG4 = 0; break; // 第4位,打开位选3
default: break;
}
delay(2); // 延时2ms
}
}
// 按键扫描函数
void key_scan(void) {
unsigned char key_value;
key_value = KEY & 0x0f; // 读取按键值
switch (key_state) {
case 0: // 等待按键按下
if (key_value != 0x0f) {
key_state = 1;
}
break;
case 1: // 等待按键释放
if (key_value == 0x0f) {
key_state = 2;
}
break;
case 2: // 按键已经按下并释放
if (key_value == 0x0e) { // 按键1按下,进入时间设置模式
key_state = 3;
set_time();
}
else { // 其他按键,恢复正常模式
key_state = 0;
}
break;
case 3: // 时间设置模式
break;
default: break;
}
}
// 时间设置函数
void set_time(void) {
unsigned char key_value;
// 显示当前时间
display(hour / 10, hour % 10, minute / 10, minute % 10);
// 等待按键按下
while ((key_value = KEY & 0x0f) == 0x0f);
// 按键1按下,修改小时
if (key_value == 0x0e) {
hour++;
if (hour > 23) {
hour = 0;
}
}
// 按键2按下,修改分钟
if (key_value == 0x0d) {
minute++;
if (minute > 59) {
minute = 0;
}
}
// 等待按键释放
while ((key_value = KEY & 0x0f) != 0x0f);
// 按键3按下,修改秒钟
if (key_value == 0x0b) {
second++;
if (second > 59) {
second = 0;
}
}
// 按键4按下,退出设置模式
if (key_value == 0x07) {
key_state = 0;
}
}
```
这个程序实现了计时、时间显示和时间设置功能,可以通过按键修改当前时间。在程序中,使用定时器0实现了1ms的定时中断,用于数码管显示和按键扫描;使用定时器1实现了1秒钟的计时功能。在主函数中,不断执行数码管显示和按键扫描,当按键按下时进入时间设置模式,可以通过按键修改时间,设置完成后退出设置模式。
单片机八位数码管显示时分秒
以下是一个使用单片机控制八位数码管显示时分秒的简单示例代码(假设使用的是共阳极数码管):
```
#include <reg52.h>
// 时分秒计数器,初始值为0
unsigned char hour = 0;
unsigned char minute = 0;
unsigned char second = 0;
// 数码管显示表,0~9的编码
unsigned char code displayTable[] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
};
// 数码管位选,控制哪一位数码管亮
unsigned char code digitSelectTable[] = {
0xFE, // 第1位数码管
0xFD, // 第2位数码管
0xFB, // 第3位数码管
0xF7, // 第4位数码管
0xEF, // 第5位数码管
0xDF, // 第6位数码管
0xBF, // 第7位数码管
0x7F, // 第8位数码管
};
// 延时函数,用于控制数码管亮的时间
void delay(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 1000; j++);
}
}
// 主函数
void main() {
// 初始化P0口为输出,用于控制数码管的段选
P0 = 0xFF;
// 初始化P2口为输出,用于控制数码管的位选
P2 = 0xFF;
// 无限循环
while (1) {
// 数码管显示时
P2 = digitSelectTable[0]; // 控制第1位数码管亮
P0 = displayTable[hour / 10]; // 显示小时的十位数
delay(5); // 延时一段时间,让数码管显示出来
P2 = digitSelectTable[1]; // 控制第2位数码管亮
P0 = displayTable[hour % 10]; // 显示小时的个位数
delay(5);
// 数码管显示分
P2 = digitSelectTable[2]; // 控制第3位数码管亮
P0 = displayTable[minute / 10]; // 显示分钟的十位数
delay(5);
P2 = digitSelectTable[3]; // 控制第4位数码管亮
P0 = displayTable[minute % 10]; // 显示分钟的个位数
delay(5);
// 数码管显示秒
P2 = digitSelectTable[4]; // 控制第5位数码管亮
P0 = displayTable[second / 10]; // 显示秒钟的十位数
delay(5);
P2 = digitSelectTable[5]; // 控制第6位数码管亮
P0 = displayTable[second % 10]; // 显示秒钟的个位数
delay(5);
// 计数器加1,每秒钟加1
second++;
if (second == 60) {
second = 0;
minute++;
}
if (minute == 60) {
minute = 0;
hour++;
}
if (hour == 24) {
hour = 0;
}
}
}
```
在该代码中,使用了一个计数器来记录时分秒,每秒钟计数器加1,同时在主循环中控制数码管显示时分秒。由于单片机的运行速度非常快,为了让数码管显示出来,需要在每次控制数码管显示之后延时一段时间,这里使用了一个简单的延时函数。注释中详细解释了代码的每一行具体作用。