新建一个工程文件,在此工程文件下放入时钟,数码管,矩阵按键,蜂鸣器对应的.c文件,建立主函数,实现相应的函数调用,key1设定闹钟开,key2设置闹钟关,k3设定时间加一,keu4设定时间减一,key5设定秒,key6设定分,key7设定时,内部定时器在定时,并将时间显示在LED上,当设定时间到时,蜂鸣器响
时间: 2023-06-16 10:07:40 浏览: 79
关于定时器和蜂鸣器的配合
好的,下面我将为你提供一个大致的代码框架,你可以在此基础上进行完善和修改。
首先,我们需要在工程文件夹下创建一个头文件`alarm.h`,用于存放函数声明和宏定义:
```c
#ifndef _ALARM_H_
#define _ALARM_H_
#include <reg52.h>
/* 宏定义 */
#define uchar unsigned char
#define uint unsigned int
/* 数码管引脚定义 */
#define DIGIT_PORT P0
#define DIGIT_CTRL P2
/* 矩阵按键引脚定义 */
#define KEY_PORT P1
#define KEY_CTRL P3
/* 蜂鸣器引脚定义 */
#define BUZZER P2_3
/* 函数声明 */
void delay_ms(uint ms);
void init_timer0(void);
void init_key(void);
void init_display(void);
void display_time(uchar hour, uchar minute, uchar second);
uchar key_scan(void);
void alarm_on(void);
void alarm_off(void);
#endif
```
接下来,在工程目录下新建`alarm.c`文件,实现上述声明的函数:
```c
#include "alarm.h"
/* 定义全局变量 */
uchar hour = 0; // 时
uchar minute = 0; // 分
uchar second = 0; // 秒
uchar alarm_hour = 0; // 闹钟时
uchar alarm_minute = 0; // 闹钟分
uchar alarm_flag = 0; // 闹钟标志
/* 延时函数 */
void delay_ms(uint ms)
{
uint i, j;
for (i = ms; i > 0; i--)
for (j = 114; j > 0; j--);
}
/* 定时器初始化 */
void init_timer0(void)
{
TMOD |= 0x01; // 定时器0工作在模式1(16位定时器)
TH0 = 0xFC; // 定时器初值,50ms
TL0 = 0x18;
ET0 = 1; // 打开定时器0中断
EA = 1; // 打开总中断
TR0 = 1; // 启动定时器0
}
/* 按键初始化 */
void init_key(void)
{
KEY_PORT = 0xFF; // 将键盘初始值设为高电平
KEY_CTRL = 0x0F; // 将P1口的高4位设为输出
}
/* 数码管初始化 */
void init_display(void)
{
DIGIT_CTRL = 0x00; // 数码管段选初始值为0
DIGIT_PORT = 0xFF; // 数码管位选初始值为1
}
/* 数码管显示时间 */
void display_time(uchar hour, uchar minute, uchar second)
{
uchar i, j, k;
uchar code table[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // 数码管段选码表
uchar disp_buf[8] = {0};
// 将时间转化为位码
disp_buf[0] = table[hour / 10];
disp_buf[1] = table[hour % 10];
disp_buf[2] = table[minute / 10];
disp_buf[3] = table[minute % 10];
disp_buf[4] = table[second / 10];
disp_buf[5] = table[second % 10];
// 循环显示
for (i = 0; i < 6; i++)
{
DIGIT_PORT = ~(0x01 << i); // 选中位
for (j = 0, k = 0x01; j < 8; j++, k <<= 1) // 显示段
{
if (disp_buf[j] & k)
DIGIT_CTRL &= ~0x7F;
else
DIGIT_CTRL |= 0x7F;
delay_ms(1);
DIGIT_CTRL <<= 1;
}
}
}
/* 按键扫描 */
uchar key_scan(void)
{
uchar key_val = 0xFF;
KEY_CTRL |= 0xF0; // 将高4位设为输出,低4位设为输入
if ((KEY_PORT & 0xF0) != 0xF0) // 检测是否有键按下
{
delay_ms(20); // 延时去抖
if ((KEY_PORT & 0xF0) != 0xF0) // 再次检测是否有键按下
{
switch (KEY_PORT & 0xF0) // 检测按下的键
{
case 0xE0:
key_val = 0;
break;
case 0xD0:
key_val = 1;
break;
case 0xB0:
key_val = 2;
break;
case 0x70:
key_val = 3;
break;
}
while ((KEY_PORT & 0xF0) != 0xF0); // 等待键松开
}
}
KEY_CTRL &= 0x0F; // 将低4位设为输出,高4位设为输入
if ((KEY_PORT & 0x0F) != 0x0F) // 检测是否有键按下
{
delay_ms(20); // 延时去抖
if ((KEY_PORT & 0x0F) != 0x0F) // 再次检测是否有键按下
{
switch (KEY_PORT & 0x0F) // 检测按下的键
{
case 0x0E:
key_val = 4;
break;
case 0x0D:
key_val = 5;
break;
case 0x0B:
key_val = 6;
break;
case 0x07:
key_val = 7;
break;
}
while ((KEY_PORT & 0x0F) != 0x0F); // 等待键松开
}
}
return key_val;
}
/* 打开闹钟 */
void alarm_on(void)
{
alarm_flag = 1;
BUZZER = 1;
}
/* 关闭闹钟 */
void alarm_off(void)
{
alarm_flag = 0;
BUZZER = 0;
}
```
最后,在主函数中调用上述函数,实现时钟功能:
```c
#include "alarm.h"
/* 定时器0中断处理函数 */
void timer0_isr(void) interrupt 1
{
static uint cnt = 0;
TH0 = 0xFC; // 重置定时器初值,50ms
TL0 = 0x18;
cnt++;
if (cnt == 20) // 50ms * 20 = 1s
{
cnt = 0;
second++;
if (second == 60)
{
second = 0;
minute++;
if (minute == 60)
{
minute = 0;
hour++;
if (hour == 24)
hour = 0;
}
}
display_time(hour, minute, second); // 显示时间
}
if (alarm_flag && (hour == alarm_hour) && (minute == alarm_minute) && (second == 0))
alarm_on(); // 触发闹钟
}
/* 主函数 */
int main()
{
init_timer0(); // 定时器初始化
init_key(); // 按键初始化
init_display(); // 数码管初始化
while (1)
{
switch (key_scan()) // 按键扫描
{
case 0: // key1,设定闹钟开
alarm_on();
break;
case 1: // key2,设定闹钟关
alarm_off();
break;
case 2: // key3,设定时间加一
second++;
if (second == 60)
{
second = 0;
minute++;
if (minute == 60)
{
minute = 0;
hour++;
if (hour == 24)
hour = 0;
}
}
display_time(hour, minute, second);
break;
case 3: // key4,设定时间减一
if ((hour == 0) && (minute == 0) && (second == 0))
break;
second--;
if (second == 255)
{
second = 59;
minute--;
if (minute == 255)
{
minute = 59;
hour--;
if (hour == 255)
hour = 23;
}
}
display_time(hour, minute, second);
break;
case 4: // key5,设定秒
second = 0;
display_time(hour, minute, second);
break;
case 5: // key6,设定分
minute = 0;
display_time(hour, minute, second);
break;
case 6: // key7,设定时
hour = 0;
display_time(hour, minute, second);
break;
default:
break;
}
}
return 0;
}
```
在上述代码中,我们使用定时器0来实现每秒钟更新时间,并在设定的时间到达时触发闹钟。同时,我们使用矩阵按键来进行时钟设定和闹钟开关的设置,并使用数码管来显示当前时间。在具体实现时,我们需要根据自己的硬件环境和需求进行相应的修改和调整。
阅读全文