12F629解PT2262IR的源程序(zt)
發(fā)布時(shí)間:2008年1月5日 2時(shí)8分
這段程序是用在一款七彩燈紅外遙控解碼程序里,單片機(jī)使用PIC12F629,軟件模擬三路PWM輸出驅(qū)動(dòng)紅綠藍(lán)LED分八組共24個(gè)LED,實(shí)現(xiàn)單LED漸明漸暗,兩LED一明一暗,七彩等九種花樣.有斷電記憶功能.如下是解碼程序. ;-------------------------------------------------------- ;filename: 24LED_Remote.asm ; mcu: PIC12f629 ; clock: 4 MHz for INTRC ; date: 2006/02/25 ; writer: aLin ; IC type: PT2262IR ; Rosc: 470K ;-------------------------------------------------------- list p=pic12f629 #i nclude"p12f629.inc" #define B_LED gpio,0 ;綠LED輸出端口 #define G_LED gpio,1 ;藍(lán)LED輸出端口 #define R_LED gpio,2 ;紅LED輸出端口 #define rem gpio,3 ;GP3/MCLR,定義遙控輸入端 ;因?yàn)楫?dāng)按住PT2262的按鍵不放的時(shí)候 ;PT2262會(huì)把編碼不斷的送出 ;設(shè)置ENABLE位用來檢測(cè)按鍵有沒有放開過, ;如果沒有放開則不再響應(yīng) ;用于遙控型 #define enable user_reg,0 ;接收允許位 #define on_off user_reg,1 ;該位為0時(shí),按花樣選擇鍵無效 #define go_next user_reg,2 ;該位為1時(shí),跳下一段 #define reset user_reg,3 ;該位為1時(shí),關(guān)顯示 #define unlock user_reg,4 ;用于配合on_off位 ;--------------------------------------------------------- ;定義變量 ; r1 equ 20h ;用于d5ms子程序 r2 equ 21h ;用于d5ms子程序 r3 equ 22h ;用于d320mS子程序 P_reg equ 23h ;正脈寬時(shí)間寄存器 N_reg equ 24h ;負(fù)脈寬時(shí)間寄存器 count1 equ 25h ;計(jì)數(shù)器1 count2 equ 26h ;計(jì)數(shù)器2 W_temp equ 27h ;W臨時(shí)寄存器 user_reg equ 28h ;用戶寄存器 ee_data equ 29h ;eeprom讀寫數(shù)據(jù)出入口 ee_addr equ 2ah ;eeprom讀寫地址入口 data_temp equ 2bh ;用于暫存從EEPROM讀出的數(shù)所數(shù)據(jù) index_reg equ 2ch ;用于保存引導(dǎo)值 data_reg equ 2dh ;用于保存從EEPROM讀出的值 A0_addr1 equ 30h A0_addr2 equ 31h A1_addr1 equ 32h A1_addr2 equ 33h r5 equ 34h ;用于解碼延時(shí) r6 equ 35h ;用于解碼延時(shí) addr_set1 equ 36h ;用于存儲(chǔ)比較密碼 addr_set2 equ 37h ;用于存儲(chǔ)比較密碼 output equ 38h count equ 39h ;接收12位編碼 status_temp equ 3ah ;保存status的值,用于現(xiàn)場(chǎng)保護(hù) ww_temp equ 3bh ;W工作寄存器,用于現(xiàn)場(chǎng)保護(hù)用 A0_data1 equ 3ch ;用于存儲(chǔ)比較數(shù)據(jù)D8 A0_data2 equ 3dh ;用于存儲(chǔ)比較數(shù)據(jù)D8 A1_data1 equ 3eh ;用于存儲(chǔ)比較數(shù)據(jù)D11 A1_data2 equ 3fh ;用于存儲(chǔ)比較數(shù)據(jù)D11 ;------------------------------------------- ;定義常數(shù) ; index equ 00h ;EEData數(shù)據(jù)引導(dǎo)地址 ;-------------------------------------------------- org 0000h call init ;調(diào)用初始化程序 goto main ;-------------------------------------------------- ;中斷處理入口 ;TMR1溢出中斷,說明按鍵松開時(shí)間大于等于65.536mS左右 org 0004h MOVwf ww_temp ;保護(hù)現(xiàn)場(chǎng) swapf status,w MOVwf status_temp bcf intcon,gie ;關(guān)所有中斷 bcf t1con,tmr1on ;停止TMR1 bcf pir1,tmr1if ;清TMR1中斷標(biāo)志位 bcf enable ;按鍵松開,清e(cuò)nable swapf status_temp,w MOVwf status swapf ww_temp,f swapf ww_temp,w return ;-------------------------------------------------- ;讀出引導(dǎo)地址單元(00H)內(nèi)容 main MOVlw index ;送引導(dǎo)地址中轉(zhuǎn) MOVwf ee_addr call ee_data_rd ;調(diào)用讀EEPROM程序 MOVf ee_data,w ;讀出引導(dǎo)地址內(nèi)容 MOVwf index_reg ;保存引導(dǎo)地址內(nèi)容 MOVwf ee_addr ;送待讀出內(nèi)容地址 call ee_data_rd MOVf ee_data,w MOVwf data_reg ;保存讀出 MOVf data_reg,w addlw jumper_tab MOVwf pcl jumper_tab goto start ;跳到開始0段 goto seg1 ;跳到第1段 goto seg2 ;跳到第2段 goto seg3 ;跳到第3段 goto seg4 ;跳到第4段 goto seg5 ;跳到第5段 goto seg6 ;跳到第6段 goto seg7 ;跳到第7段 goto seg8 ;跳到第8段 ;------------------------------------------------ 如下略.... ;----------------------------------------------- ; ;解碼程序 ; ;--------------------------------------------------------- ; A0 | A1 | 說明 ;-----+-----+------------------ ; 30H | 32H | 接收的8位地址編碼 ;-----+-----+------------------ ; 31H | 33H | 接收的4位數(shù)據(jù)編碼 ;-----+-----+------------------ ; 36H | 37H | 設(shè)定的8位地址密碼 ;------------------------------ ; ; A0_addr1 equ 30h ; A0_addr2 equ 31h ; A1_addr1 equ 32h ; A1_addr2 equ 33h ; ;其中以30H,0和32H,0為例 ;懸空: 30H,0=1,32H,0=0 ;1: 30H,0=0,32H,0=0 ;0: 30H,0=1,32H,0=1 ;38H: 輸出控制 ;--------------------------------------------------------- ; ;解碼子程序 check_sw btfss rem ;rem為1,無接收到信號(hào),返回 goto remote0 bcf go_next ;沒按鍵,清0 bcf reset ;沒按鍵,清0 bcf unlock remote_end return ;沒有按鍵,反回 ;-------------------------------------------------------- remote0 btfss enable ;rem為0,但enable為1,按鍵沒放開,返回 goto incept ;接收12位編碼 ;重新設(shè)定TMR1 bcf t1con,tmr1on ;停止TMR1 clrf tmr1h ;ffff為65.536mS clrf tmr1l bsf t1con,tmr1on ;重啟動(dòng)TMR1 bcf reset ;按鍵沒松開,解碼取消,清0 bcf go_next ;按鍵沒松開,解碼取消,清0 bcf unlock goto remote_end ;按鍵沒有放開,返回 ;清除上次解碼內(nèi)容 ;接收12位編碼 ; incept MOVlw .12 MOVwf count ;解碼 ;先找出接收到的開頭,即16mS左右的高電平 ;設(shè)置高電平時(shí)間為15~17mS ; ;檢測(cè)和等待15mS的高電平 ; remote1 MOVlw .30 MOVwf r5 remote2 MOVlw .100 MOVwf r6 remote3 btfss rem goto remote1 decfsz r6,f goto remote3 decfsz r5,f goto remote2 ;等待在2mS內(nèi)接收到的低電平 MOVlw .4 MOVwf r5 remote4 MOVlw .100 MOVwf r6 ;15mS到17mS內(nèi)接收到下降沿,則跳去解碼,否則返回 remote5 btfss rem goto remote6 decfsz r6,f goto remote5 decfsz r5,f goto remote4 ;超出17mS,接收錯(cuò)誤,返回 bcf enable goto remote_end ;等待1200uS后,采集接收信號(hào) remote6 MOVlw .200 MOVwf r5 decfsz r5,f goto $-1 MOVlw .200 MOVwf r5 decfsz r5,f goto $-1 ;采集接收信號(hào),并記錄 btfss rem ;如果rem為1,則c置1,否則清0 clrc btfsc rem setc ;rem為1,c置1 rlf A0_addr2,f rlf A0_addr1,f ;等待第二個(gè)下降沿 ;加入了限時(shí)判斷,防止死循環(huán)。 ; ; btfss rem ;rem為0,一直執(zhí)行 ; goto $-1 MOVlw .255 MOVwf r5 btfsc rem ;rem為0,一直執(zhí)行 goto $+4 decfsz r5,f goto $-3 goto remote8 ;超時(shí),跳到錯(cuò)誤處理 ; btfsc rem ;rem為1,一直執(zhí)行 ; goto $-1 MOVlw .255 MOVwf r5 btfss rem ;rem為1,一直執(zhí)行 goto $+4 decfsz r5,f goto $-3 goto remote8 ;超時(shí),跳到錯(cuò)誤處理 ;等待1200uS后采集接收信號(hào) MOVlw .200 MOVwf r5 decfsz r5,f goto $-1 MOVlw .200 MOVwf r5 decfsz r5,f goto $-1 btfss rem ;如果rem為1,則c置1,否則清0 clrc btfsc rem setc ;rem為1,c置1 rlf A1_addr2,f rlf A1_addr1,f ;等待第二個(gè)碼值的下降沿 ;加入了限時(shí)判斷,防止死循環(huán)。 ; ; btfss rem ;rem為0,一直執(zhí)行 ; goto $-1 MOVlw .255 MOVwf r5 btfsc rem ;rem為0,一直執(zhí)行 goto $+4 decfsz r5,f goto $-3 goto remote8 ;超時(shí),跳到錯(cuò)誤處理 ; btfsc rem ;rem為1,一直執(zhí)行 ; goto $-1 MOVlw .255 MOVwf r5 btfss rem ;rem為1,一直執(zhí)行 goto $+4 decfsz r5,f goto $-3 goto remote8 ;超時(shí),跳到錯(cuò)誤處理 decfsz count,f goto remote6 ;連續(xù)接收12位 goto decode ;接收完12位編碼,跳到解碼 ;開始解碼 ;把接收的編碼左移4位,將8位密碼放在同一字節(jié)上 decode MOVlw .4 MOVwf count remote7 clrc rlf A0_addr2,f rlf A0_addr1,f clrc rlf A1_addr2,f rlf A1_addr1,f decfsz count,f goto remote7 ;把4位數(shù)據(jù)編碼由高4位移到低4位上 swapf A0_addr2,f swapf A1_addr2,f ;比較密碼 MOVf A0_addr1,w xorwf addr_set1,w skpz goto remote8 ;跳到接收錯(cuò)誤處理 MOVf A1_addr1,w xorwf addr_set2,w skpz goto remote8 ;跳到接收錯(cuò)誤處理 ;接收正確處理 ;每次按鍵都一次響應(yīng) ;按鍵為PT2262IR pin10(D8) 和 pin13(D11) ;以下只識(shí)別D8、D11,對(duì)數(shù)據(jù)理D9、D10不作處理 ; ;懸空: A0=1 , A1=0 ; 1: A0=0 , A1=0 ; 0: A0=1 , A1=1 ; ;檢查鍵值D8,ON/OFF鍵 MOVf A0_addr2,w andlw 0fh xorwf A0_data1,w skpz goto D11 ;不是只有鍵值D8按下,檢查鍵值D11, ;即D8沒有按下或D8按下同時(shí)還有其它按鍵按下 MOVf A1_addr2,w andlw 0fh xorwf A1_data1,w skpz goto D11 ;不是只有鍵值D8按下,檢查鍵值D11 ;即D8沒有按下或D8按下同時(shí)還有其它按鍵按下 ;是鍵值D8按下,開始處理 ;on/off處理,按下on/off鍵假如on, ;再按下就是off,然后再按下又是off。 MOVlw b'00000010' ;取反user_reg的on_off位 xorwf user_reg,f btfss on_off ;on_off位為0,reset置1,返回時(shí)關(guān)顯示 goto clr_rst bsf unlock ;on_off位為1,置unlock為1,返回時(shí)開顯示 goto back ;檢查鍵值D11,NEXT鍵。 D11 btfss on_off ;on_off為0,當(dāng)前已關(guān)顯示,按鍵NEXT無效 goto back ;返回 MOVf A0_addr2,w andlw 0fh xorwf A0_data2,w skpz goto back ;也不是只有鍵值D11按下,返回 ;即D11沒有按下或D11按下同時(shí)還有其它按鍵按下 MOVf A1_addr2,w andlw 0fh xorwf A1_data2,w skpz goto back ;也不是只有鍵值D11按下,返回 ;即D11沒有按下或D11按下同時(shí)還有其它按鍵按下 ;是鍵值D11按下,開始處理 bsf go_next ;跳下一段 bcf reset goto back clr_rst bsf reset bcf go_next goto back back bcf t1con,tmr1on ;停止TMR1 clrf tmr1h clrf tmr1l bsf t1con,tmr1on ;啟動(dòng)TMR1 bsf enable ;置1,防止開關(guān)按住不放,不斷響應(yīng)。 work_end retfie ;返回并開中斷 ;接收錯(cuò)誤處理 remote8 bcf enable bcf go_next ;密碼錯(cuò)誤,取消解碼,清0 bcf reset ;密碼錯(cuò)誤,取消解碼,清0 bcf unlock bsf enable ;雖接收錯(cuò)誤,但都是有按鍵按下 ;重新設(shè)定TMR1 bcf t1con,tmr1on ;停止TMR1 clrf tmr1h ;ffff為65.536mS clrf tmr1l bsf t1con,tmr1on ;重啟動(dòng)TMR1 retfie ;返回并開中斷 ;------------------------------------------- ;初始化程序 init bsf status,rp0 ;選擇bank1 call 3ffh MOVwf osccal MOVlw b'00001000' ;GP0/1/2為輸出 MOVwf trisio ;GP3為輸入 clrf ioc ;關(guān)閉所有電平變化中斷 bsf pie1,tmr1ie ;開TMR1中斷 bcf status,rp0 ;選擇bank0 bcf intcon,gie ;關(guān)所有中斷 bsf intcon,peie ;開外設(shè)中斷 bcf t1con,tmr1on ;停止TMR1 clrf gpio ;輸出清0 MOVlw 07h MOVwf cmcon ;設(shè)置GP0/1/2為IO bcf enable ;頭次上電,初始化enable、reset、go_next bcf reset bcf go_next ;編碼地址設(shè)定為:A0~A7為懸空(A0=1,A1=0) MOVlw b'11111111' ;A0 MOVwf addr_set1 MOVlw b'00000000' ;A1 MOVwf addr_set2 ;D8設(shè)置1(A0=0,A1=0),D9、D10懸空(A0=1,A1=0) ;D11設(shè)置0(A0=1,A1=1),該狀態(tài)為只有D8按下。D8為ON/OFF鍵。 MOVlw b'00001110' ;A0 MOVwf A0_data1 MOVlw b'00001000' ;A1 MOVwf A1_data1 ;D11設(shè)置1(A0=0,A1=0),,D9、D10懸空(A0=1,A1=0) ;D8設(shè)置0(A0=1,A1=1),該狀態(tài)為只有D11按下。D11為NEXT鍵。 MOVlw b'00000111' ;A0 MOVwf A0_data2 MOVlw b'00000001' ;A1 MOVwf A1_data2 return ;------------------------------------------------------ end |