花了幾個星期制作了一個電子鬧鐘,能顯示自定義字符。三個按鍵調整時間和鬧鐘,主要是程序調試
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (53.92 KB, 下載次數: 69)
下載附件
2018-11-13 16:51 上傳
0.png (54.99 KB, 下載次數: 49)
下載附件
2018-11-13 16:51 上傳
0.png (8.8 KB, 下載次數: 67)
下載附件
2018-11-13 16:51 上傳
單片機源代碼:
- #define _MAIN_C
- #include "config.h"
- #include "Lcd1602.h"
- #include "keyboard.h"
- #include "DS1302.h"
- #include "DS18B20.h"
- #include "Time.h"
- #include "main.h"
- bit flag2s = 0; //2s定時標志位
- bit flag200ms = 0; //200ms定時標志
- uint8 T0RH = 0; //T0重載值的高字節
- uint8 T0RL = 0; //T0重載值的低字節
- enum eStaSystem staSystem = E_NORMAL; //系統運行狀態
- uint8 code table[]={0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x0E,0x00,0x00,0x1F,0x00,0x00,
- 0x00,0x00,0x0E,0x00,0x0E,0x00,0x1F,0x00,
- 0x00,0x1F,0x15,0x15,0x1B,0x11,0x1F,0x00,
- 0x00,0x1E,0x08,0x1E,0x0A,0x0A,0x0A,0x1F,
- 0x00,0x04,0x00,0x1F,0x0A,0x11,0x11,0x00,
- 0x00,0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,
- 0x00,0x04,0x0E,0x0E,0x0E,0x1F,0x00,0x0E };
- void main()
- {
- uint8 ledsj=0;
- EA = 1; //開總中斷
- ConfigTimer0(1); //配置T0定時1ms
- InitDS1302(); //初始化實時時鐘模塊
- InitLcd1602(); //初始化液晶模塊
- LED=0;
- WriteROM();
- Start18B20(); //啟動首次溫度轉換
- LcdShowStr(2, 0,"Zhao Wen jie");
- LcdShowStr(0, 1,"Qichuangnaozhong");
- while (!flag2s); //上電后延時2秒
- flag2s = 0;
- LcdClearScreen(); //液晶清屏
- RefreshDate(1); //立即刷新日期顯示
- RefreshTemp(1); //立即刷新溫度顯示
- RefreshTime(); //刷新當前時間
-
- while (1) //進入主循環
- {
- KeyDriver(); //執行按鍵驅動
-
- if (flag200ms) //每隔200ms執行以下分支
- {
- flag200ms = 0;
-
-
- if (staSystem == E_NORMAL) //正常運行時刷新日期顯示
- {
- AlarmMonitor(); //監控鬧鐘
- if(key==0)
- {
- if(bakekey==0)
- {
- LcdClearScreen(); //液晶清
- RefreshDate(1); //立即刷新日期顯示
- RefreshTemp(1); //立即刷新溫度顯示
- bakekey=1;
- }
- if(bakekey==1)
- {
- RefreshTime(); //刷新當前時間
- RefreshDate(0); //立即刷新日期
- }
- else
- {
- ;;
- }
- }
- else
- {
- LcdClearScreen(); //液晶清屏
- RefreshAlarm();
- }
-
- }
- }
- if (flag2s) //每隔2s執行以下分支
- {
- flag2s = 0;
- if (staSystem == E_NORMAL) //正常運行時刷新日期顯示
- {
- ledsj++;
- if(ledsj>=30)
- {
- ledsj=0;
- LED=1;
- }
-
- RefreshTemp(0);
- }
- }
- }
- }
- /* 溫度刷新函數,讀取當前溫度并根據需要刷新液晶顯示,
- ** ops-刷新選項:為0時只當溫度變化才刷新,非0則立即刷新 */
- void RefreshTemp(uint8 ops)
- {
- int16 temp;
- uint8 pdata str[8];
- static int16 backup = 0;
-
- Get18B20Temp(&temp); //獲取當前溫度值16bit
- Start18B20(); //啟動下一次轉換
- temp >>= 4; //舍棄4bit小數位
- if ((backup!=temp) || (ops!=0)) //按需要刷新液晶顯示
- {
- if((temp>>7)&0x1f)
- {
- LcdShowChar(12, 1, '-');
- temp=(uint8)temp<<5;
- temp=~(temp)+1;
- }
- str[0] = (temp/10) + '0'; //十位轉為ASCII碼
- str[1] = (temp%10) + '0'; //個位轉為ASCII碼
- str[2] = 'C';
- str[3] = '\0'; //字符串結束符
- LcdShowStr(13, 1, str); //顯示到液晶上
- backup = temp; //刷新上次溫度值
- }
- }
- /* 配置并啟動T0,ms-T0定時時間 */
- void ConfigTimer0(uint16 ms)
- {
- uint32 tmp;
-
- tmp = (SYS_MCLK*ms)/1000; //計算所需的計數值
- tmp = 65536 - tmp; //計算定時器重載值
- tmp = tmp + 33; //補償中斷響應延時造成的誤差
- T0RH = (uint8)(tmp>>8); //定時器重載值拆分為高低字節
- T0RL = (uint8)tmp;
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x01; //配置T0為模式1
- TH0 = T0RH; //加載T0重載值
- TL0 = T0RL;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- }
- /* T0中斷服務函數,實現系統定時和按鍵掃描 */
- void InterruptTimer0() interrupt 1
- {
- static uint8 tmr2s = 0;
- static uint8 tmr200ms = 0;
-
- TH0 = T0RH; //重新加載重載值
- TL0 = T0RL;
- tmr200ms++; //定時200ms
- if (tmr200ms >= 200)
- {
- tmr200ms = 0;
- flag200ms = 1;
- tmr2s++; //定時2s
- if (tmr2s >= 10)
- {
- tmr2s = 0;
- flag2s = 1;
- }
- }
- KeyScan(); //執行按鍵掃描
- }
- void WriteROM()
- {
- uint8 i=0;
- LcdWriteCmd(0x40);
- for(i=0;i<64;i++)
- {
- LcdWriteDat(table[i]);
- }
- }
- 其他子程序在附件中。
復制代碼
全部資料51hei下載地址:
電路圖.rar
(2.89 MB, 下載次數: 106)
2018-11-13 16:29 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
c.rar
(107.45 KB, 下載次數: 102)
2018-11-13 16:25 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|