紅外線遙控器解碼程序-copy_第1頁
紅外線遙控器解碼程序-copy_第2頁
紅外線遙控器解碼程序-copy_第3頁
紅外線遙控器解碼程序-copy_第4頁
紅外線遙控器解碼程序-copy_第5頁
已閱讀5頁,還剩46頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、紅外線程序?yàn)?LC7461 等 這里以紅外線編碼為例來說明用單片機(jī)實(shí)現(xiàn)紅外的詳細(xì)過 程,站長琢磨這個程序花了相當(dāng)多的精力,期間幾經(jīng)修改逐步完善,后來還用它開發(fā)了幾個小產(chǎn) 品,希望能對網(wǎng)友學(xué)習(xí)單片機(jī)有所幫助。紅外線是目前使用最廣泛的一種通信和。由于紅外線裝置具有體積小、功耗低 功能強(qiáng)、成本特點(diǎn),因而,繼彩電、機(jī)之后,在機(jī)、音響設(shè)備、空凋機(jī)以及玩具等其它 小型電器裝置上也紛紛采用紅外線。工業(yè)設(shè)備中,在高壓、輻射、氣體、粉塵等環(huán)境下,采 用紅外線不僅完全可靠而且能有效地電氣干擾。 1 紅外系統(tǒng)系統(tǒng)由發(fā)射和接收兩大部分組成,應(yīng)用編/ 通用紅外集成電路來進(jìn)行控制操作,如圖 1 所示。發(fā)射部分包括鍵盤矩陣

2、、編碼調(diào)制、LED 紅外發(fā)送器;接收部分包括光、電轉(zhuǎn)換放大器、 解調(diào)、電路。 2 及其編碼很多,根據(jù)編碼格式可以分成脈沖寬度調(diào)制和脈沖相位調(diào)制兩大類,這里以運(yùn)用比較廣泛,比較容易的脈沖寬度調(diào)制來加以說明,現(xiàn)以 LC7461 組成發(fā)射電路為例說明編碼原理。當(dāng)特征:按鍵按下后,即有碼發(fā)出,所按的鍵不同編碼也不同。這種碼具有以下采用脈寬調(diào)制的串行碼,以脈寬為 0.565ms、間隔 0.56ms、周期為 1.125ms 的組合表示二進(jìn)制的“0”以脈寬為 0.565ms、間隔 1.685ms、周期為 2.25ms 的組合表示二進(jìn)制的“1”上述“0”和“1”組成的 42 位二進(jìn)制碼經(jīng) 38kHz 的載頻進(jìn)

3、行二次調(diào)制以提高發(fā)射效率,達(dá)到降低電源功耗的目的。然后再通過紅外發(fā)射二極管產(chǎn)生紅外線向空間發(fā)射,7461 產(chǎn)生的編碼是連續(xù)的 42 位二進(jìn)制碼組,其中前 26 位為用戶識別碼,能區(qū)別不同的紅外遙控設(shè)備,防止不同機(jī)種碼互相干擾。后 16 位為 8 位的操作碼和 8 位的操作反碼用于核對數(shù)據(jù)是否接收準(zhǔn)確。上任意一個按鍵按下超過 36ms 時,LC7461 當(dāng)?shù)恼袷幤魇辜せ?,將發(fā)射一個特定的 同步碼頭,對于接收端而言就是一個 9ms 的低電平,和一個 4.5ms 的,這個同步碼頭可以使程序知道從這個同步碼頭以后可以開始接收數(shù)據(jù)。的關(guān)鍵是如何識別“0”和“1”,從位的定義可以發(fā)現(xiàn)“0”、“1”均以 0

4、.56ms 的低電平開始,不的寬度不同,“0”為 0.56ms,“1”為 1.68ms,所以必須根據(jù)的寬度區(qū)別“0”和“1”。如同的是果從 0.56ms 低電平過后,開始延時,0.56ms 以后,若讀到的電平為低,說明該位為“0”,反之則為“1”為了可靠起見,延時必須比 0.56ms 長些,但又過 1.12ms,否則如果該位為“0”,讀到的已是下,因此?。?.12ms+0.56ms)/2=0.84ms 最為可靠,一般取 0.84ms 左右即可。一位的根據(jù)紅外編碼的格式,程序應(yīng)該等待 9ms 的起始碼和 4.5ms 的結(jié)果碼完成后才能讀碼。如果郵購開發(fā)的 51 單片機(jī)試驗(yàn)板和擴(kuò)展元件的網(wǎng)友,可以

5、獲得如上圖所示的紅外手柄,這的編碼格式符合上面的描述規(guī)律,而且價格低廉,有 32 個按鍵,按鍵外形比較 種,如果用于批量開發(fā),可以把上貼膜換成你需要的字符,這為開發(fā)產(chǎn)品提供了便利。及 LT0038 是塑封紅外線,它是一種集紅外線接收、放大、整形于一體的集成電路,不需 要任何外接元件,就能完成從紅外線接收到輸出與 TTL 電平信號兼容的所有工作,沒有紅外信號時為,收到紅外信號時為低電平,而體積和普通的塑封三極管大小一樣,它適合于各種紅外線和紅外線數(shù)據(jù)傳輸。 下面是一個對 51 實(shí)驗(yàn)板配套的紅外線的程序,它可以把上圖 32 鍵的紅外每一個按鍵的鍵值讀出來,并且通過實(shí)驗(yàn)板上 P1 口的 8 個LED

