給大家分享一個單片機課程設計,已經調試成功而且做出實物了如下圖
紅外遙控萬年歷的實物圖:
1.jpg (219.57 KB, 下載次數: 87)
下載附件
2017-4-27 22:04 上傳
2.jpg (205.87 KB, 下載次數: 117)
下載附件
2017-4-27 22:04 上傳
設計要求: 1 具備在液晶上顯示年、月、日、星期、時、分、秒的功能; 2 具備年、月、日、時、分、秒校準功能(星期可以自動調整,用函數算出來) 3 具有與即時時間同步的功能紅外按鍵調時; 4 具有顯示溫度的功能,可設置鬧鐘;
紅外遙控萬年歷課程設計proteus仿真圖(51hei附件中可下載proteus仿真工程文件):
0.png (72.8 KB, 下載次數: 96)
下載附件
2017-4-27 22:10 上傳
課程設計ppt文檔:
0.png (163.05 KB, 下載次數: 91)
下載附件
2017-4-27 22:05 上傳
¤難度系數:100
¤設計要求:
用LCD1602顯示,紅外遙控器輸入,揚聲器報警,DS18B20測量溫度,DS1302計時
設計程序實現如下功能:
- 實時顯示當前日期時間溫度信息
- 用遙控器設置日期時間和鬧鐘
¤需要器件:
51hei單片機開發板
LCD1602,紅外遙控器,DS18B20
完成硬件設計,焊接,調試
編寫軟件,完成題目要求的功能
實物演示,答辯驗收
完成設計報告
周一:12講解題目,34查閱資料,56定題并給出設計方案,元件清單。
周二:上午檢查硬件電路,領取元器件,下午完成硬件電路制作。
周三:程序設計,調試。
周四:程序設計,調試。
周五:上午完成設計報告,下午提交作品和設計報告。(實物、照片、錄像)
萬年歷的單片機源程序:
- /*
- *************************************************************************************************************
- * clock.c
- * 說 明:時鐘
- * 作 者:Jonelec
- * 首發:51黑電子論壇
- * 修改者: 修改內容: 修改日期:
- * Jonelec 第一版 2017-04-20
- * Copyright(c) 2015-2025 skytech.org Inc.
- *************************************************************************************************************
- */
- #include "clock.h"
- #include "display.h"
- /* 時鐘計時閃爍設置 */
- bit FlashTimeFlag = 0; /*閃爍冒號*/
- #define FlashTimeTMR_ID 0 /*冒號閃爍定時器ID*/
- #define FlashTimeTIME 1000 /*冒號閃爍定時時間*/
- /* 切換界面參數設置*/
- bit SwitchDisplayFlag = 0;
- #define SwitchDispTMR_ID 1 /*切換顯示方式定時器ID*/
- #define SwitchDispTIME 3000 /*切換顯示方式定時時間*/
- extern float idata CurTemp; /*獲取溫度值,3s采集一次*/
- uint8_t idata DispSetIndex = 0; /*光標索引*/
- uint8_t idata AlarmSetIndex = 0;
- AlarmSetInitTypeDef RingTime,SetRing;
- RealTimeInitTypeDef CurTime,SetTime;
- void DispNormalClock(void);
- /*
- *************************************************************************************************************
- * main()
- *函數功能:主函數,執行程序入口
- *函數參數:無
- *返 回 值:無
- *************************************************************************************************************
- */
- int main(void)
- {
- bsp_Init();
- RingTime = SetRing;
- while(1)
- {
- DispNormalClock();
- }
- }
- /*
- *************************************************************************************************************
- * RefreshTime()
- *函數功能:時間顯示刷新
- *函數參數:_ucFlag 【為0時正常顯示時間,為1時顯示鬧鈴時間,不影響日期溫度等顯示】
- *返 回 值:無
- *************************************************************************************************************
- */
- void RefreshTime(uint8_t _ucFlag)
- {
- if(_ucFlag != 1) /*正常顯示時間*/
- {
- bsp_GetTime(&CurTime);
-
- if(bsp_CheckTimer(FlashTimeTMR_ID))
- {
- FlashTimeFlag = !FlashTimeFlag; /*冒號閃爍*/
- }
- Lcd1602_DispNum(1,0,CurTime.Hour>>4);
- Lcd1602_DispNum(1,1,CurTime.Hour&0xF);
- Lcd1602_DispNum(1,3,CurTime.Minute>>4);
- Lcd1602_DispNum(1,4,CurTime.Minute&0xF);
- Lcd1602_DispNum(1,6,CurTime.Second>>4);
- Lcd1602_DispNum(1,7,CurTime.Second&0xF);
-
- Lcd1602_DispStr(1,8," ");
- if(FlashTimeFlag)
- {
- Lcd1602_DispChar(1,2,':');
- Lcd1602_DispChar(1,5,':');
- }
- else
- {
- Lcd1602_DispChar(1,2,' ');
- Lcd1602_DispChar(1,5,' ');
- }
- }
- else /*顯示鬧鈴時間*/
- {
- if(RingTime.OpenFlag != 1)
- {
- Lcd1602_DispStr(1,0,"OFF");
- }
- else
- {
- Lcd1602_DispStr(1,0,"ON ");
- }
- Lcd1602_DispChar(1,3,' ');
- Lcd1602_DispNum(1,4,RingTime.Hour>>4);
- Lcd1602_DispNum(1,5,RingTime.Hour&0xF);
- Lcd1602_DispChar(1,6,':');
- Lcd1602_DispNum(1,7,RingTime.Minute>>4);
- Lcd1602_DispNum(1,8,RingTime.Minute&0xF);
- Lcd1602_DispChar(1,9,' ');
- }
- }
- /*
- *************************************************************************************************************
- * RefreshDate()
- *函數功能:日期顯示刷新
- *函數參數:_ucFlag 【為0時如果日期有變化則會刷新,為1時則立即刷新】
- *返 回 值:無
- *************************************************************************************************************
- */
- void RefreshDate(uint8_t _ucFlag)
- {
- uint8_t pdata week;
- static uint8_t day_backup = 0;
-
- week = bsp_CulateDate(CurTime); /*計算星期*/
-
- if(day_backup != CurTime.Day || _ucFlag != 0)
- {
- Lcd1602_DispNum(0,0,CurTime.YearH>>4);
- Lcd1602_DispNum(0,1,CurTime.YearH&0xF);
- Lcd1602_DispNum(0,2,CurTime.YearL>>4);
- Lcd1602_DispNum(0,3,CurTime.YearL&0xF);
- Lcd1602_DispChar(0,4,'-');
- Lcd1602_DispNum(0,5,CurTime.Month>>4);
- Lcd1602_DispNum(0,6,CurTime.Month&0xF);
- Lcd1602_DispChar(0,7,'-');
- Lcd1602_DispNum(0,8,CurTime.Day>>4);
- Lcd1602_DispNum(0,9,CurTime.Day&0xF);
-
- Lcd1602_DispStr(0,12,"W:");
- Lcd1602_DispNum(0,14,week>>4);
- Lcd1602_DispNum(0,15,week&0xF);
- day_backup = CurTime.Day;
- }
- }
- /*
- *************************************************************************************************************
- * RefreshTemp()
- *函數功能:溫度顯示刷新
- *函數參數:_ucFlag 【為0時如果溫度有變化則會刷新,為1時則立即刷新】
- *返 回 值:無
- *************************************************************************************************************
- */
- void RefreshTemp(uint8_t _ucFlag)
- {
- int16_t pdata temp;
- static int16_t tmp_backup = 0;
-
- temp = CurTemp*10;
- temp >>= 4; /*保留整數部分*/
-
- if((tmp_backup != temp) || (_ucFlag != 0))
- {
- Lcd1602_DispStr(1,10,"T:");
- if(temp < 0)
- {
- Lcd1602_DispChar(1,12,'-');
- }
- else
- {
- Lcd1602_DispChar(1,12,'+');
- }
- Lcd1602_DispNum(1,13,temp/10);
- Lcd1602_DispNum(1,14,temp%10);
- Lcd1602_WriteGram();
- Lcd1602_DispChar(1,15,0x00);
- tmp_backup = temp;
- }
- }
- /*
- *************************************************************************************************************
- * DispNormalClock()
- *函數功能:正常顯示時鐘
- *函數參數:無
- *返 回 值:無
- *************************************************************************************************************
- */
- void DispNormalClock(void)
- {
- uint8_t ucKeyCode;
-
- Lcd1602_ClearScreen(); /*清屏*/
- Lcd1602_OpenCursor(0); /*關閉光標閃爍*/
- RefreshDate(1); /*立即更新日期和溫度*/
- RefreshTemp(1);
- bsp_StartAutoTimer(FlashTimeTMR_ID,FlashTimeTIME); /*秒閃爍定時器*/
- bsp_StartAutoTimer(SwitchDispTMR_ID,SwitchDispTIME);/*切換顯示定時器*/
- while(1)
- {
- ucKeyCode = bsp_GetIRKey();
-
- if(bsp_CheckTimer(SwitchDispTMR_ID))
- {
- SwitchDisplayFlag = !SwitchDisplayFlag;
- }
- RefreshTime(SwitchDisplayFlag);/*時間顯示,即刻刷新,每秒更新*/
- RefreshDate(0);/*年份及日期顯示,只有當日期變化的時候才會刷新*/
- RefreshTemp(0);/*溫度顯示,只有當溫度變化的時候才會刷新*/
-
- if(ucKeyCode != IR_KEY_NONE)
- {
- switch(ucKeyCode)
- { case IR_KEY_POWER:
- {
- RingTime.OpenFlag = !RingTime.OpenFlag;
- }break;
- case IR_KEY_MENU:
- {
- bsp_StopTimer(SwitchDispTMR_ID);
- bsp_StopTimer(FlashTimeTMR_ID);
- LCD_ChangeMenu();
- }break;
- default :break;
- }
- }
- }
- }
- /*
- *************************************************************************************************************
- * ShiftRightCursor()
- *函數功能:光標索引右移
- *函數參數:_ucFlag : 0【設置鬧鐘】 1【設置時鐘】
- *返 回 值:無
- *************************************************************************************************************
- */
- void ShiftRightCursor(uint8_t _ucFlag)
- {
- if(_ucFlag != 0) //設置時鐘
- {
- switch(DispSetIndex)
- {
- case 0: DispSetIndex = 1;Lcd1602_SetPos(0,1);break;
- case 1: DispSetIndex = 2;Lcd1602_SetPos(0,2);break;
- case 2: DispSetIndex = 3;Lcd1602_SetPos(0,3);break;
- case 3: DispSetIndex = 4;Lcd1602_SetPos(0,5);break;
- case 4: DispSetIndex = 5;Lcd1602_SetPos(0,6);break;
- case 5: DispSetIndex = 6;Lcd1602_SetPos(0,8);break;
- case 6: DispSetIndex = 7;Lcd1602_SetPos(0,9);break;
- case 7: DispSetIndex = 8;Lcd1602_SetPos(1,0);break;
- case 8: DispSetIndex = 9; Lcd1602_SetPos(1,1);break;
- case 9: DispSetIndex = 10;Lcd1602_SetPos(1,3);break;
- case 10: DispSetIndex = 11;Lcd1602_SetPos(1,4);break;
- case 11: DispSetIndex = 12;Lcd1602_SetPos(1,6);break;
- case 12: DispSetIndex = 13;Lcd1602_SetPos(1,7);break;
- default :DispSetIndex = 0;Lcd1602_SetPos(0,0);break;
- }
- }
- else /*設置鬧鐘*/
- {
- switch(AlarmSetIndex)
- {
- case 0:AlarmSetIndex = 1;Lcd1602_SetPos(1,1);break;
- case 1:AlarmSetIndex = 2;Lcd1602_SetPos(1,3);break;
- case 2:AlarmSetIndex = 3;Lcd1602_SetPos(1,4);break;
- case 3:AlarmSetIndex = 4;Lcd1602_SetPos(1,10);break;
- default :AlarmSetIndex = 0;Lcd1602_SetPos(1,0);break;
- }
- }
- }
- /*
- *************************************************************************************************************
- * ShiftLeftCursor()
- *函數功能:光標索引左移
- *函數參數:_ucFlag : 0【設置鬧鐘】 1【設置時鐘】
- *返 回 值:無
- *************************************************************************************************************
- */
- void ShiftLeftCursor(uint8_t _ucFlag)
- {
- if(_ucFlag != 0) //設置時鐘
- {
- switch(DispSetIndex)
- {
- case 0: DispSetIndex = 13;Lcd1602_SetPos(1,7);break;
-
- case 1: DispSetIndex = 0;Lcd1602_SetPos(0,0);break;
- case 2: DispSetIndex = 1;Lcd1602_SetPos(0,1);break;
- case 3: DispSetIndex = 2;Lcd1602_SetPos(0,2);break;
- case 4: DispSetIndex = 3;Lcd1602_SetPos(0,3);break;
-
- case 5: DispSetIndex = 4;Lcd1602_SetPos(0,5);break;
- case 6: DispSetIndex = 5;Lcd1602_SetPos(0,6);break;
-
- case 7: DispSetIndex = 6;Lcd1602_SetPos(0,8);break;
- case 8: DispSetIndex = 7;Lcd1602_SetPos(0,9);break;
-
- case 9: DispSetIndex = 8;Lcd1602_SetPos(1,0);break;
- case 10: DispSetIndex = 9;Lcd1602_SetPos(1,1);break;
-
- case 11: DispSetIndex = 10;Lcd1602_SetPos(1,3);break;
- case 12: DispSetIndex = 11;Lcd1602_SetPos(1,4);break;
- default :DispSetIndex = 12;Lcd1602_SetPos(1,6);break;
- }
- }
- else
- {
- switch(AlarmSetIndex)
- {
- case 0:AlarmSetIndex = 4;Lcd1602_SetPos(1,10);break;
- case 1:AlarmSetIndex = 0;Lcd1602_SetPos(1,0);break;
- case 2:AlarmSetIndex = 1;Lcd1602_SetPos(1,1);break;
- case 3:AlarmSetIndex = 2;Lcd1602_SetPos(1,3);break;
- default :AlarmSetIndex = 3;Lcd1602_SetPos(1,4);break;
- }
- }
- }
- /*
- *************************************************************************************************************
- * InputSetNumber()
- *函數功能:將輸入數字進行判斷賦值
- *函數參數:_ucFlag : 0【設置鬧鐘】 1【設置時鐘】
- *返 回 值:無
- *************************************************************************************************************
- */
- void InputSetNumber(uint8_t _ucFlag,uint8_t _ucNum)
- {
- if(_ucFlag != 0)
- {
- switch(DispSetIndex)
- {
- case 0: /*設置年份的最高位*/
- {
- SetTime.YearH = (SetTime.YearH&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(0,0,_ucNum);
- }break;
- case 1:
- {
- SetTime.YearH = (SetTime.YearH&0xF0)|_ucNum; /*年份第三位數字*/
- Lcd1602_DispNum(0,1,_ucNum);
- }break;
- case 2:
- {
- SetTime.YearL = (SetTime.YearL&0x0F)|(_ucNum<<4); /*年份第二位數字*/
- Lcd1602_DispNum(0,2,_ucNum);
- }break;
- case 3:
- {
- SetTime.YearL = (SetTime.YearL&0xF0)|_ucNum; /*年份第一位數字*/
- Lcd1602_DispNum(0,3,_ucNum);
- }break;
- case 4:
- {
- if(_ucNum > 1)
- {
- Lcd1602_DispChar(0,5,'E'); /*月份輸入有誤*/
- }
- else
- {
- SetTime.Month = (SetTime.Month&0x0F)|(_ucNum<<4); /*設置月份*/
- Lcd1602_DispNum(0,5,_ucNum);
- }
-
- }break;
- case 5:
- {
- if((SetTime.Month>>4) == 1)
- {
- if(_ucNum > 2)
- {
- Lcd1602_DispChar(0,6,'E');
- }
- else
- {
- SetTime.Month = (SetTime.Month&0xF0)|_ucNum;
- Lcd1602_DispNum(0,6,_ucNum);
- }
- }
- else
- {
- SetTime.Month = (SetTime.Month&0xF0)|_ucNum;
- Lcd1602_DispNum(0,6,_ucNum);
- }
- }
- case 6: /*設置 天數*/
- {
- if(_ucNum > 3)
- {
- Lcd1602_DispChar(0,8,'E');
- }
- else
- {
- SetTime.Day = (SetTime.Day&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(0,8,_ucNum);
- }
- }break;
- case 7:
- {
- if((SetTime.Day>>4)==3) /*判斷是否為3,最多只有31天*/
- {
- if(_ucNum > 1)
- {
- Lcd1602_DispChar(0,9,'E');
- }
- else
- {
- SetTime.Day = (SetTime.Day&0xF0)|_ucNum;
- Lcd1602_DispNum(0,9,_ucNum);
- }
- }
- else
- {
- SetTime.Day = (SetTime.Day&0xF0)|_ucNum;
- Lcd1602_DispNum(0,9,_ucNum);
- }
- }break;
- case 8: /*設置小時*/
- {
- if(_ucNum > 2)
- {
- Lcd1602_DispChar(1,0,'E');
- }
- else
- {
- SetTime.Hour = (SetTime.Hour&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(1,0,_ucNum);
- }
- }break;
- case 9:
- {
- if((SetTime.Hour>>4) == 2)
- {
- if(_ucNum > 3)
- {
- Lcd1602_DispChar(1,1,'E');
- }
- else
- {
- SetTime.Hour = (SetTime.Hour&0xF0)|_ucNum;
- Lcd1602_DispNum(1,1,_ucNum);
- }
- }
- else
- {
- SetTime.Hour = (SetTime.Hour&0xF0)|_ucNum;
- Lcd1602_DispNum(1,1,_ucNum);
- }
- }break;
- case 10: /*設置分鐘*/
- {
- if(_ucNum > 5)
- {
- Lcd1602_DispChar(1,3,'E');
- }
- else
- {
- SetTime.Minute = (SetTime.Minute&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(1,3,_ucNum);
- }
- }break;
- case 11:
- {
- SetTime.Minute = (SetTime.Minute&0xF0)|_ucNum;
- Lcd1602_DispNum(1,4,_ucNum);
- }break;
- case 12: /*設置秒鐘*/
- {
- if(_ucNum > 5)
- {
- Lcd1602_DispChar(1,6,'E');
- }
- else
- {
- SetTime.Second = (SetTime.Second&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(1,6,_ucNum);
- }
- }break;
- default :
- {
- SetTime.Second = (SetTime.Second&0xF0)|_ucNum;
- Lcd1602_DispNum(1,7,_ucNum);
- }break;
- }
- ShiftRightCursor(1);
- }
- else /*設置鬧鐘*/
- {
- switch(AlarmSetIndex)
- {
- case 0:
- {
- if(_ucNum > 2)
- {
- Lcd1602_DispChar(1,0,'E');
- }
- else
- {
- SetRing.Hour = (SetRing.Hour&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(1,0,_ucNum);
- }
- }break;
- case 1:
- {
- if((SetRing.Hour>>4) == 2)
- {
- if(_ucNum >3)
- {
- Lcd1602_DispChar(1,1,'E');
- }
- else
- {
- SetRing.Hour = (SetRing.Hour&0xF0)|_ucNum;
- Lcd1602_DispNum(1,1,_ucNum);
- }
- }
- else
- {
- SetRing.Hour = (SetRing.Hour&0xF0)|_ucNum;
- Lcd1602_DispNum(1,1,_ucNum);
- }
- }break;
- case 2:
- {
- if(_ucNum > 5)
- {
- Lcd1602_DispChar(1,3,'E');
- }
- else
- {
- SetRing.Minute = (SetRing.Minute&0x0F)|(_ucNum<<4);
- Lcd1602_DispNum(1,3,_ucNum);
- }
- }break;
- case 3:
- {
- SetRing.Minute = (SetRing.Minute&0xF0)|_ucNum;
- Lcd1602_DispNum(1,4,_ucNum);
- }break;
- default :
- {
- if(_ucNum == IR_KEY_POWER) /*按下開關按鍵*/
- {
- SetRing.OpenFlag = !SetRing.OpenFlag;
-
- if(SetRing.OpenFlag != 0) /*開啟鬧鐘*/
- Lcd1602_DispStr(1,10,"ON ");
- else
- Lcd1602_DispStr(1,10,"OFF");
- }
- }break;
- }
- ShiftRightCursor(0); /*光標自加*/
- }
- }
- /*
- *************************************************************************************************************
- * DisplaySetTime()
- *函數功能:將當前的時間加載到設置菜單當中
- *函數參數:無
- *返 回 值:無
- *************************************************************************************************************
- */
- void DisplaySetTime(void)
- {
- bsp_GetTime(&CurTime);
-
- SetTime = CurTime ;
-
- Lcd1602_DispNum(1,0,CurTime.Hour>>4);
- Lcd1602_DispNum(1,1,CurTime.Hour&0xF);
- Lcd1602_DispNum(1,3,CurTime.Minute>>4);
- Lcd1602_DispNum(1,4,CurTime.Minute&0xF);
- Lcd1602_DispNum(1,6,CurTime.Second>>4);
- Lcd1602_DispNum(1,7,CurTime.Second&0xF);
- Lcd1602_DispChar(1,2,':');
- Lcd1602_DispChar(1,5,':');
-
- Lcd1602_DispNum(0,0,CurTime.YearH>>4);
- Lcd1602_DispNum(0,1,CurTime.YearH&0xF);
- Lcd1602_DispNum(0,2,CurTime.YearL>>4);
- Lcd1602_DispNum(0,3,CurTime.YearL&0xF);
- Lcd1602_DispChar(0,4,'-');
- Lcd1602_DispNum(0,5,CurTime.Month>>4);
- Lcd1602_DispNum(0,6,CurTime.Month&0xF);
- Lcd1602_DispChar(0,7,'-');
- Lcd1602_DispNum(0,8,CurTime.Day>>4);
- Lcd1602_DispNum(0,9,CurTime.Day&0xF);
- }
- /*
- *************************************************************************************************************
- * SetClockTime()
- *函數功能:設置時間
- *函數參數:無
- *返 回 值:無
- *************************************************************************************************************
- */
- void SetClockTime(void)
- {
- uint8_t pdata ucKeyCode;
-
- Lcd1602_ClearScreen();
-
- DisplaySetTime();
-
- Lcd1602_SetPos(0,0);
- Lcd1602_OpenCursor(1);
-
- while(1)
- {
- ucKeyCode = bsp_GetIRKey();
-
- if(ucKeyCode != IR_KEY_NONE)
- {
- switch(ucKeyCode)
- {
- case IR_KEY_LEFT : ShiftLeftCursor(1);break;
- case IR_KEY_RIGHT: ShiftRightCursor(1);break;
- case IR_KEY_0: InputSetNumber(1,0);break;
- case IR_KEY_1: InputSetNumber(1,1);break;
- case IR_KEY_2: InputSetNumber(1,2);break;
- case IR_KEY_3: InputSetNumber(1,3);break;
- case IR_KEY_4: InputSetNumber(1,4);break;
- case IR_KEY_5: InputSetNumber(1,5);break;
- case IR_KEY_6: InputSetNumber(1,6);break;
- case IR_KEY_7: InputSetNumber(1,7);break;
- case IR_KEY_8: InputSetNumber(1,8);break;
- case IR_KEY_9: InputSetNumber(1,9);break;
- case IR_KEY_RETURN :
- {
- DispSetIndex = 0;
- LCD_ChangeMenu();
- }break;
- case IR_KEY_OK :
- {
- CurTime = SetTime;
- bsp_SetTime(&CurTime);
- DispNormalClock();
- }break;
- default : break;
- }
- }
- }
- }
- /*
- *************************************************************************************************************
- * SetClockTime()
- *函數功能:設置鬧鐘
- …………限于本文篇幅 余下代碼請從51電子黑下載附件…………
復制代碼
0.png (66.57 KB, 下載次數: 107)
下載附件
2017-4-27 22:03 上傳
下載:
基于單片機的多功能遙控萬年歷設計.rar
(2.54 MB, 下載次數: 51)
2017-4-27 21:09 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|