×
单片机 > 单片机程序设计 > 详情

PT2262解码程序( pic12F629 )

发布时间:2020-05-16 发布时间:
|

这段程序是用在一款七彩灯红外遥控解码程序里,单片机使用PIC12F629,软件模拟三路PWM输出驱动红绿蓝LED分八组共24个LED,实现单LED渐明渐暗,两LED一明一暗,七彩等九种花样.有断电记忆功能.如下是解码程序. 
  
;-------------------------------------------------------- 
;filename: 24LED_Remote.asm 
;     cpu: 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   ;蓝LED输出端口 
        #define    R_LED    gpio,2   ;红LED输出端口 
        #define    rem      gpio,3   ;GP3/MCLR,定义遥控输入端seg9 
                  
;因为当按住PT2262的按键不放的时候 
;PT2262会把编码不断的送出 
;设置ENABLE位用来检测按键有没有放开过, 
;如果没有放开则不再响应           
;用于遥控型 
         
        #define    enable       user_reg,0     ;接收允许位  
        #define    on_off       user_reg,1     ;该位为0时,按花样选择键无效 
        #define    go_next      user_reg,2     ;该位为1时,跳下一段 
        #define    reset        user_reg,3     ;该位为1时,关显示   
        #define    unlock       user_reg,4     ;用于配合on_off位 
;--------------------------------------------------------- 
;定义变量 

        r1    equ    20h       ;用于d5ms子程序 
        r2    equ    21h       ;用于d5ms子程序 
        r3    equ    22h       ;用于d320mS子程序 
     P_reg    equ    23h       ;正脉宽时间寄存器 
     N_reg    equ    24h       ;负脉宽时间寄存器 
    count1    equ    25h       ;计数器1 
    count2    equ    26h       ;计数器2 
    W_temp    equ    27h       ;W临时寄存器 
  user_reg    equ    28h       ;用户寄存器 
   ee_data    equ    29h       ;eeprom读写数据出入口 
   ee_addr    equ    2ah       ;eeprom读写地址入口 
 data_temp    equ    2bh       ;用于暂存从EEPROM读出的数所数据 
 index_reg    equ    2ch       ;用于保存引导值 
  data_reg    equ    2dh       ;用于保存从EEPROM读出的值      
             
   A0_addr1   equ    30h 
   A0_addr2   equ    31h  
   A1_addr1   equ    32h 
   A1_addr2   equ    33h  
         r5   equ    34h       ;用于解码延时  
         r6   equ    35h       ;用于解码延时  
  addr_set1   equ    36h       ;用于存储比较密码       
  addr_set2   equ    37h       ;用于存储比较密码  
     output   equ    38h 
      count   equ    39h       ;接收12位编码 
status_temp   equ    3ah       ;保存status的值,用于现场保护 
    ww_temp   equ    3bh       ;W工作寄存器,用于现场保护用 
   A0_data1   equ    3ch       ;用于存储比较数据D8  
   A0_data2   equ    3dh       ;用于存储比较数据D8 
   A1_data1   equ    3eh       ;用于存储比较数据D11 
   A1_data2   equ    3fh       ;用于存储比较数据D11 
;------------------------------------------- 
;定义常数 

     index    equ    00h       ;EEData数据引导地址 
                              
;--------------------------------------------------       
            org 0000h 
             
            call init          ;调用初始化程序 
            goto main 
             
;-------------------------------------------------- 
;中断处理入口 
;TMR1溢出中断,说明按键松开时间大于等于65.536mS左右 
            org 0004h 
            movwf ww_temp      ;保护现场 
            swapf status,w 
            movwf status_temp 
             
            bcf intcon,gie     ;关所有中断 
            bcf t1con,tmr1on   ;停止TMR1 
            bcf pir1,tmr1if    ;清TMR1中断标志位 
            bcf enable         ;按键松开,清enable 
             
            swapf status_temp,w 
            movwf status 
            swapf ww_temp,f 
            swapf ww_temp,w 
             
            return                                  
