下面是基于"KR-51開發板"(51單片機)的簡化電子鬧鐘核心C代碼框架,實現如下功能需求:
- 當前時間/鬧鐘時間設定
- 光敏控制數碼管背光
- 按鍵切換/設置/加減
- 蜂鳴器鬧鈴&LED閃爍
- /*
- 51單片機電子鬧鐘 KR-51開發板
- 實現功能:
- 1.可自主設定當前時間與鬧鐘時間,4位共陽數碼管
- 2.利用光敏傳感器實現有光時數碼管常亮,無光時,按下按鍵,數碼管亮起,可切換,查看當前時間與鬧鐘時間
- 3.鬧鐘時間到了,蜂鳴器響起同時,Led燈按 200ms頻率閃爍
- 1. 主要口線分配
- | 功能 | 單片機引腳 |
- |----------------|---------------|
- | 數碼管段選 a-f | P0.0~P0.7 |
- | 數碼管位選 | P2.0~P2.3 |
- | 蜂鳴器 | P2.5 |
- | LED | P1.0 |
- | 光敏傳感器 | P1.7 |
- | 按鍵功能 | P3.2 |
- | 按鍵切換 | P3.3 |
- | 按鍵加 | P3.4 |
- | 按鍵減 | P3.5 |
- 使用說明
- - 按KEY_MODE切換顯示當前和鬧鐘時間。
- - 三個按鍵:KEY_ADD/KEY_SUB調節小時,KEY_FUNC調節分鐘。
- - 光敏自動調節背光,無光時按任一功能鍵亮屏。
- - 鬧鐘時間到,蜂鳴器響、LED閃;復位或重新設定可清除鬧鐘。
- 代碼邏輯清晰,各功能子模塊獨立,易于修改和維護。
- */
- #include <reg51.h>
- #define uint unsigned int
- #define uchar unsigned char
- // 段碼表
- uchar code seg_tab[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共陽數碼管
- // 硬件口線映射
- sbit BUZZER = P2^5; //蜂鳴器
- sbit LED = P1^0;
- sbit LDR = P1^7; // 光敏
- sbit KEY_FUNC = P3^2;
- sbit KEY_MODE = P3^3;
- sbit KEY_ADD = P3^4;
- sbit KEY_SUB = P3^5;
- //主要數據結構
- // 任務標志
- bit alarm_flag = 0;
- bit display_flag = 1; // 數碼管亮/滅
- bit key_enable_flag = 0; // 消抖允許
- uchar key_state = 0; // 按鍵當前狀態
- // 時鐘及鬧鐘變量
- uchar hour=12, minute=0;
- uchar alarm_hour=6, alarm_minute=30;
- uchar display_mode=0; // 0:當前時間 1:鬧鐘時間
- uint tcount=0; // 定時器計數
- //時間與鬧鐘管理模塊
- void time_update(void) {
- tcount++;
- if(tcount >= 2400) { //假設定時25ms; 2400*25ms=60s
- tcount = 0;
- minute++;
- if(minute >= 60) {
- minute = 0;
- hour++;
- if(hour >= 24) hour=0;
- }
- if(hour == alarm_hour && minute == alarm_minute) {
- alarm_flag = 1; //鬧鐘觸發
- }
- }
- }
- void alarm_clear(void) {
- alarm_flag = 0;
- BUZZER = 0;
- LED = 0;
- }
- //按鍵掃描與功能切換
- void key_scan(void) {
- if(KEY_MODE == 0) { // 切換顯示模式
- while(KEY_MODE == 0); //松手消抖
- display_mode ^= 1;
- }
- if(display_mode == 0) { //當前時間
- if(KEY_ADD == 0) { //小時加
- while(KEY_ADD == 0);
- hour++; if(hour > 23) hour=0;
- }
- if(KEY_SUB == 0) { //小時減
- while(KEY_SUB == 0);
- if(hour == 0) hour=23; else hour--;
- }
- if(KEY_FUNC == 0) { //分鐘加
- while(KEY_FUNC == 0);
- minute++; if(minute > 59) minute=0;
- }
- } else { //鬧鐘時間
- if(KEY_ADD == 0) {
- while(KEY_ADD == 0);
- alarm_hour++; if(alarm_hour > 23) alarm_hour=0;
- }
- if(KEY_SUB == 0) {
- while(KEY_SUB == 0);
- if(alarm_hour == 0) alarm_hour=23; else alarm_hour--;
- }
- if(KEY_FUNC == 0) {
- while(KEY_FUNC == 0);
- alarm_minute++; if(alarm_minute > 59) alarm_minute=0;
- }
- }
- }
- //光敏及顯示管理子模塊
- void ldr_check(void) {
- // 有光時一直亮,沒光時只在按鍵顯示
- if(LDR == 1)
- display_flag = 1;
- else {
- if(KEY_FUNC == 0) display_flag = 1;
- else display_flag = 0;
- }
- }
- //數碼管動態顯示模塊
- void display_time(uchar h, uchar m) {
- uchar disp_buf[4],i;
- disp_buf[0] = h / 10;
- disp_buf[1] = h % 10;
- disp_buf[2] = m / 10;
- disp_buf[3] = m % 10;
- for(i=0; i<4; i++) {
- P2 = ~(1 << i); // 位選P2.0~P2.3共陽
- P0 = seg_tab[disp_buf[i]]; // 段選
- // 若想顯示小數點或其它符號,可此處加處理
- // 延時,用于刷新和消影
- }
- }
- //鬧鐘蜂鳴/LED閃爍模塊
- void alarm_task(void) {
- if(alarm_flag) {
- BUZZER = 1;
- // 200ms LED閃爍循環(簡單用定時來實現)
- if(tcount % 8 < 4) LED = 1;
- else LED = 0;
- }
- }
- //定時器初始化與中斷服務
- void Timer0_Init(void) {
- TMOD = 0x01; //方式1 16位
- TH0 = (65536-25000)/256; //25ms
- TL0 = (65536-25000)%256;
- ET0 = 1; TR0 = 1; EA = 1;
- }
- void Timer0_ISR(void) interrupt 1 {
- TH0 = (65536-25000)/256; TL0 = (65536-25000)%256;
- time_update(); //更新時間,每25ms進一次
- }
- //主循環
- void main(void) {
- Timer0_Init();
- alarm_clear();
- while(1) {
- key_scan();
- ldr_check();
- if(display_flag) {
- if(display_mode == 0) display_time(hour, minute);
- else display_time(alarm_hour, alarm_minute);
- } else {
- //可以關閉數碼管
- P0 = 0x00; P2 = 0x00;
- }
- alarm_task();
- // 若需要按鍵消抖與顯示穩定可增加適度延時
- }
- }
復制代碼
|