6、 顯示出來,在嘀嘀”的提示音。成功的同時并且能發(fā)出“嘀0000HAJMP MAIN;轉(zhuǎn)入主程序 0003H ;外部中斷 P3.2 腳0地址AJMP;轉(zhuǎn)入外部中斷服務(wù)子程序(程序);以下為主程序進(jìn)行CPU 中斷方式設(shè)置MAIN:SETB EA ;打開 CPU 總中斷請求SETB IT0 ;設(shè)定SETB EX0 ;打開0 的觸發(fā)方式為脈沖負(fù)邊沿觸發(fā)0 中斷請求;以下對單片機(jī)的所有引腳進(jìn)行初始化,全部設(shè)置成MOV P2,#11100111BAJMP $;以下為進(jìn)入 P3.2 腳外部中斷子程序,也就是: CLR EA ;暫時關(guān)閉 CPU 的所有中斷請求MOV R6,#10SB: ACALL YS1;調(diào)

7、用 882 微秒延時子程序程序 JB P3.2,EXIT;延時 882 微秒后判斷 P3.2 腳是否出現(xiàn)如果有就退出程序 DJNZ R6, SB;重復(fù) 10 次,目的是檢測在 8820 微秒內(nèi)如果出現(xiàn)就退出程序;以上完成對信號的 9000 微秒的初始低電平信號的識別。JNB P3.2, $ ;等待避開 9 毫秒低電平引導(dǎo)脈沖ACALL YS2 ;延時 4.74 毫秒避開 4.5 毫秒的結(jié)果碼MOV R7,#26;忽略前 26 位系統(tǒng)識別碼JJJJA:JNB P3.2,$;等待地址碼第一位的信號 LCALL YS1;開始后用 882 微秒的時間尺去判斷信號此時的高低電平狀態(tài)MOV C,P3.2;

8、將 P3.2 引腳此時的電平狀態(tài) 0 或 1 存入C 中JNC UUUA;如果為 0 就跳轉(zhuǎn)到 UUUA LCALL YS3;檢測到1 的話延時 1 毫秒等待脈沖結(jié)束UUUA: DJNZ R7,JJJJAMOV R1,#1AH ;設(shè)定 1AH 為起始 RAM 區(qū)MOV R2,#2;接收從 1AH 到 1BH 的 2 個內(nèi)存,用于存放操作碼和操作反碼PP: MOV R3,#8;每組數(shù)據(jù)為 8 位 JJJJ: JNB P3.2,$;等待地址碼第一位的信號 LCALL YS1;開始后用 882 微秒的時間尺去判斷信號此時的高低電平狀態(tài)MOV C,P3.2;將 P3.2 引腳此時的電平狀態(tài) 0 或 1

9、 存入C 中JNC UUU;如果為 0 就跳轉(zhuǎn)到 UUU LCALL YS3;檢測到1 的話延時 1 毫秒等待脈沖結(jié)束UUU: MOV A,R1;將 R1 中地址的給 ARRC A;將C 中的值 0 或 1 移入A 中的最低位MOV R1,A;將 A 中的數(shù)暫時存放在 R1 數(shù)值的內(nèi)存中DJNZ R3,JJJJ;接收滿 8 位換一個內(nèi)存INC R1;對 R1 中的值加 1,換下一個 RAMDJNZ R2,PP ;接收完 8 位數(shù)據(jù)碼和 8 位數(shù)據(jù)反碼,存放在 1AH/1BH 中MOV A,1AHCPL A;對 1AH 取反后和 1BH 比較CJNE A,1BH,EXIT;如果不等表示接收數(shù)據(jù)發(fā)

10、生錯誤,放棄MOV P1,1AH;將按鍵的鍵值通過 P1 口的 8 個LED 顯示出來!CLR P2.5;蜂鳴器鳴響嘀嘀嘀 LCALL YS2LCALL YS2 LCALL YS2SETB P2.5;蜂鳴器停止EXIT: SETB EA ;允許中斷,表示成功 RETI ;退出子程序YS1: MOV R4,#20 ;延時子程序 1,精確延時 882 微秒D1: MOV R5,#20 DJNZ R5,$DJNZ R4,D1 RETYS2: MOV R4,#10 ;延時子程序 2,精確延時 4740 微秒D2: MOV R5,#235 DJNZ R5,$DJNZ R4,D2RETYS3: MOV R

11、4,#2;延時程序 3,精確延時 1000 微秒D3:MOV R5,#248 DJNZ R5,$DJNZ R4,D3 RETEND0A0111 12 13 1415A 1B 0E 02 03 1C06 04 05 0C0D 08 09 1D00 1F 1E 0B070F按鍵的實(shí)際位置給出的 32 個按鍵的鍵值(16 進(jìn)制)這是按照紅外 Last edited by sina3228 on 2005-1-14 at 19:35 0000H AJMP MAIN0003H ;外部中斷0地址AJMP;轉(zhuǎn)中斷服務(wù)子程序MAIN: MOV SP,#40H MOV P1,#00HSETB EA ;開 CPU

12、 中斷SETB IT0 ;設(shè)定0 觸發(fā)方式SETB EX0 ;0 請求中斷DSP: MOV R2,#9 ;將MOV DPTR,#TAB1 VV: MOV A,R2鍵值轉(zhuǎn)化成 A(09)MOVC A, XRL A,1CH JZ ABC DJNZ R2,VVABC: MOV A,R2TRMOV DPTR,#TAB ;將A 的值通過數(shù)碼管顯示出來MOVC A,TRRX1: MOV P1,ACLR P0.1 AJMP DSP: CLR EA MOV R6,#10 SB: ACALL YS1 JB P3.2,EXIT DJNZ R6, SBJNB P3.2, $ ;等待避開 9 毫秒低電平引導(dǎo)脈沖ACA

13、LL YS2 ;延時 4。74 毫秒判斷是否連發(fā)JB P3.2,EXIT CPL P0.0MOV R1,#1AH ;將 32 位代碼分別放在 1AH/1BH/1CH/1DH 中MOV R2,#4 PP: MOV R3,#8JJJJ: JNB P3.2,$ LCALL YS1MOV C,P3.2 JNC UUU JB P3.2,$UUU: MOV A,R1 RRC AMOV R1,A DJNZ R3,JJJJ INC R1 DJNZ R2,PPMOV P2,1CHMOV A,1AH ;進(jìn)行代碼識別XRL A,#0 ;判斷 1AH 的值是否等于 00000000 JNZ EXI ;如果不同則無效將