;--------------------------------------------------     
;读出引导地址单元(00H)内容   
       
      main  movlw index        ;送引导地址中转 
            movwf ee_addr   
             
            call ee_data_rd    ;调用读EEPROM程序             
            movf ee_data,w     ;读出引导地址内容 
             
            movwf index_reg    ;保存引导地址内容 
            movwf ee_addr      ;送待读出内容地址 
             
            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位数据编码 
;-----+-----+------------------ 
; 36H | 37H | 设定的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,无接收到信号,返回 
            goto  remote0             
            bcf   go_next      ;没按键,清0 
            bcf   reset        ;没按键,清0 
            bcf   unlock 
                              
remote_end  return             ;没有按键,反回 
;-------------------------------------------------------- 
      
   remote0  btfss enable       ;rem为0,但enable为1,按键没放开,返回  
            goto  incept       ;接收12位编码 
             
;重新设定TMR1  
            bcf t1con,tmr1on   ;停止TMR1  
            clrf tmr1h         ;ffff为65.536mS 
            clrf tmr1l 
            bsf t1con,tmr1on   ;重启动TMR1    
             
            bcf reset          ;按键没松开,解码取消,清0 
            bcf go_next        ;按键没松开,解码取消,清0   
            bcf unlock 
             
            goto remote_end    ;按键没有放开,返回 
;清除上次解码内容 
;接收12位编码 

    incept  movlw .12 
            movwf count 
;解码 
;先找出接收到的开头,即16mS左右的高电平 
;设置高电平时间为15~17mS 

;检测和等待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内接收到的低电平 
            movlw .4   
            movwf r5 
   remote4  movlw .100 
            movwf r6  
                  
;15mS到17mS内接收到下降沿,则跳去解码,否则返回 
   remote5  btfss rem 
            goto remote6 
            decfsz r6,f 
            goto remote5 
            decfsz r5,f 
            goto remote4   

;超出17mS,接收错误,返回 
            bcf enable 
            goto remote_end 
                 
;等待1200uS后,采集接收信号 
   remote6  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 A0_addr2,f 
            rlf A0_addr1,f 
              
;等待第二个下降沿 
;加入了限时判断,防止死循环。 

;            btfss rem        ;rem为0,一直执行 
;            goto $-1 
            movlw .255 
            movwf r5 
            btfsc rem         ;rem为0,一直执行 
            goto $+4 
            decfsz r5,f 
            goto $-3 
            goto remote8      ;超时,跳到错误处理 
             
                  
;            btfsc rem         ;rem为1,一直执行  
;            goto $-1 
            movlw .255 
            movwf r5 
            btfss rem         ;rem为1,一直执行  
            goto $+4 
            decfsz r5,f 
            goto $-3 
            goto remote8      ;超时,跳到错误处理  
             
             
;等待1200uS后采集接收信号                               
            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 
  
;等待第二个码值的下降沿 
;加入了限时判断,防止死循环。 

;            btfss rem        ;rem为0,一直执行 
;            goto $-1 
            movlw .255 
            movwf r5 
            btfsc rem         ;rem为0,一直执行 
            goto $+4 
            decfsz r5,f 
            goto $-3 
            goto remote8      ;超时,跳到错误处理 
             
                  
;            btfsc rem         ;rem为1,一直执行  
;            goto $-1 
            movlw .255 
            movwf r5 
            btfss rem         ;rem为1,一直执行  
            goto $+4  
            decfsz r5,f 
            goto $-3 
            goto remote8      ;超时,跳到错误处理  
             
                  
            decfsz count,f 
            goto remote6      ;连续接收12位 
            goto decode       ;接收完12位编码,跳到解码  
;开始解码 
;把接收的编码左移4位,将8位密码放在同一字节上 
    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位数据编码由高4位移到低4位上 
            swapf A0_addr2,f 
            swapf A1_addr2,f   
                  
