|
|
下面是基于"KR-51開發(fā)板"(51單片機(jī))的簡(jiǎn)化電子鬧鐘核心C代碼框架,實(shí)現(xiàn)如下功能需求:
- 當(dāng)前時(shí)間/鬧鐘時(shí)間設(shè)定
- 光敏控制數(shù)碼管背光
- 按鍵切換/設(shè)置/加減
- 蜂鳴器鬧鈴&LED閃爍
- /*
- 51單片機(jī)電子鬧鐘 KR-51開發(fā)板
- 實(shí)現(xiàn)功能:
- 1.可自主設(shè)定當(dāng)前時(shí)間與鬧鐘時(shí)間,4位共陽數(shù)碼管
- 2.利用光敏傳感器實(shí)現(xiàn)有光時(shí)數(shù)碼管常亮,無光時(shí),按下按鍵,數(shù)碼管亮起,可切換,查看當(dāng)前時(shí)間與鬧鐘時(shí)間
- 3.鬧鐘時(shí)間到了,蜂鳴器響起同時(shí),Led燈按 200ms頻率閃爍
- 1. 主要口線分配
- | 功能 | 單片機(jī)引腳 |
- |----------------|---------------|
- | 數(shù)碼管段選 a-f | P0.0~P0.7 |
- | 數(shù)碼管位選 | P2.0~P2.3 |
- | 蜂鳴器 | P2.5 |
- | LED | P1.0 |
- | 光敏傳感器 | P1.7 |
- | 按鍵功能 | P3.2 |
- | 按鍵切換 | P3.3 |
- | 按鍵加 | P3.4 |
- | 按鍵減 | P3.5 |
- 使用說明
- - 按KEY_MODE切換顯示當(dāng)前和鬧鐘時(shí)間。
- - 三個(gè)按鍵:KEY_ADD/KEY_SUB調(diào)節(jié)小時(shí),KEY_FUNC調(diào)節(jié)分鐘。
- - 光敏自動(dòng)調(diào)節(jié)背光,無光時(shí)按任一功能鍵亮屏。
- - 鬧鐘時(shí)間到,蜂鳴器響、LED閃;復(fù)位或重新設(shè)定可清除鬧鐘。
- 代碼邏輯清晰,各功能子模塊獨(dú)立,易于修改和維護(hù)。
- */
- #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}; //共陽數(shù)碼管
- // 硬件口線映射
- 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;
- //主要數(shù)據(jù)結(jié)構(gòu)
- // 任務(wù)標(biāo)志
- bit alarm_flag = 0;
- bit display_flag = 1; // 數(shù)碼管亮/滅
- bit key_enable_flag = 0; // 消抖允許
- uchar key_state = 0; // 按鍵當(dāng)前狀態(tài)
- // 時(shí)鐘及鬧鐘變量
- uchar hour=12, minute=0;
- uchar alarm_hour=6, alarm_minute=30;
- uchar display_mode=0; // 0:當(dāng)前時(shí)間 1:鬧鐘時(shí)間
- uint tcount=0; // 定時(shí)器計(jì)數(shù)
- //時(shí)間與鬧鐘管理模塊
- void time_update(void) {
- tcount++;
- if(tcount >= 2400) { //假設(shè)定時(shí)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; //鬧鐘觸發(fā)
- }
- }
- }
- 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) { //當(dāng)前時(shí)間
- if(KEY_ADD == 0) { //小時(shí)加
- while(KEY_ADD == 0);
- hour++; if(hour > 23) hour=0;
- }
- if(KEY_SUB == 0) { //小時(shí)減
- 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 { //鬧鐘時(shí)間
- 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) {
- // 有光時(shí)一直亮,沒光時(shí)只在按鍵顯示
- if(LDR == 1)
- display_flag = 1;
- else {
- if(KEY_FUNC == 0) display_flag = 1;
- else display_flag = 0;
- }
- }
- //數(shù)碼管動(dòng)態(tài)顯示模塊
- 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]]; // 段選
- // 若想顯示小數(shù)點(diǎn)或其它符號(hào),可此處加處理
- // 延時(shí),用于刷新和消影
- }
- }
- //鬧鐘蜂鳴/LED閃爍模塊
- void alarm_task(void) {
- if(alarm_flag) {
- BUZZER = 1;
- // 200ms LED閃爍循環(huán)(簡(jiǎn)單用定時(shí)來實(shí)現(xiàn))
- if(tcount % 8 < 4) LED = 1;
- else LED = 0;
- }
- }
- //定時(shí)器初始化與中斷服務(wù)
- 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(); //更新時(shí)間,每25ms進(jìn)一次
- }
- //主循環(huán)
- 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 {
- //可以關(guān)閉數(shù)碼管
- P0 = 0x00; P2 = 0x00;
- }
- alarm_task();
- // 若需要按鍵消抖與顯示穩(wěn)定可增加適度延時(shí)
- }
- }
復(fù)制代碼
|
|