14、 1CH 清零CLR P0.1 MOV A,1BHXRL A,#11110111B ;再判斷高 8 位地址是否正確JNZ EXI MOV A,1CH CPL AXRL A,1DH ;將 1CH 的值取反后和 1DH 比較 不同則無效丟棄核對數(shù)據(jù)是否準(zhǔn)確JNZ EXI AJMP EXITEXI: MOV 1CH,#0EXIT: SETB EA ;允許中斷RETIYS1: MOV R4,#20 ;精確延時 882 微秒D1: MOV R5,#20 DJNZ R5,$DJNZ R4,D1 RETYS2: MOV R4,#10 ;精確延時 4740 微秒D2: MOV R5,#235 DJNZ R5,

15、$DJNZ R4,D2 RETTAB: DB 60H,7DH,0D0H,58H,4DHDB 4AH,42H,7CH,40H,48HTAB1B 0CH,09H,1DH,1FH,0DHDB 19H,1BH,11H,15H,17HEND;TAB LED 數(shù)碼管顯示表 TAB1鍵值表2005-1-14#219:37sina3228高級會員紅外線程序編碼為uPD6121G(或者是 HT622、7461 等)為例來說明這里以紅外線用單片機(jī)實(shí)現(xiàn)紅外的詳細(xì)過程,站長琢磨這個程序花了相當(dāng)多的精力,期間幾經(jīng)修改逐步完善,后來還用它開發(fā)了幾個小產(chǎn)品,希望能對網(wǎng)友學(xué)習(xí)單片機(jī)有所幫助。紅外線是目前使用最廣泛的一種通信和

16、。由于紅外線機(jī)之后,在裝置具有體積小、功耗低、功能強(qiáng)、成本特點(diǎn),因而,繼彩電、機(jī)、音響設(shè)備、積分 354發(fā)貼 67空凋機(jī)以及玩具等其它小型電器裝置上也紛紛采用紅外線。工業(yè)設(shè)備中,在高壓、輻射、氣體、粉塵等環(huán)境下,采用紅外線不僅完全可靠而且能有效地電氣男2004-9-8來自 理工學(xué)院電子 2 班狀態(tài) 離線干擾。1 紅外系統(tǒng)系統(tǒng)由發(fā)射和接收兩大部分組成,應(yīng)用編/通用紅外集成電路來進(jìn)行控 制操作,如圖 1 所示。發(fā)射部分包括鍵盤矩陣、編碼調(diào)制、LED 紅外發(fā)送器;接收部分包括光、電轉(zhuǎn)換放大器、解調(diào)、電路。2及其編碼很多,根據(jù)編碼格式可以分成兩大類,這里以運(yùn)用比較廣泛,比較容易的一類來加以說明,現(xiàn)以

17、NEC 的uPD6121G 組成發(fā)射電路為例說明編 碼原理。當(dāng)按鍵按下后,即有碼發(fā)出,所按的鍵不同編碼也不同。這種碼具有以下特征:采用脈寬調(diào)制的串行碼,以脈寬為 0.565ms、間隔 0.56ms、周期為 1.125ms 的組合表示二進(jìn)制的“0”;以脈寬為 0.565ms、間隔 1.685ms、周期為 2.25ms 的組合表示二進(jìn)制的“1”其波形如圖 2 所示。上述“0”和“1”組成的 32 位二進(jìn)制碼經(jīng) 38kHz 的載頻進(jìn)行二次調(diào)制以提高發(fā)射效率,達(dá)到降低電源功耗的目的。然后再通過紅外發(fā)射二極管產(chǎn)生紅外線向空間發(fā)射,如圖 3 所示UPD6121G 產(chǎn)生的編碼是連續(xù)的 32 位二進(jìn)制碼組,其

18、中前 16 位為用戶識別碼,能區(qū)別不同的電器設(shè)備,防止不同機(jī)種碼互相干擾。該的用戶識別碼固定為十六 進(jìn)制 01H;后 16 位為 8 位操作碼(功能碼)及其反碼。UPD6121G 最多額 128 種不同組合的編碼。在按鍵按下后,周期性地發(fā)出同一種 32 位二進(jìn)制碼,周期約為 108ms。一組碼本身的持續(xù)時間隨它包含的二進(jìn)制“0”和“1”的個數(shù)不同而不同,大4563ms 之間,圖4 為發(fā)射波形圖。當(dāng)一個鍵按下超過 36ms,振蕩器使激活,將發(fā)射一組 108ms 的編碼脈沖,這 108ms發(fā)射代碼由一個起始碼(9ms),一個結(jié)果碼(4.5ms),低 8 位地址碼(9ms18ms),高8 位地址碼(

19、9ms18ms),8 位數(shù)據(jù)碼(9ms18ms)和這 8 位數(shù)據(jù)的反碼(9ms18ms組成。如果鍵按下超過 108ms 仍未松開,接下來發(fā)射的代碼(連發(fā)代碼)將僅由起始碼(9ms)和結(jié)束碼(2.5ms)組成。代碼格式(以接收代碼為準(zhǔn),接收代碼與發(fā)射代碼反向)位定義單發(fā)代碼格式連發(fā)代碼格式注:代碼寬度算法:16 位地址碼的最短寬度:1.1216=18ms 16 位地址碼的最長寬度:2.24ms16=36ms8 位數(shù)據(jù)代碼及其 8 位反代碼的寬度和不變:(1.12ms+2.24ms)8=27ms32 位代碼的寬度為(18ms+27ms)(36ms+27ms)1 的關(guān)鍵是如何識別“0”和“1”,從位

20、的定義 可以發(fā)現(xiàn)“0”、“1”均以 0.56ms 的低電平開始,不同的是 的寬度不同,“0”為 0.56ms,“1”為 1.68ms,所以必須根據(jù)高電平的寬度區(qū)別“0”和“1”。如果從 0.56ms 低電平過后,開始延時,0.56ms 以后,若讀到的電平為低,說明該位為“0”,反之則為“1”,為了可靠起見,延時必須比 0.56ms 長些但又 過 1.12ms, 否則如果該位為“0”,讀到的已是下一位的 ,因此?。?.12ms+0.56ms)/2=0.84ms 最為可靠,一般取 0.84ms 左右均可。2 根據(jù)碼的格式,應(yīng)該等待 9ms 的起始碼和 4.5ms 的結(jié)果碼完成后才能讀碼。如果郵購

21、開發(fā)的 51 單片機(jī)試驗(yàn)板和擴(kuò)展元件的網(wǎng)友,可以獲得如上圖所示的紅外遙控手柄,這種 的編碼格式符合上面的描述規(guī)律,而且價格低廉,有 32 個按鍵,按鍵外形比較 ,如果用于批量開發(fā),可以把 上貼膜換成你需要的字符,這為開發(fā)產(chǎn)品提供了便利。及紅外線 是一種集紅外線接收和放大于一體,不需要任何外接元件,就能完成從紅外線接收到輸出與 TTL 電平信號兼容的所有工作,而體積和普通的塑封三極管大小一樣,它適合于各種紅外線 和紅外線數(shù)據(jù)傳輸。下面是一個對 51 實(shí)驗(yàn)板配套的紅外線的程序,它可以把上圖 32 鍵的紅外遙控器每一個按鍵的鍵值讀出來,并且通過實(shí)驗(yàn)板上 P1 口的 8 個 LED 顯示出來,在成功的

22、同時并且能發(fā)出“嘀嘀嘀”的提示音。這是站長用單片機(jī)AT89C51 制作的 30 路紅外,就是自家的VCD器,接收板用了 5 片CD4069 作為輸出緩沖,當(dāng)按下30 個按鍵中的一個,接收板對應(yīng)的一個觸點(diǎn)會變成,松開按鍵,立即恢復(fù)成低電平,和 TTL 兼容。2005-1-1 #4 19:423sina3228紅外原理及程序高級會員積分 354發(fā)貼 67 男2004-9-8來自 理工學(xué)院 電子紅外一開始發(fā)送一段 13.5ms 的引導(dǎo)碼,引導(dǎo)碼由 9ms 的和 4.5ms 的低電平組成,跟著引導(dǎo)碼是系統(tǒng)碼,系統(tǒng)反碼,按鍵碼,按鍵反碼,如果按著鍵不放則則發(fā)送一段重復(fù)碼,重復(fù)碼由 9ms 的,2.25m

23、s 的低電平,跟著是一個短脈沖,本程序經(jīng)過試用,能解大部分的編碼!#include at89x52.h#define NULL 0 x00/數(shù)據(jù)無效 #define RESET 0X01/程序復(fù)位 #define REQUEST 0X02/請求信號#define ACK 0 x03/應(yīng)答信號,在接收數(shù)據(jù)后發(fā)送 ACK 信號表示數(shù)據(jù)接收正確,也位請求信號的應(yīng)答信號#define NACK 0 x04/應(yīng)答信號,表示接收數(shù)據(jù)錯誤 #define BUSY 0 x05/忙信號,表示正在忙2 班#define FREE 0 x06/空閑信號,表示處于空閑狀態(tài) #define READ_IR 0 x0b

24、/紅外#define STORE_IR 0 x0c/保存數(shù)據(jù) #define READ_KEY 0 x0d/鍵值#define RECEIVE 0Xf400/接收緩沖開始地址 #defiND 0 xfa00/發(fā)送緩沖開始地址 #define IR 0 x50/紅外接收緩沖開始地址 #define HEAD 0 xaa/數(shù)據(jù)幀頭#define TAIL 0 x55/數(shù)據(jù)幀尾 #define SDA P1_7#define SCL P1_6unsigned char xdata *buf1; /接受數(shù)據(jù)緩沖 unsignedbuf1_length; /接收到的數(shù)據(jù)實(shí)際長度 unsigned cha

25、r xdata *buf2; /發(fā)送數(shù)據(jù)緩沖 unsignedbuf2_length; /要發(fā)送的數(shù)據(jù)實(shí)際長度bit buf1_flag; /接收標(biāo)志,1 表示接受到一個數(shù)據(jù)幀,0 表示沒有接受到數(shù)據(jù)幀或數(shù)據(jù)幀為空bit buf2_flag; /發(fā)送標(biāo)志,1 表示需要發(fā)送或沒發(fā)送完畢,0 表示沒有要發(fā)送的數(shù)據(jù)或發(fā)送完畢unsigned char se1,se2; /用來標(biāo)志接收字符的狀態(tài),se1 用來表示接收狀態(tài) 離線狀態(tài),se2 用來表示發(fā)送狀態(tài)unsigned char data *ir; unionunsigned char a2;unsigned b; unsigned char da

26、ta *p12;unsigneddata *p22;unsigned char xdata *p3; /紅外緩沖的指針 unsignedxdata *p4;p;/union / unsigned char a2; / unsigned b;/ unsigned char data *p12;/ unsigneddata *p22;/ unsigned char xdata *p3;/ unsignedxdata *p4; /地址指針/q; /unionunsigned char a2;unsignedcount; unionunsigned char a2; unsignedb;temp; u

