📄 ir_decode.s43
字号:
#include <msp430x11x1.h>
;-------------------------------------------------------------------------------
; Name: ir_decode.s43
; Func: Receive and decode infra red signal
; Ver.: 1.1
; Date: June-2005
; Auth: Thomas Kot
; MSP430
; Texas Instruments Inc.
; Rem.: Build with IAR EW V4.3A
;-------------------------------------------------------------------------------
; Exported Symbols
;-------------------------------------------------------------------------------
PUBLIC IR_SEQ
PUBLIC CHECK_IR
PUBLIC IR_BRANCH
PUBLIC IR_FLAG
PUBLIC BIT_CNT
PUBLIC DATA_IN
;-------------------------------------------------------------------------------
; Imported Symbols
;-------------------------------------------------------------------------------
EXTERN IR_STORED
EXTERN ERROR_IR
EXTERN RAM
EXTERN SDA
;-------------------------------------------------------------------------------
; Define Constant
;-------------------------------------------------------------------------------
SYN_ON_ EQU 045CH ; 9mS, 15.5T, NEC SYN PULSE
SYN_OFF_ EQU 0240H ; 4.642mS, 8T, NEC SYN OFF TIME
SYN_SUB EQU 0120H ; 4T, SUBSEQUENT FRAME
DAT0 EQU 0048H ; 0.58ms, 1T, 8/8/8MHz, SMCLK = 1MHz
DAT1 EQU 0048H ; 1T
DAT0_OFF EQU 0048H ; 1T
DAT1_OFF EQU 00D8H ; 3T
TOL EQU 0033H ; 0.3ms TOLERANCE
SYN_ON_L EQU SYN_ON_ - 3*TOL
SYN_ON_H EQU SYN_ON_ + TOL
SYN_OFF_L EQU SYN_OFF_ - TOL
SYN_OFF_H EQU SYN_OFF_ + TOL
SYN_SUB_L EQU SYN_SUB - TOL
SYN_SUB_H EQU SYN_SUB + TOL
DAT0_L EQU DAT0 - TOL
DAT0_H EQU DAT0 + TOL
DAT1_L EQU DAT1 - TOL
DAT1_H EQU DAT1 + TOL
DAT0_OFF_L EQU DAT0_OFF - TOL
DAT0_OFF_H EQU DAT0_OFF + TOL
DAT1_OFF_L EQU DAT1_OFF - TOL
DAT1_OFF_H EQU DAT1_OFF + TOL
;-------------------------------------------------------------------------------
; Define RAM
;-------------------------------------------------------------------------------
RSEG DATA16_N
;-------------------------------------------------------------------------------
IR_FLAG DS 1
BIT_CNT DS 1
;-------------------------------------------------------------------------------
RSEG DATA16_N
;-------------------------------------------------------------------------------
EVEN
IR_BRANCH DW 1
DATA_IN DW 1
;-------------------------------------------------------------------------------
; Implementation
;-------------------------------------------------------------------------------
RSEG CODE
;-------------------------------------------------------------------------------
CHECK_IR
mov IR_BRANCH,R12 ; IR_BRANCH record the branching
incd R12 ; address. As this routine is mixed
mov R12, IR_BRANCH ; with "C" code, it cannot directly
br @R12 ; use R12. R4 and R5 are used in I2C
; routine
IR_SEQ DW STA_TIMER ; Capture on falling edge
DW SYN_ON ; Rising edge
DW SYN_OFF ; Falling edge
DW DATA_TIME ; rise/fall/rise/fall....
;-------------------------------------------------------------------------------
DATA_TIME ; This Routine is to sort out if the captured timing data is for
; on or off time of IR signal. And jump to the corresponding ISR
;-------------------------------------------------------------------------------
decd IR_BRANCH ; Next, will point to the same addr
inc.b BIT_CNT ; Increase bit counter
bit.b #01H,BIT_CNT ; Check for even or Odd
jnc DAT_OFF ; If even, jump to DAT_OFF
jmp DAT_ON ; If odd, jump to DAT_ON
;-------------------------------------------------------------------------------
STA_TIMER ; This ISR start the timer to measure the Sync pulse
;-------------------------------------------------------------------------------
bis #0020H,&TACTL ; Start continuous mode
bis #4000H,&TACCTL1 ; Set CMx to 01
bic #8000H,&TACCTL1 ; capture on rising edge
bis.b #01H,IR_FLAG ; To indicate IR processing
bic.b #SDA,&P2IE ; Disable SDA INT, to disable I2C
reti
;-------------------------------------------------------------------------------
SYN_ON ; This routine check if the Sync pulse is within the valid range
;-------------------------------------------------------------------------------
bis #0004H,&TACTL ; Restart Timer
cmp #SYN_ON_L,&TACCR1 ; Check if Sync pulse < lower bound
jl ERROR_IR ; If so, jump to ERROR_IR
cmp #SYN_ON_H,&TACCR1 ; Check if Sync Pulse > upper bound
jge ERROR_IR ; If so, jump to ERROR_IR
bis #8000H,&TACCTL1 ; Set CMx to 10. Change to Capture
bic #4000H,&TACCTL1 ; on falling edge.
reti
;-------------------------------------------------------------------------------
SYN_OFF ; This routine check if the Sync off is within the valid range
;-------------------------------------------------------------------------------
bis #0004H,&TACTL ; Restart Timer
cmp #SYN_OFF_L,&TACCR1 ; Check if Sync Off < lower bound
jl ERROR_IR ; If so, jump to ERROR_IR
cmp #SYN_OFF_H,&TACCR1 ; Check if Sync off > upper bound
jge ERROR_IR ; If so, jump to ERROR_IR
bis #4000H,&TACCTL1 ; Set CMx to 01. Change to Capture
bic #8000H,&TACCTL1 ; on rising edge.
reti
;-------------------------------------------------------------------------------
DAT_OFF ; This routine find out that the data bit received is "0" or "1"
;-------------------------------------------------------------------------------
bis #0004H,&TACTL ; Restart Timer
cmp #DAT0_OFF_H,&TACCR1 ; Check the bit > upper bound of "0"
jge CHECK_1 ; If yes, go to check if it is "1"
CHECK_0 cmp #DAT0_OFF_L,&TACCR1 ; Check the bit < lower bound of "0"
jl ERROR_IR ; If so, jump to ERROR_IR
clrc ; if not, clear the carry register
rrc DATA_IN ; Shift in "0"
jmp CHK_DAT_OK ; Jump to CHK_DAT_OK
CHECK_1 cmp #DAT1_OFF_H,&TACCR1 ; Check the bit > upper bound of "1"
jge ERROR_IR ; If so, jump to ERROR_IR
cmp #DAT1_OFF_L,&TACCR1 ; Check the bit < lower bound of "1"
jl ERROR_IR ; If so, jump to ERROR_IR
setc ; If not, set the carry register
rrc DATA_IN ; Shift in "1"
;-------------------------------------------------------------------------------
CHK_DAT_OK ; This routine count the number of bit received and branch to
; other routine for further processing.
;-------------------------------------------------------------------------------
bis #4000H,&TACCTL1 ; Set CMx to 01. Change to Capture
bic #8000H,&TACCTL1 ; on rising edge.
cmp.b #32, BIT_CNT ; Check if 32 data bit has received
jz T_USR_CODE ; If yes, jump to T_USR_CODE
cmp.b #64, BIT_CNT ; Check if 64 data bit has received
jnz NEXT_BIT ; If not, jump and wait for next bit
;-------------------------------------------------------------------------------
GET_DATA ; If 64 bits have been received,
; a valid data is said to be received if the data and its complement
; received.
;-------------------------------------------------------------------------------
xor.b #0FFH,&DATA_IN ; Turn a data byte to its complement
cmp.b &DATA_IN,&DATA_IN + 1 ; Is it the same as received one?
jnz ERROR_IR ; If not, Error, jump to ERROR_IR
xor.b #0FFH,&DATA_IN ; If yes, turn it back.
mov.b &DATA_IN,&RAM + 1 ; Store into the RAM buffer
mov.b &DATA_IN + 1,&RAM + 2 ;
bis.b #02H,&P1OUT ; Set P1.1, indicating data ready.
jmp IR_STORED ; Jump to IR_STORED
;-------------------------------------------------------------------------------
T_USR_CODE ; If 32 bits have been received, Customer code is supposed to be
; received. Check if it is a correct customer code.
; In this firmware, two different remote controls using
; the same timing format is introduced.
; User can change it to its own customer code.
;-------------------------------------------------------------------------------
cmp #0EF10H,DATA_IN ; Check if it is STAR
jz STAR ; If yes, go on for its data
cmp #0FF00H,DATA_IN ; Check if it is SHN
jz SHN ; If yes, go on for its data
jnz ERROR_IR ; If not, jump to ERROR_IR
STAR
SHN
NEXT_BIT reti
;-------------------------------------------------------------------------------
DAT_ON ; This routine check the valid IR timing for data bit when IR signal
; is received.
;-------------------------------------------------------------------------------
bis #0004H,&TACTL ; Restart Timer
cmp #DAT0_L,&TACCR1 ; Check if timing < lower bound
jl ERROR_IR ; If yes, jump to ERROR_IR
cmp #DAT0_H,&TACCR1 ; Check if timing > upper bound
jge ERROR_IR ; If yes, jump to ERROR_IR
bis #8000H,&TACCTL1 ; Set CMx to 10. Change to Capture
bic #4000H,&TACCTL1 ; on falling edge
reti
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -