久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3951|回復: 2
收起左側

單片機萬年歷(鬧鐘)+秒表+音樂盒+電子琴Proteus仿真程序

[復制鏈接]
ID:782856 發表于 2020-7-18 17:26 | 顯示全部樓層 |閱讀模式
      這是我在“2020年7月初學校組織的時長一周的項目”中做的項目,提前一周的周三開始從咱論壇里參考了幾個單獨分開的項目來做的。由于是提前自己做的,第一天上午講解軟件安裝的的時候就完成了所需要做的項目。但硬件方面只用到了C51和LCD12864,講解項目的時候又加了一些其他的一些諸如管理時間的DS1302,管理溫度的DS18B20。又把項目重做了一遍,做完之后還有點時間順便做了做其他的幾個功能。分享之前先對個人的項目進行說明:

  • 由于特殊原因,上的是網課,不在學校,所以并沒有在開發板上測試,只是在仿真里可以運行。
  • 項目所用到的知識點矩陣鍵盤T0中斷LCD12864的使用(顯示屏,無字庫)DS1302的使用(讀寫當前時間)。(DS18B20只是一個溫度的數值,所以交給輔助去做了,嗯,然后就沒加)。
  • 個人認為:適合拿來簡單參考了解一下功能是如何實現的,不適用于研究或鉆研細節方面的東西
  • 一開始源文件只是一個.c文件,只用到了T0中斷來控制秒表、鬧鐘以及時間,并用四個直接連在C51引腳上的按鈕來實現功能。
    但是后來聽課了解了一丁點#include命令后,將項目拆分成了各個頭文件,并加入了控制時間的DS1302來代替T0管理時間模塊。
    按鈕也從單獨的直接連接C51的引腳,換為了一個3*3的矩陣鍵盤。由于矩陣鍵盤沒有辦法檢測按下兩個鍵以上的情況,所以在功能多的前提下按鍵的安排(哪個按鍵管什么功能)就開始“放飛自我”:出于做學校項目的目標是及格,所以并沒有仔細去規劃哪個按鈕控制哪個功能,使用方法詳見附件內的"說明.docx"或"說明.pdf",這里面簡要介紹了功能如何使用。
  • 有關代碼的解釋只有項目文件的注釋。
  • 仿真圖我用的是:ISIS7 Professional,項目文件是Keil uVision4 1.png
  • 我覺得這個不難實現。做之前啥也不會,慢慢了解了LCD12864是如何輸出的,DS1802是如何讀出時間、寫入時間的;以及矩陣鍵盤的原理后,很快很容易的就能夠做出來項目,詳細請百度或參考書籍文獻或自行研究別人的項目。

一、功能:
  • 顯示時間:

    顯示模式.png

    (沒有星期,初衷是想用一個算法根據當前日期算出來星期,結果沒時間去做算法,所以就沒加,不過如果有了參數去源代碼里改改就能顯示星期)
    (溫度是假的,但可以根據參數修改,理論上是由DS18B20來檢測溫度獲得溫度數值,由于和時間一樣,甚至都不用修改,所以就沒有做)
    .
  • 秒表:
    秒表.png
    .
  • 編輯時間:
    編輯時間.png
    .
  • 鬧鐘:
    鬧鐘.png
    .
  • 音樂盒
    音樂盒.png
    (兩首曲子)
    .
  • 簡易電子琴
    簡易電子琴.png
    (本來沒打算寫,后來寫音樂盒用到了28個音符的T0定時器高低八位,寫在了code的數組中,結合之前調試按鍵用到的這個界面,花了十幾分鐘搞定。盡管界面不好看,但也就變成了簡單的一個電子琴,不能檢測多鍵按下的情況)
    .
  • 滾動輸出(第一種,需要知道原位置是什么字符):
    滾動輸出1.png
    另一種不完善的滾動輸出(直接按行輸出):
    滾動輸出2.png
    當時這樣設計是因為第一種編寫代碼的時候很麻煩,由于不清楚如何檢測LCD12864當前屏幕的輸出信息,所以有了第二種按行輸出。如果知道了如何檢測LCD12864的某頁的某列的輸出信息的話,可以優化不少的東西。


二、代碼:
main.c
  1. #include<reg52.h>
  2. #include"dingyi.h"                                                            //引腳以及宏定義
  3. #include"key.h"                                                               //檢測按鍵,以及根據按鍵去做什么。
  4. #include"clock.h"                                                             //DS1302的使用
  5. #include"LCD12864.h"                                                      //包含LCD12864的最基本的使用函數。
  6. #include"LCD12864_use.h"                                               //這里面包含了對LCD12864.h中寫的函數的使用的函數,例如:調用kaifazhe()就能再LCD12864上輸出開發者;調用ShowTime(...)可以根據參數輸出時間等。
  7. #include"music.h"                                                            //這個用來播放音樂以及鬧鐘播放
  8. #include"show.h"                                                            //這個用來配合按鍵輸出的,還未寫入,所以沒用
  9. unsigned char nowkey;                                                     //檢測到的當前按下的值
  10. unsigned char state_key[3]={0,0,0};                                 //當前模塊,按鈕4可切換的最大值,按鈕4當前狀態(切換更改的數值)
  11. unsigned char clock_time[6]={0,0,0,0x31,1,0x20};              //秒、分、時、日、月、年
  12. unsigned char alarm[4]={1,10,45,23};                                //鬧鐘啟動狀態,秒、分、時
  13. unsigned char chronograph[6]={0,0,0,0,0,0};                     //百分秒、秒、分鐘、小時、開啟狀態、暫停狀態
  14. unsigned char music[4]={0,0,0,0};                                    //音樂開關狀態、當前音樂、高八位、低八位
  15. unsigned int pwd;                                                           //按鍵檢測模式計數用
  16. /************************************************************************
  17. *函數名:initT0()
  18. *函數功能:初始化T0,讓T0處于一開就能使用的狀態
  19. *形式參數:無
  20. *返回值:
  21. *用途:初始化
  22. *************************************************************************/
  23. void initT0()
  24. {
  25.         TMOD=0x01;                                                                                        //定時器T0工作在方式1,定時模式
  26.         TH0=(65536-10000)/256;                                                                //一次中斷10ms
  27.         TL0=(65536-10000)%256;
  28.         EA=1;                                                                                                //開總中斷
  29.         ET0=1;                                                                                                //定時器T0允許中斷
  30.         TR0=0;                                                                                                //定時器初始處于關閉狀態
  31. }
  32. /************************************************************************
  33. *函數名:initMain()
  34. *函數功能:初始化T0,lcd,時鐘,讓T0處于一開就能使用的狀態
  35. *形式參數:無
  36. *返回值:
  37. *用途:初始化
  38. *************************************************************************/
  39. void initMain()
  40. {
  41.         init_lcd();
  42.         Clock_Fresh(clock_time);
  43.         Clock_Initial(clock_time);
  44.         initT0();
  45.         state_key[0]=0;                                                                                                   //按鍵狀態初始化
  46.         state_key[1]=0;
  47.         state_key[2]=0;                                                                                                   
  48.         alarm[0]=1;                                                                                                           //alarm初值這樣賦只是方便演示,當然這么寫很不嚴謹!!!。鬧鐘設定開啟
  49.         alarm[1]=0;                                                                                                           //秒→0
  50.         alarm[2]=clock_time[1]/16*10+clock_time[1]%16+1;                           //分→系統時間下一分,如果此時是59分很明顯59+1就溢出了
  51.         alarm[3]=clock_time[2]/16*10+clock_time[2]%16;                                   //時→當前時
  52.         chronograph[0]=0;
  53.         chronograph[1]=0;
  54.         chronograph[2]=0;
  55.         chronograph[3]=0;
  56.         chronograph[4]=0;
  57.         chronograph[5]=0;
  58.         music[0]=0;        
  59.         music[1]=1;                                                                                                           //初始化鬧鐘的鈴聲是第二首歌曲“夢中的婚禮”
  60.         music[2]=0;        
  61.         music[3]=0;
  62. }
  63. /************************************************************************
  64. *函數名:main()
  65. *函數功能:執行主函數
  66. *形式參數:無
  67. *返回值:
  68. *用途:順序執行編寫好的程序,中間有可能被T0中斷
  69. *************************************************************************/
  70. void main()
  71. {
  72.         REBEGIN:                                                                                                                //恢復出場設置時用
  73.         initMain();
  74.         Clr_Scr();
  75.         kaifazhe();                                                                                                                //這個加到這里之后刪不掉了。。。刪除掉反而提示內存溢出。。。
  76.         while(1)
  77.         {
  78.                 if(alarm[0]==1)                                                                                                 //檢查鬧鐘
  79.                 if(clock_time[2]%16+clock_time[2]/16*10==alarm[3]&&
  80.                 clock_time[1]%16+clock_time[1]/16*10==alarm[2]&&
  81.                 clock_time[0]%16+clock_time[0]/16*10==alarm[1]
  82.                 )
  83.                 {
  84.                                 Clr_Scr();

  85.                                 music[0]=1;
  86.                                 while(~puzi(music));                                                                //如果按下了7鍵返回1才能往下執行
  87.                                 music[0]=0;
  88.                                 TR0=0;                                                           
  89.                                 alarm[0]=0;
  90.                                 Clr_Scr();
  91.                 }


  92.                 nowkey=keyyyy();                                                                                        //檢測當前鍵
  93.                 dosomething(nowkey,state_key,clock_time,alarm,chronograph,music);                //根據當前鍵對數值進行改變

  94.                 //下面本來想也封裝個函數,寫到show.h中,但是沒時間了,就不寫封裝了。
  95.                 if(state_key[0]==0)                                                                                                                         //0.顯示模式
  96.                 {
  97.                         Clock_Fresh(clock_time);                                                                                                   //時間刷新
  98.                         ShowTime(10,alarm[0],clock_time,7);                                                                                   //輸出時間
  99.                 }
  100.                 else if(state_key[0]==1)                                                                                                         //1.秒表
  101.                 {
  102.                         if(chronograph[state_Chronograph_Show_Pause]==0)                                                   //如果此時處于不處于暫停狀態才播放,
  103.                                                                                                                                                                            //這里會導致換個模式后如果還是處于暫停狀態
  104.                         MiaoBiao(chronograph[3],chronograph[2],chronograph[1],chronograph[0]);         //秒表模式顯示        
  105.                 }
  106.                 else if(state_key[0]==2)                                                                                                         //2.編輯時間
  107.                 {
  108.                         Clock_Fresh(clock_time);                                                                                                   //時間刷新
  109.                         ShowTime(state_key[2],alarm[0],clock_time,7);                                                            //狀態2輸出編輯模式時間
  110.                 }
  111.                 else if(state_key[0]==3)                                                                                                         //3.編輯鬧鐘
  112.                 {
  113.                         ShowAlarm(alarm[0],state_key[2],alarm[3],alarm[2],alarm[1]);                            //鬧鐘狀態顯示
  114.                 }
  115.                 else if(state_key[0]==4)                                                                                                         //4.音樂盒
  116.                 {
  117.                         showmusic(music[1]);                                                                                                           //音樂模式顯示
  118.                 }
  119.                 else if(state_key[0]==5)                                                                                                         //5.電子琴
  120.                 {
  121.                         while(1)
  122.                         {
  123.                                 TR0=0;
  124.                                 pwd=0;
  125.                                 nowkey=keyyyy();                                                                                                //檢查按下的哪個鍵
  126.                                 music[2]=FREQH[nowkey+7];                                                                                //高八位賦初值
  127.                                 music[3]=FREQL[nowkey+7];                                                                                //低八位賦初值
  128.                                 showkey(nowkey);
  129.                                 TR0=1;                                                                                                                        //啟動T0中斷
  130.                                 music[0]=1;                                                                                                                //允許播放音樂
  131.                                 while(nowkey!=0&&nowkey==keyyyy())
  132.                                 {
  133.                                         delay(1);                                                                                                        //當有鍵按下,每1ms左右pwd+1(1s=1000ms)
  134.                                         pwd++;
  135.                                         if(pwd>3000&&nowkey==9)                                                                                   //9鍵按下了3s左右,關閉T0中斷(不再響),進入內部函數
  136.                                         {        
  137.                                                 TR0=0;
  138.                                                 kaifazhe2();
  139.                                         }
  140.                                 }
  141.                                 TR0=0;
  142.                                 music[0]=0;
  143.                                 
  144.                                 if(pwd>3000)goto NEXT;                                                                                        //while內部結束后檢測按鍵按下了幾秒,如果超過了3s,跳轉到NEXT
  145.                                 
  146.                         }
  147.                         NEXT:
  148.                         Clr_Scr();        
  149.                         state_key[0]=0;
  150.                 }
  151.                 else ;
  152.                 if(nowkey==9)                                                                                                                        //檢查按下的按鍵是否是9,是的話需要按下3s左右,恢復出廠設置
  153.                 {
  154.                         pwd=0;
  155.                         for(pwd=0;pwd<300;pwd++)
  156.                         {
  157.                                 delay(10);
  158.                                 if(keyyyy()==nowkey);
  159.                                 else goto MAINEND;
  160.                         }
  161.                         goto REBEGIN;

  162.                 }
  163.                 MAINEND:;         
  164.         }
  165. }

  166. void T0int()interrupt 1
  167. {
  168.         if(music[0]==1)                                                                                                                                //T0啟動,檢查是否要播放音樂
  169.         {
  170.                 TH0=music[2];
  171.                 TL0=music[3];
  172.                 P3_7=~P3_7;
  173.         }
  174.         else if(chronograph[state_Chronograph_On_Off]==1)                                                        //否則再檢測是否要啟動秒表
  175.         {
  176.                 //給下一次定時賦值
  177.                 TH0=(65536-10000)/256;                                                                                                        //高八位賦初值
  178.                 TL0=(65536-10000)%256;                                                                                                        //低八位賦初值
  179.                 chronograph[chronograph_10ms]++;                                                                                //加百分之一秒,然后進行溢出判斷以及處理
  180.                 if(chronograph[chronograph_10ms]>98)
  181.                 {
  182.                         chronograph[chronograph_10ms]=0;
  183.                         chronograph[chronograph_sec]++;
  184.                         if(chronograph[chronograph_sec]>59)
  185.                         {
  186.                                 chronograph[chronograph_sec]=0;
  187.                                 chronograph[chronograph_min]++;
  188.                         }
  189.                         if(chronograph[chronograph_min]>59)
  190.                         {
  191.                                 chronograph[chronograph_min]=0;
  192.                                 chronograph[chronograph_hour]++;
  193.                         }
  194.                         if(chronograph[chronograph_hour]>23)
  195.                         {
  196.                                 chronograph[chronograph_hour]=0;
  197.                         }
  198.                 }
  199.         }
  200.         else
  201.         {
  202.                 TR0=0;                                                                                                                                   //在不播放音樂,不啟動定時器的狀態下開啟了定時器,則關閉定時器。
  203.         }
  204. }