27、nionunsigned char a4; unsignedb2; unsigned long c;ir_code;unionunsigned char a4;unsigned b2; unsigned long c;unsigned char data *p14; unsigneddata *p24; unsigned char xdata *p32;unsigned xdata *p42;i;unsigned char ir_key;bit ir_flag; /紅外接收標(biāo)志,0 為緩沖區(qū)空,1 為接收成功,2 為緩沖溢出void sub(void); void delay(void); v

28、oid ie_0(void); void tf_0(void); void ie_1(void); void tf_1(void); void tf_2(void); void read_ir(void); void ir_jiema(void); void ir_init(void); void ir_exit(void); void store_ir(void);void read_key(void); void reset_iic(void);unsigned char read_byte_ack_iic(void); unsigned char read_byte_nack_iic(v

29、oid); bit write_byte_iic(unsigned char a);void send_ack_iic(void); void send_nack_iic(void); bit receive_ack_iic(void); void start_iic(void);b;void stop_iic(void);void write_key_data(unsigned char a);unsignedread_key_data(unsigned char a);void ie0(void) void tf0(void) void ie1(void) void tf1(void)vo

30、id tf2(void)errupt 0ie_0();errupt 1tf_0();errupt 2ie_1(); errupt 3tf_1();tf_2();errupt 5 /采用中斷方式跟查詢方式相結(jié)合的辦法EA=0; /中斷if(TF2) /判斷是否是溢出還是電平變化產(chǎn)生的中斷TF2=0; /如果是溢出產(chǎn)生的中斷則清除溢出位,重新開放中斷退出 EA=1;goto end;EXF2=0; /清除電平變化產(chǎn)生的中斷位*ir=RCAP2H; /把捕捉的數(shù)保存起來 ir+;*ir=RCAP2L;*ir+; F0=1;TR0=1; /開啟計數(shù)器 0 loop:TL0=0; /將計數(shù)器 0 重新置

31、為零TH0=0;while(!EXF2) /查詢等待 EXF2 變?yōu)?1if(TF0)goto exit; /檢查有沒超時,如果超時則退出;EXF2=0; /將EXF2 清零if(!TH0) /判斷是否是長低電平脈沖過來了 /不是長低電平脈沖而是短低電平 if(F0)count.b+; /短脈沖數(shù)加一 temp.a0=RCAP2H; /將捕捉數(shù)臨時存放起來 temp.a1=RCAP2L;goto loop; /返回繼續(xù)查詢else /是低電平脈沖,則進(jìn)行處理F0=0; *ir=temp.a0; /把連續(xù)的短脈沖總時間下來ir+;*ir=temp.a1; ir+; *ir=RCAP2H; /把長

32、電平脈沖時間下來ir+;*ir=RCAP2L;ir+; if(ir=0 xda) goto exit; /判斷是否溢出緩沖,如果溢出則失敗退出goto loop; /返回繼續(xù)查詢exit:ir_flag=1; /置 ir_flag 為 1 表示接收成功end:;void rs232(void)errupt 4sic unsigned char sbuf1,sbuf2,rsbuf1,rsbuf2; /sbuf1,sbuf2 用來接收發(fā)送臨時用,rsbuf1,rsbuf2 用來分別用來存放接收發(fā)送的半字節(jié)EA=0; /中斷if(RI)RI=0; /清除接收中斷標(biāo)志位sbuf1=SBUF; /將接收

33、緩沖的字符到sbuf1if(sbuf1=HEAD) /判斷是否幀開頭se1=10; /是則把 se 賦值為 10buf1=RECEIVE; /初始化接收地址elseswitch(se1)case 10:sbuf2=sbuf14; /把高半字節(jié)右移到的半字節(jié) sbuf2=sbuf2; /把低半字節(jié)取反 if(sbuf2&0 x0f)!=(sbuf1&0 x0f) /判斷接收是否正確 /接收錯誤,有可能接收的是數(shù)據(jù)幀尾,也有可能是接收錯誤 if(sbuf1=TAIL) /判斷是否接收到數(shù)據(jù)幀尾 /是接收到數(shù)據(jù)幀尾 buf1=RECEIVE; /初始化接收的地址if(*buf1=RESET) /判斷

34、是否為復(fù)位命令 ES=0;sbuf2=SP+1;for(p.p10=SP-0 x10;p.p104; /把高半字節(jié)右移到的半字節(jié) sbuf2=sbuf2; /將低半字節(jié)取反 if(sbuf2&0 x0f)!=(sbuf1&0 x0f) /判斷接收是否正確 /接受錯誤se1=0; / 將接收狀態(tài)標(biāo)志置為零,重新接收buf1=RECEIVE; /初始化接收的地址*buf1=NACK; /把NACK 信號存入發(fā)送緩沖里buf1_flag=1; /置標(biāo)志位為 1,使主程序能對接收錯誤進(jìn)行處理REN=0; /接收elsesbuf1&=0 x0f; /僅保留低半字節(jié),去掉高半字節(jié) rsbuf1|=sbuf

35、1; /高低半字節(jié)合并*buf1+=rsbuf1; /將接收的數(shù)據(jù)保存至接收緩沖里,并且數(shù)據(jù)指針加一 buf1_length+; /接收數(shù)據(jù)長度加一se1=10; /將se1 置為 10,準(zhǔn)備接收下個字節(jié)的高半字節(jié)break;elseTI=0; /清除發(fā)送中斷標(biāo)志 if(buf2_length) /判斷發(fā)送長度是否為零 /發(fā)送長度不為零if(se2=0) /判斷是否發(fā)送高半字節(jié) /發(fā)送高半字節(jié)sbuf2=*buf2; /將要發(fā)送的字節(jié)送到 sbuf2 rsbuf2=sbuf2; /取反,使高半字節(jié)變?yōu)榉创a sbuf2=4; /將高半字節(jié)右移到低半字節(jié) rsbuf2&=0 xf0; /保留高半字