;比较密码                                          
            movf A0_addr1,w 
            xorwf addr_set1,w 
            skpz 
            goto remote8       ;跳到接收错误处理  
                  
            movf A1_addr1,w 
            xorwf addr_set2,w 
            skpz 
            goto remote8       ;跳到接收错误处理 
;接收正确处理                                    
;每次按键都一次响应 
;按键为PT2262IR pin10(D8) 和 pin13(D11) 
;以下只识别D8、D11,对数据理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按下同时还有其它按键按下 
            movf A1_addr2,w 
            andlw 0fh 
            xorwf A1_data1,w 
            skpz 
            goto D11           ;不是只有键值D8按下,检查键值D11 
                               ;即D8没有按下或D8按下同时还有其它按键按下 
;是键值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,返回时关显示 
            goto clr_rst 
            bsf unlock         ;on_off位为1,置unlock为1,返回时开显示 
            goto back 
  
;检查键值D11,NEXT键。   
       D11  btfss on_off       ;on_off为0,当前已关显示,按键NEXT无效 
            goto back          ;返回 
                     
            movf A0_addr2,w 
            andlw 0fh 
            xorwf A0_data2,w     
            skpz  
            goto back          ;也不是只有键值D11按下,返回 
                               ;即D11没有按下或D11按下同时还有其它按键按下 
            movf A1_addr2,w 
            andlw 0fh 
            xorwf A1_data2,w 
            skpz 
            goto back          ;也不是只有键值D11按下,返回 
                               ;即D11没有按下或D11按下同时还有其它按键按下 
             
;是键值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  ;启动TMR1 
            bsf enable        ;置1,防止开关按住不放,不断响应。 
                                   
  work_end  retfie            ;返回并开中断 
             
;接收错误处理                  
   remote8  bcf enable 
             
            bcf go_next       ;密码错误,取消解码,清0 
            bcf reset         ;密码错误,取消解码,清0 
            bcf unlock 
             
            bsf enable        ;虽接收错误,但都是有按键按下 
             
;重新设定TMR1  
            bcf t1con,tmr1on  ;停止TMR1        
            clrf tmr1h        ;ffff为65.536mS 
            clrf tmr1l 
            bsf t1con,tmr1on  ;重启动TMR1 
            retfie            ;返回并开中断             
                                                       
;------------------------------------------- 
;初始化程序 
      init  bsf status,rp0     ;选择bank1 
            call 3ffh 
            movwf osccal 
            movlw b’00001000’  ;GP0/1/2为输出 
            movwf trisio       ;GP3为输入  
            clrf ioc           ;关闭所有电平变化中断 
            bsf pie1,tmr1ie    ;开TMR1中断 
             
            bcf status,rp0     ;选择bank0  
            bcf intcon,gie     ;关所有中断 
            bsf intcon,peie    ;开外设中断  
            bcf t1con,tmr1on   ;停止TMR1 
             
            clrf gpio          ;输出清0 
            movlw 07h          
            movwf cmcon        ;设置GP0/1/2为IO 
             
            bcf enable         ;头次上电,初始化enable、reset、go_next 
            bcf reset 
            bcf go_next 
             
;编码地址设定为:A0~A7为悬空(A0=1,A1=0)  
            movlw b’11111111’  ;A0 
            movwf addr_set1 
            movlw b’00000000’  ;A1 
            movwf addr_set2 
             
;D8设置1(A0=0,A1=0),D9、D10悬空(A0=1,A1=0) 
;D11设置0(A0=1,A1=1),该状态为只有D8按下。D8为ON/OFF键。 
            movlw b’00001110’  ;A0                         
            movwf A0_data1 
            movlw b’00001000’  ;A1 
            movwf A1_data1 
             
;D11设置1(A0=0,A1=0),,D9、D10悬空(A0=1,A1=0) 
;D8设置0(A0=1,A1=1),该状态为只有D11按下。D11为NEXT键。 
            movlw b’00000111’  ;A0                         
            movwf A0_data2 
            movlw b’00000001’  ;A1             
            movwf A1_data2 
  
            return



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机中高阻态的实质及意义