復制代碼


三、問題:
如mian.c代碼:第75行,明明刪掉一整個函數調用卻提示溢出,如圖:
問題.png
個人在項目展示前寫好了兩個輸出函數用來展示,但是當時也是只能放一個到主函數中,再放會溢出。后來改了改部分代碼,又加了幾個按鈕功能才把兩個輸出函數都加進去。現在的狀態是想刪刪不掉,又沒想去對這個項目文件進行優化、或者深入,所以不對其進行處理。下次做小項目的時候得提前做好代碼層細節上的優化,這次就不再對項目進行修改了。

四、壓縮包內文件說明:
項目文件:
項目文件.png
仿真圖:
硬件仿真圖.png

全部資料51hei下載地址:
萬年歷(鬧鐘)+秒表+音樂盒+電子琴.zip (295.56 KB, 下載次數: 96)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:782856 發表于 2020-7-18 17:27 | 顯示全部樓層
。。。圖片沒加上,還有附件也沒弄上,想保存草稿來著
回復

使用道具 舉報

ID:328014 發表于 2020-7-19 15:39 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品国产青草久久久久96 | 99re视频在线观看 | 欧美爱爱视频 | 涩涩视频网| 久久99国产精一区二区三区 | 欧美国产精品 | 亚洲一区二区在线 | 午夜影院毛片 | 日韩欧美在线视频 | 亚洲免费在线视频 | 久久丝袜视频 | 日韩人体在线 | 91精品国产色综合久久不卡蜜臀 | 欧美国产日韩在线观看 | 久久国产精品一区二区三区 | 国产精品亚洲精品日韩已方 | 欧美在线视频一区 | 久久88 | 国产91综合一区在线观看 | 国产日韩欧美综合 | 婷婷在线网站 | 欧美日韩精品一区二区三区蜜桃 | 91av在线视频观看 | 欧美成人综合 | 亚洲国产精久久久久久久 | 精品av| 中文一级片 | 国产高清免费在线 | 亚洲网一区 | 中文字幕av一区二区三区 | 亚洲欧美日韩在线一区二区 | 97视频免费 | 九九久久久 | 亚洲成人综合网站 | 国产激情一区二区三区 | 91在线看 | 国产精品精品视频一区二区三区 | 青娱乐一区二区 | 日韩免 | www.天天操.com | av一区二区在线观看 |