36、節(jié),去掉低半字節(jié) sbuf2&=0 x0f; /保留低半字節(jié),去掉高半字節(jié) rsbuf2|=sbuf2; /合并高低半字節(jié) SBUF=rsbuf2; /發(fā)送出去se2=10; /將se2 置為 10 準(zhǔn)備發(fā)送下半字節(jié)else /發(fā)送低半字節(jié)sbuf2=*buf2; /將要發(fā)送的字節(jié)送到 sbuf2 buf2+; /指針加一buf2_length-; /發(fā)送數(shù)據(jù)長度減一 rsbuf2=sbuf2; /取反,使低半字節(jié)變?yōu)榉创arsbuf2=4; /將低半字節(jié)反碼到高半字節(jié)rsbuf2&=0 xf0; /保留高半字節(jié),去掉低半字節(jié) sbuf2&=0 x0f; /保留低半字節(jié),去掉高半字節(jié) rsbuf

37、2|=sbuf2; /合并高低半字節(jié) SBUF=rsbuf2; /發(fā)送出se2=0;else /如果發(fā)送數(shù)據(jù)長度為零則發(fā)送數(shù)據(jù)幀尾 if(buf2_flag) /判斷是否發(fā)過數(shù)據(jù)幀尾 SBUF=TAIL; /將數(shù)據(jù)幀尾發(fā)送出去 while(TI=0);TI=0;buf2_flag=0; /置發(fā)送標(biāo)志為零,表示發(fā)送完畢EA=1; /開放中斷void ack(void) /發(fā)送ACK 信號子程序buf1_flag=0; /置接收標(biāo)志位位零表示已經(jīng)相應(yīng)了,可以接收下一幀數(shù)據(jù) REN=1; /接收使能whiuf2_flag); /判斷上一幀有沒發(fā)送完,沒有則繼續(xù)等待 buf2=SEND; /初始化發(fā)送

38、地址*buf2=ACK; /將 ACK 信號存入發(fā)送緩沖里 buf2_length=1; /存入發(fā)送數(shù)據(jù)長度 buf2_flag=1; /置發(fā)送長度為 1 SBUF=HEAD; /發(fā)送數(shù)據(jù)幀頭void nack(void) /發(fā)送 NACK 信號子程序buf1_flag=0; /置接收標(biāo)志位位零表示已經(jīng)相應(yīng)了,可以接收下一幀數(shù)據(jù) REN=1; /接收使能whibuf2=S*buf2= buf2_len buf2_fl SBUF=void frebuf1_fl REN=1whi buf2=S*buf2= buf2_len buf2_fl SBUF=void bubuf1_fl REN=1whiu

39、f2_flag); /判斷上一幀有沒發(fā)送完,沒有則繼續(xù)等待END; /初始化發(fā)送地址NACK; /將NACK 信號存入發(fā)送緩沖里gth=1; /存入發(fā)送數(shù)據(jù)長度 ag=1; /置發(fā)送長度為 1 HEAD; /發(fā)送數(shù)據(jù)幀頭e(void) /發(fā)送FREE 信號子程序ag=0; /置接收標(biāo)志位位零表示已經(jīng)相應(yīng)了,可以接收下一幀數(shù)據(jù); /接收使能uf2_flag); /判斷上一幀有沒發(fā)送完,沒有則繼續(xù)等待 END; /初始化發(fā)送地址FREE; /將 FREE 信號存入發(fā)送緩沖里gth=1; /存入發(fā)送數(shù)據(jù)長度 ag=1; /置發(fā)送長度為 1 HEAD; /發(fā)送數(shù)據(jù)幀頭sy(void) /發(fā)送BUSY

40、信號子程序ag=0; /置接收標(biāo)志位位零表示已經(jīng)相應(yīng)了,可以接收下一幀數(shù)據(jù); /接收使能uf2_flag); /判斷上一幀有沒發(fā)送完,沒有則繼續(xù)等待buf2=SEND; /初始化發(fā)送地址*buf2=BUSY; /將BUSY 信號存入發(fā)送緩沖里 buf2_length=1; /存入發(fā)送數(shù)據(jù)長度 buf2_flag=1; /置發(fā)送長度為 1 SBUF=HEAD; /發(fā)送數(shù)據(jù)幀頭void download(void)i; /用于循環(huán)計數(shù)i=buf1_length-3; /數(shù)據(jù)長度等于數(shù)據(jù)包長度減去一個字節(jié)控制字和兩個字節(jié)地址buf1=RECEIVE+1; /使指針指向地址 p.a0=*buf1+;

41、/讀入目標(biāo)地址高字節(jié) p.a1=*buf1+; /讀入目標(biāo)地址低字節(jié) while(i-) /長度減一直至為零*p.p3+=*buf1+; /將接受緩沖里數(shù)據(jù)送到目標(biāo)地址,并且兩個指針加一REN=1; /數(shù)據(jù)處理完,允許接收下一幀數(shù)據(jù) buf1_flag=0; /置接收標(biāo)志為零,表示已經(jīng)處理完 free(); /發(fā)送 FREE 信號表示已經(jīng)處理完處于空閑狀態(tài)void upload(void)i; / whiuf2_flag); /判斷上一幀有沒發(fā)送完,沒有則繼續(xù)等待buf1=RECEIVE+1; /將指針指向地址 buf2=SEND; /初始化發(fā)送地址*buf2+=UPLOAD; /把控制字存進(jìn)

