51单片机时钟设计 倒计时 整点报时 温度显示源代码
时间: 2023-10-29 13:22:41 浏览: 186
以下是51单片机时钟设计的源代码,包括时钟模块、温度检测模块、显示模块、倒计时模块和整点报时模块的实现。代码仅供参考,具体实现需要根据实际情况进行调整和优化。
```c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 数码管引脚定义
sbit DIG_1 = P2^0;
sbit DIG_2 = P2^1;
sbit DIG_3 = P2^2;
sbit DIG_4 = P2^3;
// 数码管段选引脚定义
sbit SEG_A = P0^0;
sbit SEG_B = P0^1;
sbit SEG_C = P0^2;
sbit SEG_D = P0^3;
sbit SEG_E = P0^4;
sbit SEG_F = P0^5;
sbit SEG_G = P0^6;
sbit SEG_DP = P0^7;
// 温度传感器引脚定义
sbit DQ = P1^0;
// 声音引脚定义
sbit BEEP = P1^1;
// 定时器初始化函数
void timer_init() {
TMOD = 0x01; // 定时器0,工作方式1
TH0 = 0xFC; // 1ms定时
TL0 = 0x67;
TR0 = 1; // 启动定时器
ET0 = 1; // 使能定时器0中断
EA = 1; // 使能总中断
}
// 数码管显示函数
void display(uchar *buf) {
uchar i;
for (i = 0; i < 4; i++) {
switch (i) {
case 0: // 显示百位
DIG_1 = 0;
DIG_2 = 1;
DIG_3 = 1;
DIG_4 = 1;
break;
case 1: // 显示十位
DIG_1 = 1;
DIG_2 = 0;
DIG_3 = 1;
DIG_4 = 1;
break;
case 2: // 显示个位
DIG_1 = 1;
DIG_2 = 1;
DIG_3 = 0;
DIG_4 = 1;
break;
case 3: // 显示小数点
DIG_1 = 1;
DIG_2 = 1;
DIG_3 = 1;
DIG_4 = 0;
break;
}
P0 = buf[i]; // 数码管段选
_nop_();
_nop_();
_nop_();
_nop_();
}
}
// 温度检测函数
uchar get_temp() {
uchar i, j;
uchar temp;
EA = 0; // 关闭总中断
DQ = 0; // 发送开始信号
_nop_();
_nop_();
_nop_();
_nop_();
DQ = 1;
while (DQ); // 等待DS18B20响应
_nop_();
_nop_();
_nop_();
_nop_();
for (i = 0; i < 8; i++) { // 读取8位温度数据
DQ = 0;
_nop_();
_nop_();
_nop_();
_nop_();
temp = temp >> 1;
if (DQ) {
temp |= 0x80;
}
_nop_();
_nop_();
_nop_();
_nop_();
DQ = 1;
}
EA = 1; // 重新打开总中断
return temp;
}
// 倒计时函数
void countdown(uint sec) {
while (sec > 0) {
display(" ");
delay(1000); // 延时1秒
sec--;
}
BEEP = 0; // 发出提示音
delay(500); // 延时500ms
BEEP = 1;
}
// 整点报时函数
void hour_report() {
BEEP = 0; // 发出提示音
delay(500); // 延时500ms
BEEP = 1;
}
// 定时器0中断处理函数
void timer0_isr() interrupt 1 {
static uchar cnt = 0;
static uchar sec = 0;
static uchar min = 0;
static uchar hour = 0;
static uint count_down = 0;
static uchar temp_buf[4] = {0};
uchar i;
uint temp;
cnt++;
if (cnt == 20) { // 20ms中断一次
cnt = 0;
// 温度检测
temp = get_temp();
temp_buf[0] = temp / 100;
temp_buf[1] = temp % 100 / 10;
temp_buf[2] = temp % 10;
temp_buf[3] = 0x40; // 小数点
// 倒计时
if (count_down > 0) {
count_down--;
if (count_down == 0) {
countdown(0);
}
}
// 整点报时
if (min == 0 && sec == 0 && hour > 0) {
hour_report();
}
sec++;
if (sec == 60) {
sec = 0;
min++;
if (min == 60) {
min = 0;
hour++;
if (hour == 24) {
hour = 0;
}
}
}
// 数码管显示
display(temp_buf);
}
}
// 主函数
void main() {
timer_init();
while (1) {
// 设置倒计时
if (/* 按键按下 */) {
count_down = 60 * 10; // 倒计时10分钟
}
// 设置整点报时
if (/* 按键按下 */) {
hour_report();
}
}
}
```
以上代码中,需要根据具体硬件和需求进行修改和调整。其中,需要注意的是:
1. 定时器中断周期需要根据实际情况进行调整,以保证时钟的准确性。
2. 温度传感器需要使用DS18B20或者其他支持1-Wire协议的传感器,需要根据传感器的使用手册进行连接和驱动。
3. 声音提示需要使用蜂鸣器或者其他输出设备,需要根据具体硬件进行调整。
4. 按键检测需要使用外部中断或者轮询方式实现,具体实现方式可以根据实际需求进行选择。
阅读全文