www.pudn.com > st-asm.rar > st-rmt.asm


;红外线遥控读码机,用本实例配合本站套件可读出任何6121或6122(CD6121/CD6122/SC6121/SC6122)及其兼容芯片的红外线遥控器的用户码、键码。 
;本例是一个红外线遥控接收解码程序,程序中数码管显示用的是定时器中断法的动态扫描 
;动态显示二位数码管的方法,中断法,我们以3MS中断一次从而交换两位数码管轮流点亮。 
;对准实验板红外线接收头轻按要测定的遥控器的待测按键一次,此时实验板的两位数码管将显示该键的键码, 
;(显示为16进制的),轻触实验板的S2此时显示器切换为显示当前遥控器用户码的低8位, 再次轻触实验板的S2此时显示器切换为显示当前遥控器用户码的高8位, 
;再一次轻触实验板的S2此时显示又回到显示当前键的键码,用按键S2可反复循环显示用户码低8位、高8位、键码。 
;注意:所有的显示均为16进制,'A'显示为'A','B'显示为'b','C'显示为'c','D'显示为'd','E'显示为'E','F'显示为'F'. 
;注意6121的遥控器发射码依次为:同步头(引导码)+32位数据码(用户码低8位+用户码高8位+键码+键码的反码) 
;引导码是由9MS的高电平加4.5MS的低电平构成,我们接收到的刚好反相为9MS的低电平加4.5MS的高电平. 
;数据码'0'是由560US的高电平加560US的低电平构成,接收时反相为560US的低电平加560US的高电平构成. 
;数据码'1'是由560US的高电平加1.69MS的高电平构成,接收时反相为560US的低电平加1.69MS的高电平构成. 
;PIC单片机学习网    陈学乾   http://www.pic16.com 
;程序文件名:“ST-RMT.ASM" 
;烧写时应注意:配置位已经在程序中写明,加载HEX文件时会自动加载,烧写时不用再手动设置配置位。 
;实验时请注意套件跳线选择; 
;******************************************************************* 
 LIST P=16F84A,R=DEC  ;定义器件为16F84,默认数制为十进制 
;------------------------------------------------------- 
  __CONFIG B'11111111110001';_CP_OFF&_WDT_OFF&_PWRITE_ON&_XT_OSC  
                                              ;没有代码保护 
                                              ;看门狗关闭 
                                              ;上电廷时器开启 
                                              ;振荡器模式为XT 
;------------------------------------------------------------- 
RTCC   EQU 01H           ;定义定时器0地址 
PC     EQU 02H           ;定义程序计数器低字节寄存器地址 
STATUS EQU 03H           ;定义状态寄存器地址 
PORTA  EQU 05H           ;定义RA口数据寄存器地址 
PORTB  EQU 06H           ;定义RB口数据寄存器地址 
INTCON EQU 0BH           ;定义中断控制寄存器 
 
OPTION_REG  EQU 81H      ; 
TRISA       EQU 85H      ;定义RA口方向控制寄存器 
TRISB       EQU 86H      ;定义RB口方向控制寄存器 
;-----------------------STATUS 
C           EQU 0        ;定义进位标志位位地址 
Z           EQU 2         ;定义0标志位位地址 
RP0         EQU 5          ;寄存器体选 
;-------------------------INTCON 
T0IF        EQU 2          ;定时器0溢出中断标志位 
T0IE        EQU 5          ;定时器0溢出中断允许/禁止 
GIE         EQU 7          ;总中断允许/禁止 
;------------------------- 
RMT         EQU 4          ;遥控接收输入脚位地址(RA。4) 
;------------------------- 
BITIN       EQU 7           ;遥控接收数据位位标志 
;------------------------- 
CNT0         EQU 20H          ;用户临时寄存器1 
CNT1         EQU 21H          ;用户临时寄存器2 
CNT2         EQU 22H          ;用户临时寄存器3 
CNT3         EQU 23H          ;用户临时寄存器4 
TABADD       EQU 24H          ;数码管显示码取码用寄存器 
FLAGS        EQU 25H         ;显示位选标志位 
DISPBUF_H    EQU 26H         ;显示器高位 
DISPBUF_L    EQU 27H         ;显示器低位 
W_TEMP       EQU 2BH         ;W现场保护寄存器 
STATUS_TEMP  EQU 2CH         ;STATUS现场保护寄存器 
CSR0         EQU 2DH         ;遥控键码反码寄存器 
CSR1         EQU 2EH        ;遥控器键码寄存器 
CSR2         EQU 2FH        ;遥控器用户码高8位寄存器 
CSR3         EQU 30H        ;遥控器用户码低8位寄存器 
FLAGS2       EQU 31H        ;临时寄存器 
CSR0A        EQU 32H        ;遥控接收32位数据暂存寄存器 
CSR1A        EQU 33H        ;遥控接收32位数据暂存寄存器 
CSR2A        EQU 34H        ;遥控接收32位数据暂存寄存器 
CSR3A        EQU 35H        ;遥控接收32位数据暂存寄存器 
COUNTER      EQU 36H        ;按键计数寄存器 
;-------------------- 
               ORG 0000H 
               GOTO MAIN 
               ORG  0004H 
               GOTO TMR0SERV    ;定时器中断,扫描数码管 
               ORG  0008H 