42、去并且指針加一*buf2+=*buf1+; /把地址高字節(jié)過去*buf2+=*buf1+; /把地址低字節(jié)過去p.a0=*buf1+; /把數(shù)據(jù)長度高字節(jié)過去p.a1=*buf1+; /把數(shù)據(jù)長度低字節(jié)過去i=p.b; /把數(shù)據(jù)長度過去buf1-=4; /將指針減 4,使其指向地址處 p.a0=*buf1+; /把地址高字節(jié)過去 p.a1=*buf1+; /把地址低字節(jié)過去 buf1_flag=0; /已經(jīng)對接受數(shù)據(jù)處理完畢 REN=1; /允許接收buf2_length=i+3; /數(shù)據(jù)包長度等于數(shù)據(jù)長度加 3while(i-) /判斷數(shù)據(jù)長度是否為零,為零則不執(zhí)行循環(huán)語句,同時長度減一*b

43、uf2+=*p.p3+; /把數(shù)據(jù)到發(fā)送緩沖區(qū)buf2=SEND;buf2_flag=1; /置發(fā)送標(biāo)志為 1 SBUF=HEAD; /發(fā)送數(shù)據(jù)幀頭void run(void) /運(yùn)行的程序sub();void delay1s(void)for(i.b0=0;i.b00 x f;i.b0+)i.b0=i.b0+; i.b0=i.b0-;void ir_init(void)ir_flag=0; /將紅外接收標(biāo)志置為零 for(ir=IR;iri.b1)i.b0=0 x f-i.b0;i.b0+=i.b1; i.b0+;elsei.b0=i.b1-i.b0;*p.p20=i.b0; p.p20+;

