总结:代码思路
總結:
實驗1:點LED燈
實驗2:蜂鳴器 按鍵提示音
beep.c:位定義蜂鳴器的端口P1^5,一個延時函數,一個蜂鳴器發出響聲的函數,在for循環里不斷翻轉蜂鳴器電平,并加上延時,使其有周期性
Delay.c:1ms延時函數
key.c:軟件消抖方式的按鍵檢測
Nixie.c:數碼管顯示,先位定義好74HC138譯碼器的三個引腳P22、P23、P24,8種組合對應數碼管的位選,再用數組定義好P0口所需的段選數值,顯示的函數里用switch case 判斷參數傳來的位選以及段選
main.c:獲取按鍵值,有按鍵按下則蜂鳴器發出響聲,數目管顯示按鍵值
實驗3:靜態數碼管
main.c:P22,P23,P24三個引腳組成位選,P0口是段選,段選的哪一位給高電平,哪一位就亮
實驗4:動態數碼管
main.c:根據人的視覺暫留現象,用for循環將每一位都依次點亮,最后加上延時,延時短則所有位都亮,延時長則一位一位點亮,延時后面要加上消影操作,即位選P0口全置0
實驗5.:獨立按鍵(二進制)
main.c:定義一個局部變量NUM,當有按鍵按下時,NUM就++,把NUM取反后賦給端口P2,因為LED要為0才亮,NUM每按一次加1
實驗6:矩陣按鍵(LCD顯示)
矩陣鍵盤掃描(輸入掃描)
原理:讀取第1行(列)→讀取第2行(列) →讀取第3行(列) → ……,然后快速循環這個過程,最終實現所有按鍵同時檢測的效果
matrixkey.c:先將P1口全部置1,然后P13腳置0,則第一列右邊已經是低電平了,就分別去判斷P17、P16、P15、P14是否被按下,即判斷P17~P14是否是0,是則按鍵按下,函數返回對應的鍵碼值,復制三份,修改對應的引腳,即每一列都要判斷
main.c:主函數讀取鍵碼值,并在LCD上顯示
實驗6:矩陣按鍵(LCD顯示)-密碼鎖
matrixkey.c:用上一個代碼的矩陣按鍵檢測方法
main.c:主函數中獲取到鍵碼值后,進行判斷,鍵碼值要小于10,一個密碼為4位,定義一個count全局變量,每次按一個0~9的按鍵count就++,按下個位后,第二次按時原來的個位就變成了十位,新按的值加入個位,再按一次十位就進到了百位;接下來就通過判斷是否按下key11確認鍵,然后判斷輸入的密碼跟寫死的密碼是否相等,相等就在LCD右上角顯示OK,錯誤則顯示ERR,對和錯密碼都清零,以便重新輸入,按key12清除鍵則密碼清零,重新輸入
if(count < 4) {password *= 10; //原來的數*10,向高位移一位,最低位為0password += ret%10; //最低位加上新按下的密碼值,%10是保證ret的值是0~9count++; //控制次數,密碼只有四位 }實驗6:矩陣按鍵(LCD顯示)升級密碼鎖
matrixkey.c:用上一個代碼的矩陣按鍵檢測方法
mian.c:跟密碼鎖代碼邏輯差不多,這個加了自己設置密碼的功能 ,首次開啟會提示輸入密碼,按下key1,輸入密碼,中間判斷跟上個代碼一致,最后按確認鍵保存,然后輸入密碼,判斷一樣,如果密碼跟自己設的不一樣,則ERR,如果一樣就OK
實驗7:8x8點陣顯示一個圖形
main.c:定義74HC595芯片要用到的引腳,先定義一個函數用來實現74HC595(串轉并)芯片的功能,用字模工具生成要顯示圖形的十六進制數據,用數組存著,再寫個顯示圖形的函數,參數column控制列,dat控制行數據,因為P0口是給低電平才亮,所以把列&0x80取反后給P0,函數里要作消隱操作,即P0口置1;最后在mian函數中用for循環,不斷給P0口的每一列置0,進行快速掃描,i控制的是列,因為行的數據已經通過字模軟件生成了,只要在i列的時候顯示這一列的哪一行要亮,根據人眼余暉暫留,就可看到一個圖形
實驗7:8x8點陣動態顯示?
main.c:其余代碼跟顯示一個圖形的一樣,不同的是main函數里面,for循環掃描P0口時,行的數據是[i+offset],即列號加上偏移量,后面用count++控制offset++,offset++后還要注意不能數組溢出,不太懂
實驗8:外部中斷
main.c:先定義外部中斷所使用的引腳,外部中斷0是P3_2口,外部中斷1是P3_3口,而P3_2、P3_3剛好是KEY3、KEY4的引腳,所以平時沒配置外部中斷開啟時使用的是普通IO口的功能,在中斷配置函數中,EX0 = 1讓外部中斷0開啟中斷,EA = 1開啟總中斷,IT0 = 1為下降沿觸發,IT0 = 0則為低電平觸發;然后在中斷處理函數中處理外部中斷,當KEY3不按下時是高電平,按下則為低電平,產生了下降沿,就進入了中斷,中斷處理函數中可以讓LED燈翻轉,要注意中斷號一定要寫對,外部中斷0中斷號是0
實驗9:定時器中斷
main.c:定義配置定時器0的函數,配置TMOD,一般會用TMOD &= 0xF0將低位清0,高位保持不變,然后設置定時器的工作方式,TH0,TL0賦初值,設置計數多少后爆表產生中斷,計數到65536溢出,ET0 = 1,EA =1,開啟中斷;在中斷處理函數中,TH0和TL0溢出會硬件置0,要將TH0和TL0重新賦值,為下一次的計數作準備,可以再定義一個局部變量count,當每計數1ms時進一次中斷,count++,累加到1000次則經過了1s,則可以執行其他代碼,實現了精準定時;記得在main函數中調用初始化函數
定時器計時溢出后不一定非要用中斷來處理,定時和中斷可以分開使用的,在配置定時器函數中不開啟中斷,則可以在主函數中將TH0和TL0重新賦值,也可以使count++,只不過這樣是用CPU來處理,在中斷處理函數中處理則效率高,有多線程的意思,main函數執行主要功能,定時器中斷執行次要功能
實驗9:定時器控制流水燈
main.c:配置定時器函數跟上面一樣,可以用STC-ISP一鍵生成,開啟中斷,在中斷處理函數中將TH0和TL0重新賦值,count++,定義一個變量mode,mode = 1則用左移函數 _crol _()左移P0端口,mode = 0則用右移函數 _cror _()右移P0端口,每次移一位;在main函數中檢測按鍵key1,key2是否按下,key1按下則mode = 0,key2按下則mode = 1
實驗9:定時器-時鐘
time.c:先定義秒、分、時三個全局變量,然后定時器0配置,配置為1ms,開啟中斷,在中斷處理函數中,TH0和TL0重新賦值,令count++,當count>1000時,秒++,當秒>59時,分++,當分>59時,時++,當時>23時,全部清零,重新開始計時,main函數中,初始化定時器0,初始化LCD1602,在while循環里分別在屏幕的合適位置上顯示時、分、秒
實驗10:串口通信
usart.c:先配置串口初始化函數,設置T1定時器為定時模式,工作方式為2:8位自動重裝定時器,可用STC-ISP的波特率設置生成初始化函數,打開串口中斷和總中斷;在中斷處理函數中,串行口中斷號為4,定義局部變量接收SBUF的值,然后將接收中斷標志RI置0,等待下一次接收數據,可以再將變量接收到的串口數據賦給SBUF,while(!TI),當沒發送完成時,TI=0,!TI=1,此時不會退出循環,發送完成后TI=1,!TI=0,會退出循環,然后也要手動將TI置0,為下一次發送作準備;最后只需在main函數中調用串口配置函數即可完成電腦串口發送信息到單片機,觸發中斷單片機再將信息發回給電腦
實驗10:串口通信 串口向電腦發送數據
usart.c:配置串口初始化函數,開啟串口中斷,定義一個1ms的延時函數,然后定義一個單片機串口發送數據的函數,參數為要發送的數據,在函數里將參數放到SBUF上,while(TI == 0),TI = 0,最后在main函數中先定義一個count = 0,while循環前調用函數發送數據0x66,延時兩秒,在while循環內調用函數發送0x77,延時兩秒,count++,當count >5時count清零,用break跳出循環,串口助手看到的現象是單片機先發送66,隔兩秒后發送77,發送6個77,然后再發送66;后面實驗直接把while循環注釋掉,單片機就一直發送66
可得出結論:單片機是不斷循環執行main函數的,就算沒有加while循環,也是重復執行主函數,而為什么一般要加上while循環?
網上答案一:我們在單片機中使用while(1),大部分還是為了防止程序跑飛,因為很多時候執行完某段程序后單片機的程序指針PC(就是程序指針)并不會停止,仍然會繼續從ROM中讀取指令并執行,這樣一來可能會出現程序跑飛的情況,進而出現不確定的結果,我們加個while(1)就能讓程序在執行完后在原地循環,相當于停在原地,防止跑飛。
網上答案二:下載到單片機運行的程序包含兩部分,一部分是我們編寫的程序代碼,另外一部分是編譯器自動生成的代碼,因此,用KEIL軟件編寫的程序在沒有while(1)的情況下運行到最后一行,會自動跳轉到main函數第一行運行。通過查看一個簡單P2_1口置0的程序的匯編代碼發現匯編代碼也是個循環,在main函數執行經過一大堆nop空指令后,會寫著:C:0x000C 02000F LJMP main(C:000F)07 ;該匯編指令意思是重新跳到mian函數入口處執行;而在一開始創建工程時會提醒添加的51啟動文件中,最后也有一句匯編代碼: LJMP ?C_START,也是種跳轉到開始的意思
這里的while(1)并不是防止程序“跑飛”的,而是防止main()返回。 ① 在嵌入式中main是不能返回的。不同的C語言實現的單片機初始化代碼會有不同的表現,有的是在call _main后jmp,而有的是jmp 0,等等這些會導致不可預料的結果。 ② 在我們寫的C語言后轉換成匯編,再觀察單片機的代碼區,你會發現沒有寫程序的部分例如全1或者全0區域,程序運行到這里,就會有可能造成意料不到的結果。若無while(1)循環,程序全部執行后,跳轉至程序起始處重新執行。實驗10:串口通信 電腦發送數據控制LED
usart.c:配置串口初始化函數,這里用的波特率是9600,定義串口發送函數,將參數放到SBUF上,在中斷處理函數種中,定義變量接收SBUF的值,將變量取反后賦給P2端口,根據接收到的數據將LED燈點亮,調用發送函數同時將接收到的數據再發送到電腦上顯示,main函數中調用串口初始化函數
實驗13:DS1302時鐘
DS1302.c:1.先位定義好時鐘芯片的三個引腳IO、CE、SCLK
2.然后定義初始化函數DS1302_init(),將CE和SCLK置0
3.然后定義單字節寫數據函數DS1302_WriteByte(unsigned char command,unsigned char Data),一個參數是命令字(是時分秒等時鐘信息的地址),另一個參數是數據,函數里按照DS1302的時序編寫,先發送命令字,再發送數據,相當于先給定要寫入的時鐘信息,再寫入數據;
4.然后定義單字節讀數據函數DS1302_ReadByte(unsigned char command),一個命令字參數,先發送命令字,再讀取數據;
5.然后定義時間設置寫入函數DS1302_SetTime(),通過調用寫數據函數,將Data_Time數組中的十進制轉為BCD碼后寫入到時鐘芯片中
6.DS1302_GetTime()通過調用讀數據函數,讀到的時鐘信息先從BCD碼轉為十進制,再放入到Get_Time數組中
7.main.c:主函數中調用DS1302的初始化函數,在while循環外DS1302_SetTime()設置時鐘,在while循環里DS1302_GetTime()獲取到時間信息,在LCD1602上顯示
實驗13:DS1302可調時鐘-復雜
/*** 工程名: 可調時鐘* 功能: 使用DS1302時鐘芯片,在LCD1602上顯示年月日,時分秒,星期,秒數自動增加* 控制說明: key1按鍵控制顯示時間或者設置時間* key2按鍵控制要對哪一位進行設置* key3按鍵控制對應位數值增加* key4按鍵控制對應位數值減少*/DS1302.c:跟上面的定義過程一樣,在頭文件中聲明函數供主函數調用
Key.c:按鍵檢測功能,軟件消抖
Delay.c:1ms延時函數
Timer0.c:1ms定時器0初始化,主要是中斷處理函數中每隔500ms翻轉閃爍的標志位,當設置時間時選擇哪一位則哪一位會閃爍顯示,用空字符串擋住原來的時間信息即可,每500ms閃一次
main.c:TimeShow()在LCD上顯示獲取的時間,TimeSet()進入調整時間模式,key2按下選擇設置的位,key3按下則對應位數值增加,key4按下則對應位數據減少,期間要判斷年月日是否越界,每個大月小月,閏年和平年的2月,時分秒越界,自動進位減位,判斷完進行閃爍設置,當對哪一位進行設置,&& 閃爍標志位是否等于1,為真則顯示空字符串,為假則顯示時鐘信息,最后將獲取時鐘數據的數組每一位賦給設置時間的數組,在main函數中進行模式選擇時可以重新設置時間;(獲取時間數組可以不用,把獲取的時間直接放到設置時間的數組里,比較簡單)
實驗13:DS1302可調時鐘-簡單,加星期
/*** 工程名: 可調時鐘* 功能: 使用DS1302時鐘芯片,在LCD1602上顯示年月日,時分秒,星期,秒數自動增加* 控制說明: key1按鍵控制顯示時間或者設置時間* key2按鍵控制要對哪一位進行設置* key3按鍵控制對應位數值增加* key4按鍵控制對應位數值減少*//*** 復雜的版本,有三處不足:* 1.將設置時間的數組和獲取時間的數組分開,導致后續操作困難* 2.時鐘加減越界的判斷邏輯過多且不準確* 3.沒有實現星期的加減功能* * 該版本將對上訴問題進行優化*/DS1302.c:把設置時間Data_Time和獲取時間Get_Time數組寫成一個數組DS1302_Time,后續操作獲取到的時間也放在該數組中,新增加星期的顯示,先寫入星期的命令字,再寫入數據
main.c:大部分跟上個工程代碼差不多,改為一個數組后,在閃爍判斷后不需要將獲取到的時間再次賦值給設置數組,直接對原時間數組進行操作,加上對星期的增加減少和越界判斷
實驗15:IIC總線
I2C.c:先位定義SCL、SDA引腳,起始信號I2C_Start(),停止信號I2C_Stop(),發送一個字節I2C_SendByte(unsigned char dat),接收一個字節I2C_ReceiveByte(),發送應答I2C_SendAck(unsigned char ack),接收應答I2C_ReceiveAck(),各函數按照時序圖編寫SCL、SDA引腳的高低電平
AT24C02.c:發送一幀數據AT24C02_SendData(unsigned char word_address,unsigned char dat),word_address為要往哪個字地址發送數據,dat為要發送的數據,接收一幀數據AT24C02_ReceiveData(unsigned char word_address),word_address為從哪個地址接收數據,根據AT24C02的時序編寫發送和接收數據的具體過程
main.c:按鍵1按下Data++,按鍵2按下Data–,LCD會相應顯示,按鍵3按下則寫入到AT24C02中,因為一個字最多存255,超過的會舍棄高位的,所以要將數據的高8位和低8位分別保存在兩個地址中,按鍵4按下則讀取出來,先讀低位的數據,然后將讀取到的高位數據左移8位后或上低位數據,就組成了一個完成的數據,最后在LCD上顯示
實驗16:秒表(定時器掃描按鍵數碼管)
key.c:Key_GetState()按鍵檢測函數,一但有按鍵被按下,標志位keynum立即置位并返回,給key_loop函數處理,沒有用到Delay延時和while()判斷松手
key_loop()每隔20毫秒執行一次該函數,對按鍵狀態進行掃描,獲取從Key_GetState()返回的按鍵值,定義上次狀態的變量和本次狀態的變量,如果上次不為0而本次為0則表示按鍵被按下,如果上次為0而本次為1則表示按鍵松開,在判斷后將key_keyNumber標志位賦按鍵值,在key_return()函數中用temp接收一下,將temp返回給主函數調用
main.c:調用定時器的初始化函數,中斷處理函數中時間定為20ms,每隔20ms執行一次key_loop()函數,不斷掃描按鍵
數碼管定時器掃描未見到效果
實驗17:DS18B20溫度顯示
OneWire.c:因為DS18B20是用單總線通信的,所以要先把但總線的時序寫好,OneWire_Init()單總線初始化,OneWier_SendBit(unsigned char Bit)主機發送一位,OneWire_ReceiveBit()主機接收一位,OneWire_SendByte(unsigned char Data)發送一個字節,即調用發送一位的函數8次即可,OneWire_ReceiveByte()接收一個字節,即調用接收一位的函數8次
DS18B20.c:DS18B20_ConvertT(void)DS18B20溫度轉換,即將溫度傳感器的值讀入到RAM中,要在函數內使用OneWire_SendByte發送特定的地址,DS18B20_ReadT()讀取溫度供main函數使用,要注意BIT3~0是小數位,最后結果要除以16.0才正確數值,并保留小數
main.c:main函數中先調用溫度轉換函數DS18B20_ConvertT,將溫度值讀入到DS18B290的RAM中,并延時一會,消掉默認的溫度值,在while中也要進行溫度轉換,然后用DS18B20_ReadT將溫度讀取出來,賦給一個變量,然后在LCD上顯示,小數部分要單獨取出來顯示,如果是4位小數,方法是先乘以10000,強轉為unsigned long型,然后再%10000,取出小數部分,與整數分開顯示
實驗17:DS18B20 溫度報警器
key.c:定時器動態掃描按鍵
Timer0.c:定時器0初始化,中斷處理函數用于按鍵掃描
AT24C02.c:main函數中用于將閾值存入AT24C02中,傳輸用到了I2C協議
DS18B20.c:獲取溫度傳感器的值
main.c:先初始化LCD,定時器,溫度轉換,while循環中先溫度轉換,讀取溫度值,在LCD上顯示,定義兩個全局變量表示高閾值和低閾值,按鍵1高閾值++,按鍵2高閾值–,按鍵3低閾值++,按鍵4高閾值–,在增減中也要加上判斷,如高閾值不能超過125,低閾值不能低于-55,高閾值不能低于低閾值,低閾值不能高于高閾值,如果相等了,再增加或者減少的話就–,閾值也時刻顯示在LCD上,然后調用AT24C02_SendData(0,Tlow);和AT24C02_SendData(1,Thight);將閾值寫入到EEPROM中保存;如果檢測到的溫度超過或低于閾值,則在LCD右上角顯示過高或過低的標志,并將蜂鳴器的標志位置1,蜂鳴器報警;然后在main函數開頭處寫Tlow = AT24C02_ReceiveData(0);
Thight = AT24C02_ReceiveData(1);讀取AT24C02中的閾值,如果一開始沒有數據則賦初值,顯示在LCD上
實驗18:LCD1602
LCD1602.c:先位定義LCD的WR、RS、EN引腳,宏定義P0口,
LCD_WriteCommand(unsigned char Command)LCD1602寫指令,
LCD_WriteData(unsigned char Data)LCD1602寫數據,
LCD_Init()LCD1602初始化,初始化要調用LCD_WriteCommand函數寫入4個配置LCD顯示的指令,
LCD_SetCursor(unsigned char Line,unsigned char Column)LCD1602設置光標位置,因為無論顯示什么類型數據都要先設置光標位置,即在哪個位置顯示,所以提取出來寫成一個函數調用,
LCD_ShowChar(unsigned char Line,unsigned char Column,unsigned char Data)LCD1602在指定位置上顯示一個字符,
LCD_ShowString(unsigned char Line,unsigned char Column,char *string)LCD1602在指定位置上顯示字符串,
LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length)LCD1602在指定位置上顯示十進制數字,Pow(int x,int y)求x的y次方,因為要將整型數的每一位都提取出來,再轉為字符才能顯示,所以求次方函數使用來提取每一位的,
LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int number,unsigned char length)LCD1602在指定位置上顯示有符號十進制數字,跟顯示整型數據差不多,只不過要加上正負號顯示
LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length)LCD1602在指定位置上顯示十六進制數字,只是將整數提取位數時/10和%10改為/16和%16
LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int number,unsigned char length)LCD1602在指定位置上顯示二進制數字,將整數提取位數時/10和%10改為/2和%2
main.c:在main函數中先要調用LCD初始化函數,然后才能調用相應函數顯示字符;如果想顯示字符滾動效果,則需在屏幕外面的地址寫入字符串,然后在while循環內調用寫命令的函數LCD_WriteCommand(0x18);寫入指令后并延時Delay1ms(500);就能實現屏幕滾動的效果
實驗19:LED呼吸燈
main.c:主要使用for循環控制變量time從0到100變化,作為高低電平的持續時間,里面一層for循環主要是控制有多少個這樣的周期,LED亮后延時的時間是time,滅后延時的時間是100-time,所以亮和滅的總時間是100,可以實現從不亮慢慢到亮的效果,如果想從亮到滅,只需復制一遍循環,把time從100減到0即可
實驗20:PWM控制電機速度
key.c:定時器0中斷掃描按鍵
Timer0.c:定時器0的初始化函數,定時值為100us
main.c:定義電機的端口P1^0,一個計數值全局變量,一個比較全局變量,main函數中調用初始化函數,然后檢測按鍵的返回值,通過不同的按鍵改變比較值的值, 中斷處理函數中,TH0和TL0重新賦值,count++,count%=100將count的范圍設為0~99,調用key_loop函數,然后判斷計數值count和比較值compare的大小,如果count小于compare,則電機端口置1,如果count大于compare,則電機端口置0
實驗21:AD轉換
XPT2046.c:先定義端口DIN、CS、DCLK、DOUT,XPT2046_ReadAD(unsigned char Command)ZPT2046讀取AD值,參數是命令字,在.h頭文件中宏定義好的命令字,按照XPT2046的時序,先初始換時鐘,然后開始發送指令,for循環8次,從高位開始發送指令,時鐘線給上升沿則發送數據,然后讀取數據,for循環16次,先跳過時序圖中BUSY高電平的部分,來到讀取開始的時序,讀取數據到變量中,返回數字量,將命令字的MODE位取出來判斷,當MODE位是1時,選擇8位為轉換分辨率,所以要左移8位得到真實數值同時返回,當MODE位是0時,選擇12位為轉換分辨率,16-12=4,就左移4位得到數據同時返回,MODE位取值要在宏定義地址時區分開來
main.c:先LCD初始化,在while循環內調用XPT2046_ReadAD函數,對照手冊的表,XP、YP、VBAT、AUX要讀取哪一個,就將地址組合好后放到參數中,應事先在XPT2046.h頭文件中宏定義好,用全局變量接收函數返回的值,然后顯示在LCD上
實驗22:DA轉換(PWM)
main.c:DA轉換實際就是PWM,可以用PWM來代替,所以平時DA轉換用的少,程序現象:DAC模塊的DA1燈呈呼吸燈狀態,先定義計數值和比較值,在main函數中一個for循環i從0~99,將i賦給比較值compare,時刻改變compare的值,另一個for循環i從100減到1,也賦給比較值,在定時器中斷處理函數中,TH0和TL0重新賦值,count取值范圍0到99,如果count小于compare,則DA1燈置1,如果count大于compare,則DA1燈置0
實驗23:紅外遙控
Int0.c:外部中斷0初始化,選擇下降沿觸發
Timer0.c:定時器0初始化,TH0和TL0初始化為0,清除TF0標志,TR0停止計時;另外定義函數設置計數器值Timer0_SetCounter(unsigned int value),分別為TH0和TL0賦初值,value的高位放TH0,低位放TL0,TH0 = value/256;TL0 = values%256;Timer0_GetCounter()獲取計數器值,Timer0_Run(unsigned char Flag)定時器0啟動停止控制,參數為0停止,為1開始
IR.c:IR_Init()紅外遙控初始化,初始化外部中斷0和定時器0,IR_GetDataFlag()紅外遙控獲取收到數據幀標志位,IR_GetRepeatFlag()紅外遙控獲取收到連發幀標志位,IR_GetAddress()紅外遙控獲取收到的地址數據,IR_GetCommand()紅外遙控獲取收到的命令數據,在下降沿觸發的外部中斷0處理函數中對數據進行接收
main.c:while循環中判斷IR_GetDataFlag || IR_GetRepeatFlag是否為真,為真用變量Address接收IR_GetAddress()返回的地址值,變量Command接收IR_GetCommand()返回的指令,在LCD上顯示,如果指令等于IR_VOL_MINUS則表示按下遙控器的VOL–鍵,則NUM–,在LCD上顯示,如果指令等于IR_VOL_ADD則表示按下遙控器的VOL++鍵,NUM++并顯示,按下的話在LCD上顯示就是一直變化的
實驗23:紅外遙控 控制電機速度
Timer1.c:定時器1用于電機的PWM調速
Timer0.c:定時器0用于紅外接收信號時計算時間
Motor.c:將電機的PWM調速寫成一個.c文件,先定義電機的端口,然后Motor_Init()電機初始化,就是初始化定時器1,Motor_SetSpeed(unsigned char Speed)設置電機速度,將參數Speed賦給比較值Compare,在定時器1中斷處理函數中,TH0和TL0重新賦值,count++的范圍是0到99,比較count和compare的大小
IR.c:和上一個工程一樣
Int0.c:和上一個工程一樣
main.c:while循環中判斷如果收到數據幀IR_GetDataFlag(),if判斷如果為真,則Command = IR_GetCommand(),判斷Command是0、1、2、3哪個按鈕按下的,按鈕有對應的按鍵碼,可在頭文件處宏定義出來,方便使用,則在判斷后調用Motor_SetSpeed(50)函數設置電機的比較值,即轉速
總結
- 上一篇: 图论及其应用:第二次作业
- 下一篇: php制作多媒体课件,网络自主学习型多媒