;------------------------------------------------- 
CONVERT    
            MOVWF    	PC             	   ;将W寄存器内的7段显示码地址放入PC  
TABLE                                       ;PC执行新地址指令, 跳到相对的地址执行?              	 
	  RETLW       081H   		;0  ;RETLW指令,将七段显示码存入W后返回 
	  RETLW       0E7H  		;1                                 
	  RETLW       092H  		;2 
	  RETLW       0A2H  		;3 
	  RETLW       0E4H  		;4 
	  RETLW       0A8H  		;5 
	  RETLW       088H   		;6 
	  RETLW       0E3H   	        ;7 
	  RETLW       080H  		;8 
	  RETLW       0A0H  		;9 
          RETLW       0C0H            ;A 
          RETLW       08CH            ;b 
          RETLW       09EH            ;c  
          RETLW       086H            ;d 
          RETLW       098H            ;E 
          RETLW       0D8H            ;F 
;----- ----------------------------------------------- 
TMR0SERV 
                MOVWF      W_TEMP            ;现场保护 
                SWAPF      STATUS,W          ;用SWAPF才不会影响标志位 
                MOVWF      STATUS_TEMP       ;将W和STATUS存入各保护寄存器 
 
                MOVLW      0FFH 
                MOVWF      PORTB             ;先熄灭所有数码管以免闪烁 
                BSF        PORTA,1 
                BSF        PORTA,2 
 
   
                MOVLW      TABLE 
                MOVWF      TABADD           ;将转换表的首地址存入TABADD   
                MOVFW      DISPBUF_L        ;计数值(W)与转换表的起始地址相加 
                BTFSS      FLAGS,1 
                MOVFW      DISPBUF_H 
                ADDWF      TABADD,W 
                CALL       CONVERT          ;存入W后调用转换表子程序 
                MOVWF      PORTB            ;送RB口显示 
 
                BTFSS      FLAGS,1          ;根据标志位选择是点亮那一个数码管 
                BCF        PORTA,1 
                BTFSC      FLAGS,1 
                BCF        PORTA,2 
                COMF       FLAGS,1 
 
                MOVLW      155         ;送定时器初值 
                MOVWF      RTCC 
 
                BCF        INTCON,T0IF      ;清定时器0溢出中断标志位 
                SWAPF      STATUS_TEMP,W    ;恢复中断前STATUS,W的值 
                MOVWF      STATUS 
                SWAPF      W_TEMP,F 
                SWAPF      W_TEMP,W         ;(用SWAPF才不会影响STATUS的值) 
                RETFIE 
;------------------------------------------------ 
MAIN 
               CLRF        PORTA 
               CLRF        PORTB   ;初始化IO口 
      
               BSF         STATUS,RP0 ;设置寄存器体1 
               MOVLW       0F8H       ;将RMT设置为输入,S2输入其它IO口设置为输出 
               MOVWF       TRISA  
               MOVLW       00H       ; 
               MOVWF       TRISB   
               MOVLW       84H 
               MOVWF       OPTION_REG  ;预分频器分配给定时器0,分频比1:32; 
               BCF         STATUS,RP0  ;恢复寄存器体0 
    
               MOVLW       155 
               MOVWF       RTCC       ;定时器送初值(255-155)*32US=3.2MS,每3.2MS一次中断  
               MOVLW       0FFH       ;先让数码管全部不显示 
               MOVWF       PORTB 
               CLRF        DISPBUF_L  ;数码管先显示00 
               CLRF        DISPBUF_H 
               CLRF        COUNTER     ;按键计数送初值 
               BCF         INTCON,T0IF 
               BSF         INTCON,T0IE ;定时器0溢出中断允许 
               BSF         INTCON,GIE  ;总中断允许 