44、i.b0=*p.p20;p.p21+;i.b1=*p.p21;*p.p20=0;p.p20=IR;temp.b=*p.p20; ir_code.c=count.b;ir_code.b0=(ir_code.c*1536000)/temp.b;for(;temp.b!=0*p.p20=temp.b/154; p.p20+;temp.b=*p.p20;ir_code.b1=0; if(p.p20=IR+132) p.p20=IR;p.p20+=3;i.c=0; temp.b=*p.p20;for(;temp.b!=0 i.c=11) i.a3+; p.p20+=2;temp.b=*p.p20;if(

45、i.a0=(i.a1)&i.a2=(i.a3) ir_code.a2=i.a0;ir_code.a3=i.a2;else ir_code.b0=0;else if(p.p20=IR+4) p.p20=IR;p.p20+;temp.b=*p.p20; if(temp.b=30) ir_code.b0=1;else ir_code.b0=0;else ir_code.b0=2;/if(ir_flag=2)ir_code.b0=3;void read_ir(void) buf1_flag=0; REN=1;buf2_length=4;whiuf2_flag); ir_init();while(!ir

46、_flag); ir_exit(); ir_jiema(); buf2=SEND;*buf2+=ir_code.a0;*buf2+=ir_code.a1;*buf2+=ir_code.a2;*buf2=ir_code.a3; buf2=SEND; buf2_flag=1; SBUF=HEAD;void delay(void)void start_iic(void) SCL=0;SDA=1;delay();delay(); SCL=1;delay(); SDA=0;delay(); SCL=0;delay();void stop_iic(void) SDA=0;delay(); SCL=1;de

47、lay(); SDA=1;delay(); SCL=0;delay();delay(); SCL=1;delay();void send_ack_iic(void) SDA=0;delay(); SCL=1;delay();delay(); SCL=0;delay();void send_nack_iic(void) SDA=1;delay(); SCL=1;delay();delay(); SCL=0;delay();bit receive_ack_iic(void) bit a;SDA=1;delay(); SCL=1;delay(); if(SDA) a=1;else a=0; dela

48、y(); SCL=0;delay(); return a;unsigned char read_byte_ack_iic(void) unsigned char a;SDA=1; for(p.a0=0;p.a08;p.a0+)a=1;delay(); SCL=1;delay(); if(SDA) a+;delay(); SCL=0;delay();send_ack_iic(); return a;unsigned char read_byte_nack_iic(void) unsigned char a;SDA=1; for(p.a0=0;p.a08;p.a0+) a=1;delay(); S

49、CL=1;delay(); if(SDA) a+;delay(); SCL=0;delay();send_nack_iic(); return a;void reset_iic(void) SDA=1;for(p.a0=0;p.a010;p.a0+) SCL=0;delay();delay(); SCL=1;delay();delay();bit write_byte_iic(unsigned char a) for(p.a0=0;p.a08;p.a0+)if(a&0 x80) SDA=1;else SDA=0;delay(); SCL=1;delay();delay(); SCL=0;del

50、ay(); a=1;return receive_ack_iic(); unsigned read_key_data(unsigned char a) unionunsigned char a2; unsigned b;key_data; reset_iic(); start_iic(); write_byte_iic(0 xa0); write_byte_iic(a); start_iic(); write_byte_iic(0 xa1);key_data.a0=read_byte_ack_iic(); key_data.a1=read_byte_nack_iic(); stop_iic()

51、;return key_data.b;void write_key_data(unsigned char a) reset_iic();start_iic(); write_byte_iic(0 xa0); write_byte_iic(a); write_byte_iic(ir_code.a2); write_byte_iic(ir_code.a3); stop_iic();void store_ir(void) buf1_flag=0; REN=1; buf1=RECEIVE+1;*buf1=(*buf1)1; write_key_data(*buf1);unsigned char yim

52、a(void) unsigned char a;for(a=0;a=1;return a;void read_key() unsigned char a; buf1_flag=0; REN=1;ir_init(); while(!ir_flag); ir_exit(); ir_jiema(); buf2=SEND; a=yima(); if(a=50)*buf2=0 xff;else *buf2=a; buf2_length=1; buf2_flag=1; SBUF=HEAD;main()unsigned char ctr; delay1s(); P0=0 xff; P1=0 xff; P2=

53、0 xff; P3=0 xff;ctr=0; buf1=RECEIVE; buf2=SEND; buf1_length=0; buf2_length=0; buf1_flag=0; buf2_flag=0;se1=0; se2=0;SP=0 xe0; /將堆棧指針指向高端TL2=0 xfb;TH2=0 xff; /溢出值為 5,波特率為 115.2Kbps; RCAP2H=0 xff;RCAP2L=0 xfb;SCON=0 x50; /方式 1,8 位方式,SM0=0,SM1=1,SM2=0,REN=1 允許接收IE=0 x10; /串行中斷允許,全局中斷不允許 T2CON=0 x34; /R

54、CLK=1,TCLK=1,TR2=1 啟動計數(shù)器EA=1; /開放全局中斷 free();while(1)/ir_init();/while(!ir_flag);/ir_exit();/ir_jiema();/if(yima()=0) P1_0=1;/if(yima()=1) P1_0=0;if(buf1_flag) buf1=RECEIVE;ctr=*buf1;switch(ctr) case ACK: ack(); break;case NACK: nack(); break;case FREE: free(); break;case BUSY: busy(); break;case DO

55、WNLOAD: download(); break;case UPLOAD: upload(); break;case RUN: run(); break;case READ_IR: read_ir(); break;case READ_KEY: read_key(); break;case STORE_IR: store_ir(); break;default: buf1_flag=0; REN=1;break;void sub(void)void ie_0(void)void tf_0(void)void ie_1(void)void tf_1(void)void tf_2(void)20

56、05-1-14#419:45sina3228高級會員紅外線讀碼機(jī)源程序和說明;紅外線讀碼機(jī),用本實(shí)例配合 PIC 單片機(jī)的 ST 套件可讀出任何 6121 或6122(CD6121/CD6122/SC6121/SC6122)及其兼容碼。的紅外線的用戶碼、鍵;本例是一個紅外線掃描程序,程序中數(shù)碼管顯示用的是定時器中斷法的動態(tài)接收 ;動態(tài)顯示二位數(shù)碼管的方法,中斷法,流點(diǎn)亮。 ;對準(zhǔn)實(shí)驗(yàn)板紅外線接收頭輕按要測定的碼管將顯示該鍵的鍵碼,以 3MS 中斷一次從而交換兩位數(shù)碼管輪的待測按鍵一次,此時實(shí)驗(yàn)板的兩位數(shù)積分 354發(fā)貼 67男2004-9-8來自 理工學(xué)院 電子 2 班狀態(tài) 離線 ;(顯示為1

57、6 進(jìn)制的),輕觸實(shí)驗(yàn)板的S2 此時顯示器切換為顯示當(dāng)前用戶碼的低8位, 再次輕觸實(shí)驗(yàn)板的 S2 此時顯示器切換為顯示當(dāng)前用戶碼的高 8 位,;再一次輕觸實(shí)驗(yàn)板的 S2 此時顯示又回到顯示當(dāng)前鍵的鍵碼,用按鍵 S2 可反復(fù)循環(huán)顯示用戶碼低 8 位、高 8 位、鍵碼。;注意:所有的顯示均為 16 進(jìn)制,A顯示為A,B顯示為b,C顯示為c,D顯示為d,E顯示為E,F顯示為F.;注意6121 的發(fā)射碼依次為:同步頭(引導(dǎo)碼)+32 位數(shù)據(jù)碼(用戶碼低8 位+用戶碼高 8 位+鍵碼+鍵碼的反碼);引導(dǎo)碼是由 9MS 的低電平加 4.5MS 的加 4.5MS 的低電平,接收到的剛好反相為 9MS 的.;

58、數(shù)據(jù)碼0是由 560US 的電平加 560US 的;數(shù)據(jù)碼1是由 560US 的電平加 1.69MS 的加 560US 的低電平,接收時反相為 560US 的低.加 1.69MS 的,接收時反相為 560US 的低.;PIC 單片機(jī);程序文件名:“ST-RMT.ASMht;燒寫時應(yīng)注意:配置位已經(jīng)在程序中寫明,加載HEX 文件時會自動加載,燒寫時不用再手動設(shè)置配置位。;實(shí)驗(yàn)時請注意套件跳線選擇;;* LIST P=16F84A,R=DEC ;定義器件為 16F84,默認(rèn)數(shù)制為十進(jìn)制; CONFIG B11111111110001;_CP_OFF&_WDT_OFF&_PWRITE_ON&_XT_

59、OSC;沒有代碼保護(hù);看門狗關(guān)閉;上電廷時器開啟;振蕩器模式為 XT;RTCCEQU 01HPCEQU 02H;定義定時器 0 地址;定義程序計數(shù)器低字節(jié)寄存器地址;定義狀態(tài)寄存器地址;定義RA 口數(shù)據(jù)寄存器地址;定義RB 口數(shù)據(jù)寄存器地址SUS EQU 03HPORTA EQU 05HPORTB EQU 06HCON EQU 0BH;定義中斷控制寄存器OPTION_REG EQU 81H;定義 RA 口方向控制寄存器;定義RB 口方向控制寄存器TRISATRISBEQU 85HEQU 86H;SUS;定義進(jìn)位標(biāo)志位位地址;定義 0 標(biāo)志位位地址;寄存器體選 CON;定時器 0 溢出中斷標(biāo)志位

60、;定時器 0 溢出中斷允許/;總中斷允許/C ZRP0;EQU 0EQU 2EQU 5T0IF T0IE GIE;EQU 2EQU 5EQU 7RMT;EQU 4;接收輸入腳位地址(RA。4)BITIN;EQU 7;接收數(shù)據(jù)位位標(biāo)志CNT0 CNT1 CNT2 CNT3 TABADD FLAGSDISPBUF_H DISPBUF_LW_TEMPEQU 20H EQU 21H EQU 22H EQU 23HEQU 24H EQU 25HEQU 26H EQU 27HEQU 2BH;用戶臨時寄存器 1;用戶臨時寄存器 2;用戶臨時寄存器 3;用戶臨時寄存器 4;數(shù)碼管顯示碼取碼用寄存器;顯示位選標(biāo)

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論