![從業(yè)將近十年!手把手教你單片機程序框架_第1頁](http://file4.renrendoc.com/view/3293654907117618034958f2245d56f5/3293654907117618034958f2245d56f51.gif)
![從業(yè)將近十年!手把手教你單片機程序框架_第2頁](http://file4.renrendoc.com/view/3293654907117618034958f2245d56f5/3293654907117618034958f2245d56f52.gif)
![從業(yè)將近十年!手把手教你單片機程序框架_第3頁](http://file4.renrendoc.com/view/3293654907117618034958f2245d56f5/3293654907117618034958f2245d56f53.gif)
![從業(yè)將近十年!手把手教你單片機程序框架_第4頁](http://file4.renrendoc.com/view/3293654907117618034958f2245d56f5/3293654907117618034958f2245d56f54.gif)
![從業(yè)將近十年!手把手教你單片機程序框架_第5頁](http://file4.renrendoc.com/view/3293654907117618034958f2245d56f5/3293654907117618034958f2245d56f55.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
(1)很難記住繁雜的寄存器?寄存器不用死記硬背,鴻哥我行走江湖多年,連一個寄存器都記不住。需要配置寄存器的時候,直接在網(wǎng)上或者書本上參考別人(2)很難記住繁雜的匯編語言指令?除非是在校學(xué)生要應(yīng)付考試或者少數(shù)工作中繞不開匯編,否則學(xué)匯編就是浪費時間。鴻哥我行走江湖多年,從來就沒有用(3)C語言很難學(xué)?你不用學(xué)指針,你不用學(xué)帶形參的函數(shù),你不用學(xué)結(jié)構(gòu)體,你不用學(xué)宏定義,你不用學(xué)文件操作,你也不用死記繁瑣的數(shù)據(jù)類型。你只要個邏輯關(guān)系符||,&&,!=,==.那么世界上任何一種邏輯功能的單片機軟件你都能做出來。Cif等復(fù)雜的功CC簡單方便了一點,編譯后的機器碼都大同小異。所以不會指針等高級功能你不用自卑,恰恰相反,當你會最簡單的幾個語句,就把這些高級功能的程序都做出來了,你才發(fā)現(xiàn)你對底層了解得更加透切,再學(xué)那些高級功能輕而易舉。當你裸機跑的程序都能夠協(xié)調(diào)得很好的時候,你才發(fā)現(xiàn)所謂高深的操作系統(tǒng)也不過如此,只要給你時間和金錢你也可以寫個操作系統(tǒng)來玩玩。(4)很難記住精確時間的計算公式?經(jīng)??吹綍r間公式等于晶振,時鐘周期,執(zhí)行指令次數(shù)他們之間的乘除關(guān)系式。鴻哥我認為這些都是浮云,不用糾結(jié)也不(5)很難記住繁雜的各種通信協(xié)議?什么IIC,SPI,232串口通訊,CAN,USB等等。這些都是浮云,你不用記那么多,你只要理解兩種通訊方式就夠了,那就是演變而來。注程序的運行效率,可讀性和可修改性。?那就是裸機奔跑的程序結(jié)構(gòu)。一個好的程序結(jié)構(gòu),本身就是一個微型的多任務(wù)操mainswitch個定時器中斷,這鴻哥首次提出的“三區(qū)一線”理論。此理論把程序代碼分成三個區(qū),一個延時分割線。(1)硬件平臺:基于朱兆祺51單片機學(xué)習板。(2)實現(xiàn)功能:讓一個LED閃爍。(3)源代碼講解如下:oidinitialmyselfinitialperipheralyshortunsignedintuiDelayshortaylongunsignedintuiDelaylongidledflicker/*注釋一:鴻個人的命名風格:凡是輸出后綴都是_dr,凡是輸入后綴都是_sr。voidmain()//學(xué)習要點:深刻理解鴻哥首次提出的三區(qū)一線理論{/*注釋二:IO,initial_myself();/*注釋三:口通訊的,上電立即處理的。delay_long(100);/*注釋四:ral/*注釋五:*專門用來編寫被循環(huán)掃描到的非中斷應(yīng)用程序while(1){led_flicker();//LED閃爍應(yīng)用程序}}voidledflickerLED序{led_dr=1;//LED亮delayshort延時50000個空指令的時間/*注釋六:led_dr=0;//LED滅}/*注釋七:。數(shù)值越大,延時越長。*時間精度不要刻意去計算,感覺差不多就行。DelayShort{unsignedinti;for(i=0;i<uiDelayShort;i++){;//一個分號相當于執(zhí)行一條空語句}}/*注釋八:DelayLong{unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//初始化單片機{led_dr=0;//LED滅}voidinitialperipheral始化外圍{;//本例為空}項目程序的基本分區(qū)。我后續(xù)的程序就按此分區(qū)編寫。Delay在后面的章節(jié)中會提到。p法實現(xiàn)時間延時(1)硬件平臺:基于朱兆祺51單片機學(xué)習板。(2)實現(xiàn)功能:讓一個LED閃爍。(3)源代碼講解如下:/*注釋一:defineconsttimelevel10000oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongidledflickereddrP/*注釋二:epmain{initial_myself();aylonginitial_peripheral();le{}}voidledflickerLED閃爍應(yīng)用程序{{case0:/*注釋三:。uiTimeCnt++;//累加循環(huán)次數(shù),eCntconsttimelevel{meCntucLedStep//切換到下一個步驟}case1:uiTimeCnt++;//累加循環(huán)次數(shù),eCntconsttimelevel{meCntucLedStep//返回到上一個步驟}}}unsignedintuiDelayLong{unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{led_dr=0;//LED滅}voidinitialperipheral第二區(qū)初始化外圍{;//本例為空}melevel決這個問題。這一節(jié)要教會大家四個知識點:方法實現(xiàn)時間延時一些核心變量必須這么做。(1)硬件平臺:基于朱兆祺51單片機學(xué)習板。(3)源代碼講解如下:defineconsttimelevel00oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongidledflickervoidT0_time();//定時中斷函數(shù)bitleddrPunsignedcharucLedStep步驟變量unsignedintuiTimeCnt時中斷次數(shù)的延時計數(shù)器voidmain(){initial_myself();aylonginitial_peripheral();le{}}}voidledflicker三區(qū)LED閃爍應(yīng)用程序{p{case0:/*注釋一:eCntconsttimelevel{/*注釋二:,in且在中斷里又更改了此變量,這種情況在某些要求高的定時中斷。在這里只是提醒各位初學(xué)者有這種情況。ET禁止定時中斷meCntucLedStep//切換到下一個步驟}case1:eCntconsttimelevel{ET禁止定時中斷meCntET0=1;//開啟定時中斷ucLedStep//返回到上一個步驟}}}/*注釋三:*void函數(shù)名()interrupt中斷號*中斷程序內(nèi)容*}。*定時中斷的中斷號是1.至于其它中斷的中斷號,大家可以查找和資料。大家進入中斷時,必須先清除中斷標志,并且斷,然后再寫代碼,最后出來時,記得重裝初始值,并且*打開中斷。voidT0_time()interrupt1{TF0=0;//清除中斷標志TR0=0;//關(guān)中斷imeCntxffffuiTimeCnt{uiTimeCnt++;//累加定時中斷的次數(shù),}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{{/*注釋四:無論一個單片機有多少內(nèi)置資源,。TMODx1/*注釋五:,就像一個水桶里裝的水。如果這個桶是空桶,那么想的時間就很長,如果是里面已經(jīng)裝了大半的水,那么想*把這個桶灌滿水的時間就相對比較短。也就是定時器初始值越小,產(chǎn)生一次的時間就越長。如果初始值太小了,每次產(chǎn)生定時中斷main,而且累記中斷次數(shù)極端就行。TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;led_dr=0;//LED滅}voidinitialperipheral第二區(qū)初始化外圍{TR;/允許定時中斷/啟動定時中斷}點:框架編寫。的長叫和短叫。 (1)硬件平臺:基于朱兆祺51單片機學(xué)習板。 報警,反復(fù)循環(huán)。 (3)源代碼講解如下:#include"REG52.H"/*注釋一::程序。#defineconst_time_05s222//0.5秒鐘的時間需要的定時中斷次數(shù)#defineconst_time_1s444//1秒鐘的時間需要的定時中斷次數(shù)#defineconst_time_3s1332//3秒鐘的時間需要的定時中斷次數(shù)#defineconst_time_6s2664//6秒鐘的時間需要的定時中斷次數(shù)#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間#defineconst_voice_long200//蜂鳴器長叫的持續(xù)時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongidledflickervoidalarmrunvoidT0_time();//定時中斷函數(shù)eepdrPIOsbitled_dr=P3^5;//LED燈的驅(qū)動IO口unsignedcharucLedStep=0;//LED燈的步驟變量unsignedintuiTimeLedCntLED計數(shù)器unsignedcharucAlarmStep變量unsignedintuiTimeAlarmCnt警統(tǒng)計定時中斷次數(shù)的延時計數(shù)器unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{alarm_run();//第二個任務(wù)報警器定時報警}}voidledflickerLED爍應(yīng)用程序{p{case0:{imeLedCntucLedStep//切換到下一個步驟}case1:{imeLedCntucLedStep步驟}}}voidalarmrun/第三區(qū)報警器的應(yīng)用程序{ep{case0:{TimeAlarmCnt/*注釋二:*\貴楊貴貴貴楊楊貴楊貴,u*\楊}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{led_dr=0;//LED滅TMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TR;//開總中斷/允許定時中斷/啟動定時中斷}本節(jié)程序已經(jīng)展示了一個多任務(wù)處理的基本思路,假如要實現(xiàn)一個獨立按鍵檢測,能不能也按照這種思路來處理呢?欲知詳情,請聽下回分解-----在主函數(shù)中檢測。利用累計主循環(huán)次數(shù)來實現(xiàn)獨立按鍵的檢測。上一節(jié)講了多任務(wù)中蜂鳴器驅(qū)動程序的框架,這節(jié)繼續(xù)利用多任務(wù)處理的方式,在主函數(shù)中利用累計主循環(huán)次數(shù)來實現(xiàn)獨立按鍵的檢測。要教會大家四個知識的按鍵自鎖標志。中總 (3)源代碼講解如下:H#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間/*注釋一:整抖動時間閥值的大小,可以更改按鍵的觸發(fā)靈敏度。*去抖動的時間本質(zhì)上等于累計主循環(huán)次數(shù)的時間。#defineconst_key_time1500//按鍵去抖動延時的時間#defineconst_key_time2500//按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan;//按鍵掃描函數(shù)unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{keyscan按鍵掃描函數(shù)ervice}}}voidkeyscan鍵掃描函數(shù){/*注釋二::鍵被按下,去抖動延時計數(shù)器開始累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上又把延時計數(shù)器uiKeyTimeCnt1。ysrIO{Lock}elseifucKeyLock有按鍵按下,且是第一次被按下{++uiKeyTimeCnt1;//延時計數(shù)器constkeytime{ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)}}{}KeyLock{constkeytime{}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}{TF;//清除中斷標志{}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:NDTH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TR;//開總中斷/允許定時中斷/啟動定時中斷}立按鍵的檢測。獨立按鍵的檢測。上一節(jié)講了在主函數(shù)中利用累計主循環(huán)次數(shù)來實現(xiàn)獨立按鍵的檢測,但是它也有一個小小的不足,隨著在主函數(shù)中任務(wù)量的增加,為了保證去抖動延時的時間略作修改,就可以在主函數(shù)中,利用累計定時中斷的次數(shù)來實現(xiàn)去抖動的延時。(2)實現(xiàn)功能:有兩個獨立按鍵,每按一個獨立按鍵,蜂鳴器發(fā)出“滴”的一聲后就停。(3)源代碼講解如下:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間/*注釋一:整抖動時間閥值的大小,可以更改按鍵的觸發(fā)靈敏度。。#defineconst_key_time130//按鍵去抖動延時的時間#defineconst_key_time230//按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan;//按鍵掃描函數(shù)unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedcharucKeyStartFlag關(guān)unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedcharucKeyStartFlag關(guān)unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{keyscan按鍵掃描函數(shù)ervice}}voidkeyscan鍵掃描函數(shù){/*注釋二::鎖標志,計時器開關(guān)和去抖動延時計數(shù)器一直被清零。時計數(shù)器開始在定時中斷函數(shù)里累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上停止計時,并且把延時計數(shù)器uiKeyTimeCnt1k{LockartFlag}elseifucKeyLock有按鍵按下,且是第一次被按下{artFlagconstkeytime{artFlagucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)}}{artFlag}KeyLock{artFlagconstkeytime{tartFlag}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}{TF0=0;//清除中斷標志TR0=0;//關(guān)中斷yStartFlag{ifuiKeyTimeCnt0xffff)//防止計數(shù)器超范圍{}}tartFlag{ifuiKeyTimeCntxffff)//防止計數(shù)器超范圍{}}{}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:NDTMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TR;//開總中斷/允許定時中斷/啟動定時中斷}就有可能沒有上一節(jié)講了在主函數(shù)中利用累計定時中斷的次數(shù)來實現(xiàn)獨立按鍵的檢測,但是如果在某些項目中,需要在主函數(shù)里間歇性地執(zhí)行一些一氣呵成的耗時任務(wù),當主函數(shù)正在處理一氣呵成的耗時任務(wù)時(前提是沒有關(guān)閉定時器中斷),這個時候如果有按鍵按下來,就有可能沒有及時被響應(yīng)到而遺漏了。在定時中斷函數(shù)里處理獨立按鍵的掃描程序,可以避免這個問題。要教會大家一個知識點:如何在上一節(jié)的基礎(chǔ)上,略作修改,就可以在定時中斷函數(shù)里處理獨立按鍵的掃描程(3)源代碼講解如下:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間/*注釋一:整抖動時間閥值的大小,可以更改按鍵的觸發(fā)靈敏度。。#defineconst_key_time120//按鍵去抖動延時的時間#defineconst_key_time220//按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan;//按鍵掃描函數(shù)放在定時中斷里unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{ervice}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋二::發(fā)時,按鍵的自鎖標志,去抖動延時計數(shù)器一直被清零。時計數(shù)器開始在定時中斷函數(shù)里累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上把延時計數(shù)器uiKeyTimeCnt1k{Lock}{TimeCntconstkeytime{ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)}}{}KeyLock{TimeCntconstkeytime{}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}{TF0=0;//清除中斷標志TR0=0;//關(guān)中斷keyscan數(shù){}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間DTMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TR;//開總中斷/允許定時中斷/啟動定時中斷}本節(jié)程序已經(jīng)展示了在定時中斷函數(shù)里執(zhí)行獨立按鍵的掃描程序。這節(jié)和前面兩節(jié)所講的掃描方式,我都在項目上用過,具體跟項目的側(cè)重點不同來選擇不同的方式,我本人用得最多的就是當前這種方式。假如要獨立按鍵實現(xiàn)類似鼠標的雙擊功能,我們改怎么寫程序?欲知詳情,請聽下回分解-----獨立按鍵的雙擊第九節(jié):獨立按鍵的雙擊按鍵觸發(fā)。上一節(jié)講了在定時中斷函數(shù)里處理獨立按鍵的掃描程序,這種結(jié)構(gòu)的程序我用在了很多項目上。這一節(jié)教大家如何實現(xiàn)按鍵雙擊觸發(fā)的功能,這種功能類似鼠看源代碼講解。(3)源代碼講解如下:/*注釋一:。#defineconst_key_time120//按鍵去抖動延時的時間#defineconst_key_time220//按鍵去抖動延時的時間/*注釋二:#defineconst_interval_time2200//連續(xù)兩次按鍵之間的有效時間差//連續(xù)兩次按鍵之間的有效時間差oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan);//按鍵掃描函數(shù)放在定時中斷里unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志CntunsignedintuiKeyIntervalCnt器unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志CntunsignedintuiKeyIntervalCnt器unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{ervice}}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋三:發(fā)時,按鍵的自鎖標志,去抖動延時計數(shù)器一直被清零。***發(fā),則把累加按鍵觸發(fā)的時計數(shù)器開始在定時中斷函數(shù)里累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上把延時計數(shù)器uiKeyTimeCnt1。**。{LockCnt{KeyIntervalCnteyIntervalCntconstintervaltime{lCnt}}}{TimeCntconstkeytime{ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)ervalCntif(ucKeyTouchCnt1>1)//連續(xù)被按了兩次以上{ucKeyTouchCnt1=0;//統(tǒng)計按鍵次數(shù)清零}}}{{KeyIntervalCnteyIntervalCntconstintervaltime{lCnt}}}KeyLock{TimeCntconstkeytime{ervalCntif(ucKeyTouchCnt2>1)//連續(xù)被按了兩次以上{ucKeyTouchCnt2=0;//統(tǒng)計按鍵次數(shù)清零}}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}}{TF;//清除中斷標志{}{}P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋四:NDTMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;voidinitialperipheral第二區(qū)初始化外圍{TR;/允許定時中斷/啟動定時中斷}}序?欲知詳情,請聽下回分解-----獨立按鍵的組合按鍵觸發(fā)。上一節(jié)講了按鍵雙擊觸發(fā)功能的程序,這一節(jié)講類似電腦鍵盤組合按鍵觸發(fā)的功能,要教會大家一個知識點:如何在上一節(jié)的基礎(chǔ)上,略作修改,就可以實現(xiàn)。(3)源代碼講解如下:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間/*注釋一:整抖動時間閥值的大小,可以更改按鍵的觸發(fā)靈敏度。*去抖動的時間本質(zhì)上等于累計定時中斷次數(shù)的時間。#defineconst_key_time1220//按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan;//按鍵掃描函數(shù)放在定時中斷里unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{ervice}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋二:時計數(shù)器開始在定時中斷函數(shù)里累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上把延時計數(shù)器uiKeyTimeCnt12。k{Lock}elseifucKeyLock有按鍵按下,且是第一次被按下{TimeCntif(uiKeyTimeCnt12>const_key_time12){ucKeyLock12=1;//自鎖按鍵置位,避免一直觸發(fā)}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}{TF;//清除中斷標志{}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:NDTMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TRTR;/允許定時中斷/啟動定時中斷}}以前尋呼機流行的時候,尋呼機往往只有一個設(shè)置按鍵,它要求用一個按鍵來設(shè)置不同的參數(shù),這個時候就要用到同一個按鍵來實現(xiàn)短按和長按的區(qū)別觸發(fā)功上一節(jié)講了類似電腦鍵盤組合按鍵觸發(fā)的功能,這節(jié)要教會大家一個知識點:如何在上一節(jié)的基礎(chǔ)上,略作修改,就可以實現(xiàn)同一個按鍵短按與長按的區(qū)別觸SS那么超(3)源代碼講解如下:#defineconst_voice_short20//蜂鳴器短叫的持續(xù)時間#defineconst_voice_long140//蜂鳴器長叫的持續(xù)時間/*注釋一:整抖動時間閥值的大小,可以更改按鍵的觸發(fā)靈敏度。*去抖動的時間本質(zhì)上等于累計定時中斷次數(shù)的時間。#defineconst_key_time_short120//短按的按鍵去抖動延時的時間#defineconst_key_time_long1400//長按的按鍵去抖動延時的時間#defineconst_key_time_short220//短按的按鍵去抖動延時的時間#defineconst_key_time_long2400//長按的按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan);//按鍵掃描函數(shù)放在定時中斷里unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志rtTouchFlagunsignedintuiKeyTimeCnt延時計數(shù)器unsignedcharucKeyLock志ortTouchFlagunsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{ervice}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋二:被按下時,按鍵的自鎖標志,去抖動延時計數(shù)器一直被清零。時計數(shù)器開始在定時中斷函數(shù)里累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上把延時計數(shù)器uiKeyTimeCnt1***{if(ucShortTouchFlag1==1)//短按觸發(fā)標志{ucKeySec//觸發(fā)一號鍵的短按}}{TimeCntif(uiKeyTimeCnt1>const_key_time_short1){ucShortTouchFlag1=1;//激活按鍵短按的有效標志}if(uiKeyTimeCnt1>const_key_time_long1){ucShortTouchFlag1=0;//清除按鍵短按的有效標志ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)}}ifkeysrIO被按下,這時要及時清零一些標志位{if(ucShortTouchFlag2==1)//短按觸發(fā)標志{}}elseifucKeyLock有按鍵按下,且是第一次被按下{TimeCntif(uiKeyTimeCnt2>const_key_time_short2){ucShortTouchFlag2=1;//激活按鍵短按的有效標志}if(uiKeyTimeCnt2>const_key_time_long2){ucShortTouchFlag2=0;//清除按鍵短按的有效標志ucKeyLock2=1;//自鎖按鍵置位,避免一直觸發(fā)}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}{TF;//清除中斷標志{}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelaylongunsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:NDTMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TR;//開總中斷/允許定時中斷/啟動定時中斷}連續(xù)步進觸發(fā)。點:int (3)源代碼講解如下:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間#defineconst_key_time120//按鍵去抖動延時的時間#defineconst_key_time220//按鍵去抖動延時的時間#defineconst_time_0_25s111//0.25秒鐘的時間需要的定時中斷次數(shù)#defineconst_time_1s444//2秒鐘的時間需要的定時中斷次數(shù)oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan;//按鍵掃描函數(shù)放在定時中斷里voidled_run();//led燈的應(yīng)用程序{sbitled_dr=P3^5;//LED的驅(qū)動IO口unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedintuiKeyCtntyCnt1=0;//按鍵連續(xù)觸發(fā)的間隔延時計數(shù)器unsignedcharucKeyLock志unsignedintuiKeyTimeCnt延時計數(shù)器unsignedintuiKeyCtntyCnt2=0;//按鍵連續(xù)觸發(fā)的間隔延時計數(shù)器unsignedcharucKeyLock志unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器unsignedintuiSetNumber的數(shù)據(jù)voidmain{initial_myself();aylonginitial_peripheral();ile{erviceled_run();//led燈的應(yīng)用程序}}voidled_run()//led燈的應(yīng)用程序{{led_dr=0;//滅}seled_dr=1;//亮}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋一::延時計數(shù)器,以及時間間隔延時計數(shù)器一直被清零。時計數(shù)器開始在定時中斷函數(shù)里累加,在還沒累加到****IO口突然瞬間觸發(fā)成高電平,這個時候馬上把延時計數(shù)器uiKeyTimeCnt11秒鐘。進入連續(xù)觸發(fā)模式的程序{LockntiKeyCtntyCnt}{TimeCntconstkeytime{ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)}}{}else秒后仍然不放手,這個時候進入有節(jié)奏的連續(xù)觸發(fā){yCtntyCntifuiKeyCtntyCntconsttimes5秒就觸發(fā)一次{}}{}KeyLock{TimeCntconstkeytime{}}KeyTimeCntconsttimes{}{tconsttimes{}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{uiSetNumberr{}ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)/*注釋二:uiSetNumberf{uiSetNumber=0;}ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}{TF;//清除中斷標志{}{}}PTH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:NDled_dr=0;//LED燈滅TMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;voidinitialperipheral第二區(qū)初始化外圍{TR;/允許定時中斷/啟動定時中斷}}。 器每叫一次,按鍵就觸發(fā)一次。實際上加速到最后,按鍵觸發(fā)的速度遠遠比蜂鳴器的觸發(fā)速度快。 (3)源代碼講解如下:#include"REG52.H"#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間#defineconst_key_time120//按鍵去抖動延時的時間#defineconst_key_time220//按鍵去抖動延時的時間#defineconst_time_1s444//1秒鐘的時間需要的定時中斷次數(shù)#defineconst_initial_set160//連續(xù)觸發(fā)模式的時候,按鍵剛開始的間隔觸發(fā)時間defineconstminlevel30//連續(xù)觸發(fā)模式的時候,按鍵經(jīng)過加速后,如果一旦發(fā)現(xiàn)小于這個值,則直接變到最后的間隔觸發(fā)時間#defineconst_sub_dt10//按鍵的"加速度",相當于按鍵間隔時間每次的變化量defineconst_last_min_set5//連續(xù)觸發(fā)模式的時候,按鍵經(jīng)過加速后,最后的間隔觸發(fā)時間defineconstsynminlevel最小閥值這個時間必須要比蜂鳴器的時間略長一點。oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan);//按鍵掃描函數(shù)放在定時中斷里voidled_run();//led燈的應(yīng)用程序sbitled_dr=P3^5;//LED的驅(qū)動IO口unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCnt延時計數(shù)器unsignedintuiKeyCtntyCnt1=0;//按鍵連續(xù)觸發(fā)的間隔延時計數(shù)器unsignedcharucKeyLock志unsignedintuiSynCtntyCnt1=0;//產(chǎn)生按鍵同步聲音的計數(shù)器unsignedintuiCtntyTimeSet1=const_initial_set;//按鍵每次觸發(fā)的時間間隔,這數(shù)值不斷變小,導(dǎo)致速度不斷加快unsignedintuiCtntySynSet1=const_initial_set;//同步聲音的時間間隔,這數(shù)值不斷變小,導(dǎo)致速度不斷加快unsignedcharucCtntyFlag1=0;//是否處于連續(xù)加速觸發(fā)模式的標志位unsignedintuiKeyTimeCnt延時計數(shù)器unsignedintuiKeyCtntyCnt2=0;//按鍵連續(xù)觸發(fā)的間隔延時計數(shù)器unsignedcharucKeyLock志unsignedintuiSynCtntyCnt聲音的計數(shù)器lsetlsetunsignedcharucCtntyFlag模式的標志位unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器unsignedintuiSetNumber的數(shù)據(jù)voidmain{initial_myself();aylonginitial_peripheral();ile{erviceled_run();//led燈的應(yīng)用程序}}voidled_run()//led燈的應(yīng)用程序{{led_dr=0;//滅}se{led_dr=1;//亮}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋一:***始加速的時候,按鍵觸發(fā)與音跟按鍵的觸發(fā)不一致,并不是srIO{LockimeCntuiKeyCtntyCntuiSynCtntyCnt1=0;//蜂鳴器連續(xù)加速的時間間隔延時計數(shù)器清零uiCtntyTimeSet1=const_initial_set;//按鍵每次觸發(fā)的時間間隔初始值,這數(shù)值不斷變小,導(dǎo)致速度不斷加快uiCtntySynSetconstinitialset值不斷變小,導(dǎo)致鳴叫的節(jié)奏不斷加快}elseifucKeyLock有按鍵按下,且是第一次被按下{TimeCntconstkeytime{ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)ucCtntyFlag模式標志位0代表單擊1代表連續(xù)加速觸發(fā)}}{}else秒后仍然不放手,這個時候進入有節(jié)奏的連續(xù)加速觸發(fā){KeyCtntyCntntyTimeSet{evel{uiCtntyTimeSet1=uiCtntyTimeSet1-const_sub_dt;//uiCtntyTimeSet1不斷減小,速度就越來越快}{uiCtntyTimeSet1=const_last_min_set;//uiCtntyTimeSet1不斷減小,到達一個極限值}ucCtntyFlag發(fā)模式}uiSynCtntyCnt累加iCtntySynSet{etuiCtntySynSetconstsubdtuiCtntySynSetlevel{uiCtntySynSet1=const_syn_min_level;//uiCtntySynSet1不斷減小,達到一個極限值}}}{uiCtntyTimeSet2=const_initial_set;uiCtntySynSet2=const_initial_set;}KeyLock{constkeytime{}}KeyTimeCntconsttimes{}{ntyTimeSet{evel{uiCtntyTimeSet2=uiCtntyTimeSet2-const_sub_dt;}{uiCtntyTimeSet2=const_last_min_set;}}iCtntySynSet{ntySynSetconstsubdtlevel{uiCtntySynSet2=const_syn_min_level;}hort}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{uiSetNumber{uiSetNumber=1000;}{}ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)/*注釋二:uiSetNumber{}ifucCtntyFlag在單擊按鍵的情況下,則蜂鳴器鳴叫,否則蜂鳴器在按鍵掃描key_scan里鳴叫{}ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}}{TF;//清除中斷標志{}{}P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}voidinitial_myself()//第一區(qū)初始化單片機{/*注釋三:NDled_dr=0;//LED燈滅TMODx1TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;voidinitialperipheral第二區(qū)初始化外圍{TR;/允許定時中斷/啟動定時中斷}}(1)硬件平臺:基于朱兆祺51單片機學(xué)習板。。(2)實現(xiàn)功能:16個按鍵中,每按一個按鍵都能觸發(fā)一次蜂鳴器發(fā)出“滴”的一聲。(3)源代碼講解如下:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間#defineconst_key_time20//按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyservice按鍵服務(wù)的應(yīng)用程序voidkeyscan;//按鍵掃描函數(shù)放在定時中斷里sbitkeysrP一行輸入sbitkeysrP二行輸入sbitkeysrP三行輸入sbitkeysrP四行輸入sbitkeydrP//第一列輸出sbitkeydrP//第二列輸出sbitkeydrP//第三列輸出sbitkeydrP//第四列輸出eepdrPIOunsignedcharucKeyStep描步驟變量unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCntunsignedcharucKeyLock志unsignedintuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器voidmain{initial_myself();aylonginitial_peripheral();ile{ervice}}}voidkeyscan按鍵掃描函數(shù)放在定時中斷里{/*注釋一:四行,別輸出另外三列eyStep{case1://按鍵掃描輸出第一列低電平keydr=0;keydr=1;uiKeyTimeCnt=0;//延時計數(shù)器清零ucKeyStep++;//切換到下一個運行步驟case2://此處的小延時用來等待剛才列輸出信號穩(wěn)定,再判斷輸入信號。不是去抖動延時。{ucKeyStep++;//切換到下一個運行步驟}case3:ifkeysrkeysrkeysrkeysr1){ucKeyStep++;//如果沒有按鍵按下,切換到下一個運行步驟ucKeyLock=0;//按鍵自鎖標志清零meCnt}}elseif(ucKeyLock==0)//有按鍵按下,且是第一次觸發(fā){ysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}}case4://按鍵掃描輸出第二列低電平keydr=1;keydr=1;uiKeyTimeCnt=0;//延時計數(shù)器清零切換到下一個運行步驟case5://此處的小延時用來等待剛才列輸出信號穩(wěn)定,再判斷輸入信號。不是去抖動延時。{ucKeyStep++;//切換到下一個運行步驟}case6:ifkeysrkeysrkeysrkeysr1){ucKeyStep++;//如果沒有按鍵按下,切換到下一個運行步驟ucKeyLock=0;//按鍵自鎖標志清零meCnt}elseif(ucKeyLock==0)//有按鍵按下,且是第一次觸發(fā){ysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}}case7://按鍵掃描輸出第三列低電平keydr=1;keydr=0;uiKeyTimeCnt=0;//延時計數(shù)器清零切換到下一個運行步驟case8://此處的小延時用來等待剛才列輸出信號穩(wěn)定,再判斷輸入信號。不是去抖動延時。{ucKeyStep++;//切換到下一個運行步驟}case9:ifkeysrkeysrkeysrkeysr1){ucKeyStep++;//如果沒有按鍵按下,切換到下一個運行步驟ucKeyLock=0;//按鍵自鎖標志清零meCnt}elseif(ucKeyLock==0)//有按鍵按下,且是第一次觸發(fā){ysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}}case10://按鍵掃描輸出第四列低電平keydr=1;keydr=1;uiKeyTimeCnt=0;//延時計數(shù)器清零ucKeyStep++;//切換到下一個運行步驟case11://此處的小延時用來等待剛才列輸出信號穩(wěn)定,再判斷輸入信號。不是去抖動延時。{ucKeyStep++;//切換到下一個運行步驟}case:ifkeysrkeysrkeysrkeysr1){ucKeyStep=1;//如果沒有按鍵按下,返回到第一步,重新開始掃描ucKeyLock=0;//按鍵自鎖標志清零meCnt}elseif(ucKeyLock==0)//有按鍵按下,且是第一次觸發(fā){ysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}rkeysrkeysrkeysr{uiKeyTimeCnt++;//去抖動延時計數(shù)器stkeytime{ucKeyLock松開按鍵,此標志位才會被清零}}}}}voidkeyservice)//第三區(qū)按鍵服務(wù)的應(yīng)用程序{witchucKeySec{ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)}}}{TF;//清除中斷標志keyscan數(shù){}{P}TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;TR0=1;//開中斷}voiddelay_long(unsignedintuiDelayLong){unsignedinti;unsignedintj;for(i=0;i<uiDelayLong;i++){for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量{}}}}voidinitial_myself()//第一區(qū)初始化單片機{TMODx1voidkeyservice按鍵服務(wù)的應(yīng)用程序TH0=0xf8;//重裝初始值(65535-2000)=63535=0xf82fTL0=0x2f;}voidinitialperipheral第二區(qū)初始化外圍{TR;//開總中斷/允許定時中斷/啟動定時中斷}。而且有時候,代碼寫多一點,可讀性非常強,修改起來也非常方便。如果一味的追求壓縮代碼,就會刻意用很多循環(huán),數(shù)組等元素,代碼雖然緊湊了,但是可給大(1)硬件平臺:基于朱兆祺51單片機學(xué)習板。。(2)實現(xiàn)功能:16個按鍵中,每按一個按鍵都能觸發(fā)一次蜂鳴器發(fā)出“滴”的一聲。(3)源代碼講解如下:#defineconst_voice_short40//蜂鳴器短叫的持續(xù)時間#defineconst_key_time20//按鍵去抖動延時的時間oidinitialmyselfinitialperipheralaylongunsignedintuiDelaylongvoidT0_time();//定時中斷函數(shù)voidkeyscan();//按鍵掃描函數(shù)放在定時中斷里sbitkeysrP一行輸入sbitkeysrP二行輸入sbitkeysrP三行輸入sbitkeysrP四行輸入sbitkeydrP//第一列輸出sbitkeydrP//第二列輸出sbitkeydrP//第三列輸出sbitkeydrP//第四列輸出eepdrPIOunsignedcharucKeyStep描步驟變量unsignedcharucKeySec=0;//被觸發(fā)的按鍵編號unsignedintuiKeyTimeCntunsignedcharucKeyLock志ignedcharucRowRecordunsigned
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年公司年會老板致辭范文(17篇)
- 涉外購貨合同(3篇)
- 設(shè)計車輛出入口流量與停車位布局方案
- 2024-2025學(xué)年四川省九校高二上學(xué)期12月聯(lián)考歷史試卷
- 2025年協(xié)作資金合同解析
- 2025年中小型企業(yè)品牌共建合作協(xié)議書
- 2025年專利權(quán)許可與技術(shù)轉(zhuǎn)移合同分析
- 2025年住宅裝飾施工合同
- 2025年企業(yè)流動資金貸款償還協(xié)議合同
- 2025年城市規(guī)劃策劃合作發(fā)展協(xié)議
- 人教版初中英語八年級下冊 單詞默寫表 漢譯英
- 蘇教版六年級數(shù)學(xué)下冊《解決問題的策略2》優(yōu)質(zhì)教案
- 《靜脈治療護理技術(shù)操作規(guī)范》考核試題及答案(共140題)
- 英國文學(xué)8.2講解Sonnet18
- 公民個人信息安全的刑法保護論文
- 人事測評理論與方法-課件
- 最新卷宗的整理、裝訂(全)課件
- 人教版部編道德與法治三年級下冊全冊全套課件
- 信訪事項受理、辦理、復(fù)查、復(fù)核、聽證程序課件
- 【北京】施工現(xiàn)場安全生產(chǎn)標準化管理圖集
- 部編版小學(xué)道德與法治五年級下冊教案(全冊)
評論
0/150
提交評論