0

我在继续我在这里尝试做的事情时遇到了一些麻烦。我设置了一个红外接收器来检查传入的信号,它确实如此。我用的是一个简单的遥控器,上面0-9,显然是10个数字。

到目前为止,这是我的代码,它可以获取传入的 IR 并注意到它。我想解码它是什么数字。我知道每个数字都有不同的信号,我可以通过高低点、0 和 1 找出正在按下的数字,但是我如何将其转换为数字并将其放在某个地方以显示在我拥有的 LCD 上。

这是代码:

        list p=16f690,r=dec     ; set processor type, default to base 10

#include    <p16f690.inc>           ; chip definitions
        errorlevel  -302        ; bank warnings on +302 off -302
        __CONFIG    (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF 
        & _MCLRE_OFF &    _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

#define     IR_PORT PORTA           ; IR receiver
#define     IR      2               ; IR receiver on RA2
#define     SWITCH  3               ; switch on RA3
#define     LED_0   0               ; LED on RC0
#define     LED_1   1               ; LED on RC1
#define     LED_2   2               ; LED on RC2
#define     LED_3   3               ; LED on RC3
#define     READY   0               ; READY bit

BANK_0      UDATA   0x20            ; bank_0
BANK_0      RES     1               ; variable used for bank switching
state       RES     1               ; state bits
bitcount    RES     1               ; number of bits seen so far
buffer      RES     20              ; the bits

SHARED      UDATA_SHR               ; shared across all banks
w_temp      RES     1               ; variable used for context saving 
status_temp RES     1               ; variable used for context saving
pclath_temp RES     1               ; variable used for context saving

RESET_VECTOR    CODE    0x000       ; processor reset vector location
    goto    main                ; go to beginning of program

INT_VECTOR      CODE    0x004       ; interrupt vector location
    goto    interrupt           ; go to the interrupt service routine

MAIN            CODE    0x005       ; address after vectors
interrupt:                          ; interrupt service routine
    movwf   w_temp              ; save off current W register contents
    movf    STATUS,w            ; move status register into W register
    movwf   status_temp         ; save off contents of STATUS register
    movf    PCLATH,w            ; move pclath register into W register
    movwf   pclath_temp         ; save off contents of PCLATH register
lowedge:                            ; let's check RA2
    btfss   INTCON,INTF         ; check for type of interrupt = RA2
    goto    timercheck          ; not RA2
    bcf     INTCON,INTF         ; ack the interrupt
    movf    TMR0,w              ; get the value
    movwf   INDF                ; store in buffer
    incf    FSR,f               ; bump the pointer
    incf    bitcount,f          ; count the bit
    movf    bitcount,w          ; pick up the count
    sublw   18                  ; got all the bits?
    btfss   STATUS,Z            ; check
    goto    goon                ; continue
    bsf     state,READY         ; it is
    bcf     INTCON,INTE         ; turn off RA2 interrupts for now
    bcf     INTCON,GIE
goon:                               ; go on
    movlw   200                 ; prepare
    movwf   TMR0                ; timeout
    bcf     INTCON,T0IF         ; clear the interrupt flag
    bsf     INTCON,T0IE         ; enable timer 0 interrupts
    goto    eoi                 ; we're done
timercheck:
    btfss   INTCON,T0IF         ; check for type of interrupt = TMR0
    goto    eoi                 ; is it an alien attack?
    bcf     INTCON,T0IF         ; ack the interrupt
    clrf    bitcount            ; clear the bitcount
    bcf     state,READY         ; clear just in case
    movlw   buffer              ; point at
    movwf   FSR                 ; start of buffer
    bcf     INTCON,T0IE         ; disable timer 0 interrupts
    BANKSEL BANK_0              ; bank 0
    comf    PORTC,f             ; flip the leds
    bcf     INTCON,T0IF         ; ack the interrupt
eoi:                                ; end of interrupt
    BANKSEL BANK_0              ; bank 0
    movf    pclath_temp,w       ; retrieve copy of PCLATH register
    movwf   PCLATH              ; restore pre-isr PCLATH register contents
    movf    status_temp,w       ; retrieve copy of STATUS register
    movwf   STATUS              ; restore pre-isr STATUS register contents
    swapf   w_temp,f            ; restore pre-isr W register contents
    swapf   w_temp,w            ; (swapf doesn't affect the flags)
    retfie                      ; return from interrupt

main:                               ; main code
    BANKSEL OSCCON              ; bank 1
    movlw   0x10                ; system clock = 125 kHz
    movwf   OSCCON              ; instruction clock = 7750 Hz, 32uS/instruction
    BANKSEL PORTA               ; bank 0
    clrf    PORTA               ; init PORTA
    BANKSEL ANSEL               ; bank 2
    clrf    ANSEL               ; digital I/O
    clrf    ANSELH              ; digital I/O
    BANKSEL TRISA               ; bank 1
    movlw   0xff                ; init PORTA
    movwf   TRISA               ; as inputs
    BANKSEL PORTC               ; bank 0
    clrf    PORTC               ; init PORTC as outputs
    BANKSEL TRISC               ; bank 1
    movlw   0xf0                ; set RC<7:4> as inputs
    movwf   TRISC               ; set RC<3:0> as outputs
    BANKSEL PORTC               ; bank 0
    movlw   0x09                ; init the
    movwf   PORTC               ;   leds
    clrwdt                      ; clear WDT and prescaler
    BANKSEL OPTION_REG          ; bank 1
    movlw   b'11110000'         ; mask TMR0 select and
    andwf   OPTION_REG,W        ;   prescaler bits
    iorlw   b'00000010'         ; set prescale to
    movwf   OPTION_REG          ;   1:n
    bcf     OPTION_REG,T0CS     ; make it a timer
    bcf     OPTION_REG,INTEDG   ; select the falling edge of RA2
    BANKSEL TMR0                ; bank 0
    clrf    TMR0                ; clear the count
    BANKSEL INTCON              ; bank 0
    bcf     INTCON,T0IF         ; clear pending timer 0 interrupts
    bcf     INTCON,T0IE         ; disallow timer 0 interrupts for now
    bsf     INTCON,INTE         ; enable RA2 interrupts
    BANKSEL BANK_0              ; bank 0
    bcf     state,READY         ; clear the ready bit
    clrf    bitcount            ; we have seen no bits
    movlw   buffer              ; point at
    movwf   FSR                 ; start of buffer
    bsf     INTCON,GIE          ; enable global interrupts
    BANKSEL BANK_0              ; bank 0
forever:                            ; stay here forever
    btfss   state,READY         ; check for IR Code ready
    goto    forever             ; go check again
dobits:                             ; process ir code
    BANKSEL BANK_0              ; bank 0

    bcf     state,READY         ; clear the ready bit
    clrf    bitcount            ; we have seen no bits
    movlw   buffer              ; point at
    movwf   FSR                 ; start of buffer
    bsf     INTCON,INTE         ; enable RA2 interrupts
    bsf     INTCON,GIE          ; enable global interrupts
    goto    forever             ; keep doing it

EE              CODE    0x2100  ;   eeprom
    DE      'J', 'A', 'S', 'O', 'N', 0

    END
4

1 回答 1

0

正如现在所写的那样,中断处理程序仅在从高到低转换时被调用。这仅测量输入的频率。如您所说,如果将 1 和 0 编码为特定长度的高状态和低状态,则您需要在更改时中断(在下降和上升转换时)。使用计时器测量下一次更改的持续时间。通过将持续时间除以位长度来确定该状态的位数。

于 2014-12-09T00:21:55.540 回答