;-------------------------------------------------- 
LOOP	  	    
               BTFSS       PORTA,3     ;是否按下S9 
               GOTO        KEY          ;跳转键处理 
               BTFSS       PORTA,RMT    ;是否有遥控器按下 
               GOTO        RCV          ;跳转遥控接收程序 
               GOTO        LOOP         ;反复检测 
;-------------------------------------------------- 
KEY                                
               
               CLRF        CNT0          ;消除键抖动 
               MOVLW       100 
               MOVWF       CNT1  
KEY_A 
               BTFSC       PORTA,3       
               INCF        CNT0,1 
               BTFSS       PORTA,3 
               CLRF        CNT0 
               BTFSC       CNT0,3 
               GOTO        LOOP 
               DECFSZ      CNT1,1 
               GOTO        KEY_A 
               INCF        COUNTER,1     ;按键计数加一 
               MOVFW       COUNTER 
               MOVWF       CNT1 
               DECFSZ      CNT1,1        ;是否是第一次按下按键 
               GOTO        KEY_B         ;不是则转 
               SWAPF       CSR3,W        ;用户码低8位 高低位交换,先处理高位 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_H     ;存入寄存器 
               MOVFW       CSR3          ;用户码低8位 低位处理 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_L     ;存入寄存器  
               GOTO        KEY_END 
KEY_B 
               DECFSZ      CNT1,1        ;第二次按下按键否 
               GOTO        KEY_C         ;不是第二次按下按键则是第三次转相应程序 
               SWAPF       CSR2,W        ;显示值高低位交换,先处理高位 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_H     ;存入寄存器 
               MOVFW       CSR2          ;显示值低位处理 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_L     ;存入寄存器  
               GOTO        KEY_END 
KEY_C 
               CLRF        COUNTER       ;该次循环结束,按键计数送初值 
               SWAPF       CSR1,W        ;键码值高低位交换,先处理高位 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_H     ;存入寄存器 
               MOVFW       CSR1          ;键码值低位处理 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_L     ;存入寄存器 
KEY_END  
               BTFSS       PORTA,3       ;等待键释放 
               GOTO        $-1       
               GOTO       LOOP 
;-------------------------------------------------- 
RCV 
               BTFSC       PORTA,RMT 
               GOTO        LOOP        ;是干扰退出 
               MOVLW        4 
               MOVWF       CNT1       ;4*256*10us 
               CLRF        CNT2 
               CLRF        CNT0 
RCV1                                     ;先检测引导码的9MS低电平 
               GOTO        $+1           ;每一个循环10US  
               NOP 
               BTFSC       PORTA,RMT 
               INCF        CNT2,1 
               BTFSS       PORTA,RMT 
               CLRF        CNT2 
               BTFSC       CNT2,3         ;高电平大于8*10US=80US则为有效高电平,否则是一些干扰信号 
               GOTO        RCV2 
               DECFSZ      CNT0,1 
               GOTO        RCV1 
               DECFSZ      CNT1,1 
               GOTO        RCV1 
               GOTO        LOOP           ;低电平大于4*256*10US=10.24MS则是错误脉冲 
RCV2 
               MOVLW        3              
               SUBWF       CNT1,0         ;低电平小于2*256*10US=5.12MS则是错误脉冲 
               SKPNC 
               GOTO        LOOP 
               MOVLW       3 
               MOVWF       CNT1           ;3*256*10us 
               CLRF        CNT2 
               CLRF        CNT0 
RCV3 
               GOTO        $+1             ;每一个循环10US 
               NOP 
               BTFSS       PORTA,RMT 
               INCF        CNT2,1 
               BTFSC       PORTA,RMT 
               CLRF        CNT2 
               BTFSC       CNT2,3         ; 低电平大于8*10US=80US则为有效低电平,否则是一些干扰信号 
               GOTO        RCV4 
               DECFSZ      CNT0,1          
               GOTO        RCV3 
               DECFSZ      CNT1,1 
               GOTO        RCV3 
               GOTO        LOOP           ;高电平大于3*256*10US=7.68MS则是错误的 
