單片機源程序如下:
- /*
- *******************************************************************************
- * 《手把手教你學51單片機(C語言版)》
- * 配套 KST-51 單片機開發板 示例源代碼
- *
- * 文件名:main.c
- * 描 述:第16章 作業題4 帶溫度顯示的電子鐘
- * 版本號:v1.0.0
- * 備 注:在lesson15_3基礎上添加溫度,溫度顯示在第二行右端,原時間位置相應左移
- *******************************************************************************
- */
- #include <reg52.h>
- struct sTime { //日期時間結構體定義
- unsigned int year;
- unsigned char mon;
- unsigned char day;
- unsigned char hour;
- unsigned char min;
- unsigned char sec;
- unsigned char week;
- };
- bit flag1s = 0; //1s定時標志
- bit flag200ms = 1; //200ms定時標志
- struct sTime bufTime; //日期時間緩沖區
- unsigned char setIndex = 0; //時間設置索引
- unsigned char T0RH = 0; //T0重載值的高字節
- unsigned char T0RL = 0; //T0重載值的低字節
- void ConfigTimer0(unsigned int ms);
- void RefreshTimeShow();
- void GetShowTemp();
- extern void InitDS1302();
- extern void GetRealTime(struct sTime *time);
- extern void SetRealTime(struct sTime *time);
- extern void KeyScan();
- extern void KeyDriver();
- extern void InitLcd1602();
- extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
- extern void LcdSetCursor(unsigned char x, unsigned char y);
- extern void LcdOpenCursor();
- extern void LcdCloseCursor();
- extern bit Start18B20();
- extern bit Get18B20Temp(int *temp);
- void main()
- {
- unsigned char psec=0xAA; //秒備份,初值AA確保首次讀取時間后會刷新顯示
- EA = 1; //開總中斷
- ConfigTimer0(1); //T0定時1ms
- Start18B20(); //啟動DS18B20
- InitDS1302(); //初始化實時時鐘
- InitLcd1602(); //初始化液晶
-
- //初始化屏幕上固定不變的內容
- LcdShowStr(3, 0, "20 - - ");
- LcdShowStr(1, 1, " : : --`C");
-
- while (1)
- {
- KeyDriver(); //調用按鍵驅動
- if (flag200ms && (setIndex == 0))
- { //每隔200ms且未處于設置狀態時,
- flag200ms = 0;
- GetRealTime(&bufTime); //獲取當前時間
- if (psec != bufTime.sec) //檢測到時間有變化時刷新顯示
- {
- RefreshTimeShow();
- psec = bufTime.sec; //用當前值更新上次秒數
- }
- }
- if (flag1s && (setIndex == 0)) //每隔1s讀取并顯示溫度
- {
- flag1s = 0;
- GetShowTemp();
- }
- }
- }
- /* 將一個BCD碼字節顯示到屏幕上,(x,y)-屏幕起始坐標,bcd-待顯示BCD碼 */
- void ShowBcdByte(unsigned char x, unsigned char y, unsigned char bcd)
- {
- unsigned char str[4];
-
- str[0] = (bcd >> 4) + '0';
- str[1] = (bcd&0x0F) + '0';
- str[2] = '\0';
- LcdShowStr(x, y, str);
- }
- /* 獲取并顯示溫度 */
- void GetShowTemp()
- {
- int temp;
- unsigned char str[4];
-
- if (Get18B20Temp(&temp)) //讀取當前溫度并判斷是否成功
- { //讀取成功時,刷新當前溫度顯示
- temp >>= 4; //右移4位以舍棄小數位
- str[0] = temp/10 + '0'; //顯示為兩位十進制數字
- str[1] = temp%10 + '0';
- str[2] = '\0';
- LcdShowStr(11, 1, str);
- }
- else
- { //讀取失敗時,提示錯誤信息
- LcdShowStr(11, 1, "--");
- }
- Start18B20(); //重新啟動下一次轉換
- }
- /* 刷新日期時間的顯示 */
- void RefreshTimeShow()
- {
- ShowBcdByte(5, 0, bufTime.year);
- ShowBcdByte(8, 0, bufTime.mon);
- ShowBcdByte(11, 0, bufTime.day);
- ShowBcdByte(1, 1, bufTime.hour);
- ShowBcdByte(4, 1, bufTime.min);
- ShowBcdByte(7, 1, bufTime.sec);
- }
- /* 刷新當前設置位的光標指示 */
- void RefreshSetShow()
- {
- switch (setIndex)
- {
- case 1: LcdSetCursor(5, 0); break;
- case 2: LcdSetCursor(6, 0); break;
- case 3: LcdSetCursor(8, 0); break;
- case 4: LcdSetCursor(9, 0); break;
- case 5: LcdSetCursor(11, 0); break;
- case 6: LcdSetCursor(12, 0); break;
- case 7: LcdSetCursor(1, 1); break;
- case 8: LcdSetCursor(2, 1); break;
- case 9: LcdSetCursor(4, 1); break;
- case 10: LcdSetCursor(5, 1); break;
- case 11: LcdSetCursor(7, 1); break;
- case 12: LcdSetCursor(8, 1); break;
- default: break;
- }
- }
- /* 遞增一個BCD碼的高位 */
- unsigned char IncBcdHigh(unsigned char bcd)
- {
- if ((bcd&0xF0) < 0x90)
- bcd += 0x10;
- else
- bcd &= 0x0F;
-
- return bcd;
- }
- /* 遞增一個BCD碼的低位 */
- unsigned char IncBcdLow(unsigned char bcd)
- {
- if ((bcd&0x0F) < 0x09)
- bcd += 0x01;
- else
- bcd &= 0xF0;
-
- return bcd;
- }
- /* 遞減一個BCD碼的高位 */
- unsigned char DecBcdHigh(unsigned char bcd)
- {
- if ((bcd&0xF0) > 0x00)
- bcd -= 0x10;
- else
- bcd |= 0x90;
-
- return bcd;
- }
- /* 遞減一個BCD碼的低位 */
- unsigned char DecBcdLow(unsigned char bcd)
- {
- if ((bcd&0x0F) > 0x00)
- bcd -= 0x01;
- else
- bcd |= 0x09;
-
- return bcd;
- }
- /* 遞增時間當前設置位的值 */
- void IncSetTime()
- {
- switch (setIndex)
- {
- case 1: bufTime.year = IncBcdHigh(bufTime.year); break;
- case 2: bufTime.year = IncBcdLow(bufTime.year); break;
- case 3: bufTime.mon = IncBcdHigh(bufTime.mon); break;
- case 4: bufTime.mon = IncBcdLow(bufTime.mon); break;
- case 5: bufTime.day = IncBcdHigh(bufTime.day); break;
- case 6: bufTime.day = IncBcdLow(bufTime.day); break;
- case 7: bufTime.hour = IncBcdHigh(bufTime.hour); break;
- case 8: bufTime.hour = IncBcdLow(bufTime.hour); break;
- case 9: bufTime.min = IncBcdHigh(bufTime.min); break;
- case 10: bufTime.min = IncBcdLow(bufTime.min); break;
- case 11: bufTime.sec = IncBcdHigh(bufTime.sec); break;
- case 12: bufTime.sec = IncBcdLow(bufTime.sec); break;
- default: break;
- }
- RefreshTimeShow();
- RefreshSetShow();
- }
- /* 遞減時間當前設置位的值 */
- void DecSetTime()
- {
- switch (setIndex)
- {
- case 1: bufTime.year = DecBcdHigh(bufTime.year); break;
- case 2: bufTime.year = DecBcdLow(bufTime.year); break;
- case 3: bufTime.mon = DecBcdHigh(bufTime.mon); break;
- case 4: bufTime.mon = DecBcdLow(bufTime.mon); break;
- case 5: bufTime.day = DecBcdHigh(bufTime.day); break;
- case 6: bufTime.day = DecBcdLow(bufTime.day); break;
- case 7: bufTime.hour = DecBcdHigh(bufTime.hour); break;
- case 8: bufTime.hour = DecBcdLow(bufTime.hour); break;
- case 9: bufTime.min = DecBcdHigh(bufTime.min); break;
- case 10: bufTime.min = DecBcdLow(bufTime.min); break;
- case 11: bufTime.sec = DecBcdHigh(bufTime.sec); break;
- case 12: bufTime.sec = DecBcdLow(bufTime.sec); break;
- default: break;
- }
- RefreshTimeShow();
- RefreshSetShow();
- }
- /* 右移時間設置位 */
- void RightShiftTimeSet()
- {
- if (setIndex != 0)
- {
- if (setIndex < 12)
- setIndex++;
- else
- setIndex = 1;
- RefreshSetShow();
- }
- }
- /* 左移時間設置位 */
- void LeftShiftTimeSet()
- {
- if (setIndex != 0)
- {
- if (setIndex > 1)
- setIndex--;
- else
- setIndex = 12;
- RefreshSetShow();
- }
- }
- /* 進入時間設置狀態 */
- void EnterTimeSet()
- {
- setIndex = 2; //把設置索引設置為2,即可進入設置狀態
- LeftShiftTimeSet(); //再利用現成的左移操作移到位置1并完成顯示刷新
- LcdOpenCursor(); //打開光標閃爍效果
- }
- /* 退出時間設置狀態,save-是否保存當前設置的時間值 */
- void ExitTimeSet(bit save)
- {
- setIndex = 0; //把設置索引設置為0,即可退出設置狀態
- if (save) //需保存時即把當前設置時間寫入DS1302
- {
- SetRealTime(&bufTime);
- }
- LcdCloseCursor(); //關閉光標顯示
- }
- /* 按鍵動作函數,根據鍵碼執行相應的操作,keycode-按鍵鍵碼 */
- void KeyAction(unsigned char keycode)
- {
- if ((keycode>='0') && (keycode<='9')) //本例中不響應字符鍵
- {
- }
- else if (keycode == 0x26) //向上鍵,遞增當前設置位的值
- {
- IncSetTime();
- }
- else if (keycode == 0x28) //向下鍵,遞減當前設置位的值
- {
- DecSetTime();
- }
- else if (keycode == 0x25) //向左鍵,向左切換設置位
- {
- LeftShiftTimeSet();
- }
- else if (keycode == 0x27) //向右鍵,向右切換設置位
- {
- RightShiftTimeSet();
- }
- else if (keycode == 0x0D) //回車鍵,進入設置模式/啟用當前設置值
- {
- if (setIndex == 0) //不處于設置狀態時,進入設置狀態
- {
- EnterTimeSet();
- }
- else //已處于設置狀態時,保存時間并退出設置狀態
- {
- ExitTimeSet(1);
- }
- }
- else if (keycode == 0x1B) //Esc鍵,取消當前設置
- {
- ExitTimeSet(0);
- }
- }
- /* 配置并啟動T0,ms-T0定時時間 */
- void ConfigTimer0(unsigned int ms)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
溫度檢測.rar
(41.24 KB, 下載次數: 72)
2018-4-27 10:55 上傳
點擊文件名下載附件
|