RCV4 
               MOVLW       3 
               SUBWF       CNT1,0         ;高电平小于1*256*10US=2.56MS则是错误的 
               SKPNC 
               GOTO        LOOP 
                
               MOVLW       32 
               MOVWF      CNT2            ;接收数据共32位,16位用户码,8位控制码加8位控制码的反码 
RCV5 
               CLRF       CNT3  
               MOVLW      170           ;低电平大于256-170=86*10US=860US错误 
               MOVWF      CNT0   
               MOVLW      56 
               MOVWF      CNT1            ;高电平大于256-56=200*10US=2MS错误 
RCV5_HI             
               GOTO       $+1 
               NOP 
               BTFSC      PORTA,RMT 
               INCF       CNT3,1 
               BTFSS      PORTA,RMT 
               CLRF       CNT3 
               BTFSC      CNT3,2        ;高电平大于8*10US=80US则为有效高电平 
               GOTO       RCV6 
               INCFSZ     CNT0,1 
               GOTO       RCV5_HI       ;低电平大于860US则是错误的 
               GOTO       LOOP 
RCV6 
               CLRF       CNT3 
RCV6_LO               
               GOTO       $+1 
               NOP 
               BTFSS      PORTA,RMT 
               INCF       CNT3,1 
               BTFSC      PORTA,RMT 
               CLRF       CNT3 
               BTFSC      CNT3,3      ;低电平大于10*8US=80US则是有效低电平 
               GOTO       COMPARE  
               INCFSZ     CNT1,1       
               GOTO       RCV6_LO     ;高电平大于256-56=200*10US=2MS错误 
               GOTO       LOOP 
COMPARE         
               MOVLW        170 
               SUBWF        CNT0,1     ;CNT0的值减初始值等于实际低电平计数值 
               MOVLW        56 
               SUBWF        CNT1,1     ;CNT1的值减初始值等于实际高电平计数值 
               MOVFW        CNT1 
               ADDWF        CNT0,1     ;将高低电平的计数加在一起并存入CNT0,通过比较高低电平总的时间来确定是1还是0 
               SKPNC 
               GOTO         LOOP       ;总的值大于255(即时间大于255*10US=2.55MS)则错误 
               MOVLW        70 
               SUBWF        CNT0,0 
               SKPC 
               GOTO         LOOP        ;总的时间小于70*10US=700US则是错误的 
               MOVLW        130         ;130*10=1.3MS 
               SUBWF        CNT0,0 
               SKPNC 
               GOTO         COMPARE_H     ;时间大于1.3MS转去确定是否1 
               BCF          FLAGS2,BITIN  ;时间在700US-1.3MS之间则是0 
               GOTO         MOVDATA       ;送数 
COMPARE_H 
               MOVLW        160 
               SUBWF        CNT0,0 
               SKPC 
               GOTO         LOOP            ;小于160*10US=1.6MS,则错误 
               MOVLW        230 
               SUBWF        CNT0,0 
               SKPNC  
               GOTO         LOOP            ;大于230*10US=2.3MS,则错误  
               BSF          FLAGS2,BITIN    ;时间在1.6MS-2.3MS之间则是1             
MOVDATA 
               RRF         CSR0A,1           ;将每一位移入相应寄存器 
               RRF         CSR1A,1 
               RRF         CSR2A,1 
               RRF         CSR3A,1 
               BCF         CSR0A,7 
               BTFSC       FLAGS2,BITIN     ;接收当前位送入CSR0.7 
               BSF         CSR0A,7 
               DECFSZ      CNT2,1           ;是否接收完32位 
               GOTO        RCV5 
                
 
               MOVFW       CSR0A            ;将临时寄存器中的数存回相应寄存器 
               MOVWF       CSR0 
               MOVFW       CSR1A 
               MOVWF       CSR1 
               MOVFW       CSR2A 
               MOVWF       CSR2 
               MOVFW       CSR3A 
               MOVWF       CSR3 
     
               COMF        CSR0,0           ;比较键码的反码取反后是否等于键码 
               XORWF       CSR1,0 
               BNZ         LOOP             ;不等于则接收到的是错误的信息 
                                            ;将键码送显示 
               SWAPF       CSR1,W        ;显示值高低位交换,先处理高位 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_H     ;存入寄存器 
               MOVFW       CSR1          ;显示值低位处理 
               ANDLW       0FH           ;屏蔽掉高位 
               MOVWF       DISPBUF_L     ;存入寄存器        
               GOTO       LOOP 
;------------------------------------------------------ 
     END 
;***********************************************************