tohbas
Junior Member level 3

16f684 raif raie
i use 16F684 to be RF remote decoder
normally, there are a lot of noise from out out of RF decoder module
i need to detect 28 bits code with 250-300 uSec pulse width
after i detected i need to send forward to another
i use this 684 like a pulse fillter...
my problem,
1. 16F684 can not dectect signal in first times i need to press remote two or tree times
2. i if i dont use "goto 0x0000" my 16F684 always "hank"
3. for " goto test " i think it should send pulse out forever but it isnt !!
it send out just one time and send only if there are an on change interrupt
why ???
and the last is ... i set its oscillator to be 8 Mhz its mean for 1 istruction it need
1/(8MHz /4) = 0.5 uSec but i try it to do
bsf PORTC,2
bcf PORTC,2
bsf PORTC,2
bcf PORTC,2
i got a pulse with pulse width 0.16uSec... what wrong? i try 3 CPU but the same results
list p=16F684
#include <p16F684.inc>
__CONFIG 0x34c4
FSR_temp equ 0xa0
counter equ 0xba
ii equ 0xbb
bit_bufferP equ 0xbc
bit_buffer equ 0xbd
timeH equ 0xbe
timeL equ 0xbf
status_temp equ 0x7e
w_temp equ 0x7f
bank0 macro
movlw 0x1f
andwf STATUS,F
endm
bank1 macro
bcf STATUS,IRP
bcf STATUS,RP1
bsf STATUS,RP0
endm
org 0x0000
clrf INTCON
clrf PCLATH ; ensure page bits are cleared
goto start
org 0x0004
goto interrupts_vector
start
;==============================================================
;== subrutine of initial all port and somefunction ===========
;==============================================================
;initial 16F684
banksel ANSEL
clrf ANSEL ; all analog pins are digital
banksel CMCON0
movlw 0x07
movwf CMCON0 ; off comparator
banksel WPUA
clrf WPUA ;disable pull up
banksel OPTION_REG
bcf OPTION_REG,7 ; disable pull up on PORTA
banksel TRISA
movlw b'00111111' ; RA5 as input RA0 i/p of comparator
movwf TRISA
;setup_interrupt_on_change on PORTA check TRISA on setup PORT
bsf INTCON,RAIE ;interrupt on change
banksel IOCA
movlw 0x01
movwf IOCA ; enable RA5 interrupt on change
;setup port C
banksel TRISC ; analog i/p RA2 =C2OUT RC0 = C2IN+ , RC4 =C1OUT RA0 = C1IN+
movlw b'00000000' ;RC5 is an input to disable decoder
movwf TRISC
banksel PORTC
movlw 0xff
movwf PORTC
;setup_timer1
banksel CMCON1 ; config T1G as comparator o/p
clrf CMCON1
banksel T1CON
movlw 0x04
movwf T1CON ;1:1 prescale
banksel PIE1
bcf PIE1,TMR1IE
;setup internal oscillator
banksel OSCTUNE
movlw 0x0F
movwf OSCTUNE
banksel OSCCON
movlw 0x75
movwf OSCCON ; use clock 8 Mhz
bsf INTCON,7
bsf INTCON,6
goto main
;//////////////////////////////////////////////////////////////
main
movlw 0x27
movwf FSR ; set address
banksel counter
clrf counter
banksel T1CON
bsf T1CON,TMR1ON
wait_signal
movf FSR,F
skpz
goto wait_signal
;===========================================================
;=========== now time to send data forward===================
;============================================================
test
;///////////////////////////////////////////////////////////
bcf INTCON,RAIE ;disable interrupt on change
bcf INTCON,GIE ;disable all interrupts
bcf INTCON,PEIE
banksel T1CON
bcf T1CON,TMR1ON ;stop timer1
;/////////////////////////////////////////////////////////
banksel TMR1H
clrf TMR1H
clrf TMR1L
call delay
;======================================================
; ======= time to send out data =======================
;========================================================
send_data
movlw 0x27
movwf FSR ; data
send_out
movf INDF,W
banksel PORTC
movwf PORTC
incf FSR,F ; index timeL
call check_RAM_address
movf INDF,W
sublw 0xff ; 0xff - W => W
banksel TMR1L
movwf TMR1L
incf FSR,F ;index timeH address
call check_RAM_address
movf INDF,W
sublw 0xff ; 0xff - W => W
banksel TMR1H
movwf TMR1H
call delay
incf FSR,F ; index next data
call check_RAM_address
decf counter,F
skpz
goto send_out
{ !!!! goto test !!!}
goto 0x0000
;===========================================================
;============================================================
;=====================delay =================================
;======= TMR1H and TMR1L need to be setted before call ====
;======= this subroutine =======================
;============================================================
delay
banksel PIE1
bsf PIE1,TMR1IE ; enable timer1 interrupt
bsf INTCON,PEIE
bsf INTCON,GIE
banksel T1CON
bsf T1CON,TMR1ON ;start timer1
banksel ii
movlw 0xff
movwf ii
wait_delay ;wait timer1 INT
banksel ii ; untilll ii == 0x00 clrf by timer1_INT
movf ii,F
skpz
goto wait_delay ; wait timer1 INT
banksel T1CON
bcf T1CON,TMR1ON ;stop timer1
banksel PIE1
bcf PIE1,TMR1IE ; disable timer1 interrupt
bcf INTCON,GIE
bcf INTCON,PEIE
return
;============================================================
;===================== end delay =================================
;============================================================
;====================================================================
;========== interrupts routine service detector ===================
;========== dectect the cause of interrupt ==============
;==================================================================
interrupts_vector
movwf w_temp
swapf STATUS,W
clrf STATUS
movwf status_temp ; keep data on status reg.
btfsc INTCON,RAIF ;interrupts is the most importante
call RA_INT
banksel PIR1
btfsc PIR1,TMR1IF ;interrupts is the most importante
call TMR1_INT
bcf STATUS,Z ; for skpz in main loop
swapf status_temp,W
movwf STATUS ; return data on w registor
swapf w_temp,F
swapf w_temp,W
bsf INTCON,PEIE
retfie
;/////////////////////////////////////////////////////////////
TMR1_INT
banksel PIR1
bcf PIR1,TMR1IF
banksel ii
clrf ii
return
;==================================================================
; =====interrupt on change of port RA5 is used to be input========
;==================================================================
RA_INT
banksel PORTA
movf PORTA,F ; cancle mismath condition
bcf INTCON,RAIF ; clear interrupt flag caused by RA5
;keep previous status of RA5
banksel bit_bufferP
movf bit_bufferP,W
banksel bit_buffer
movwf bit_buffer
banksel PORTA
movf PORTA,W ; cancle mismath condition
banksel bit_bufferP
movwf bit_bufferP
comf bit_bufferP,F ; inversion
;read timer
banksel TMR1H
movf TMR1H,W
banksel timeH
movwf timeH
banksel TMR1L
movf TMR1L,W
banksel timeL
movwf timeL
;clear timer
banksel TMR1H
clrf TMR1H
clrf TMR1L
;check time lower than limited
movlw 0x05 ; 0x04 163.84 uS 0x05 = 254 uSec
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto noise ; time less than 163.84 uS it is noise
;check time higher than limited
; timeH_more_than_163uS
movlw 0x09 ; 0x1500 = 900uS 0x0fff = 3840 * 0.16 = 614 uS
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto keep_bit1 ; time more than or equal 600 uS
;check time lower than limited
movlw 0x0b ; 0x04 163.84 uS 0x05 = 254 uSec
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto noise ; time less than limited
timeH_more_than_163uS
movlw 0x12 ; 0x1500 = 900uS 0x0fff = 3840 * 0.16 = 614 uS
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto keep_bit2 ; time more than or equal 600 uS
goto noise
keep_bit2 ; count 2 bit
banksel counter
incf counter,F
keep_bit1 ;count 1 bit
banksel counter
incf counter,F
banksel bit_buffer
movf bit_buffer,W
movwf INDF ;keep data
incf FSR,F
call check_RAM_address
banksel timeL
movf timeL,W
movwf INDF ;keep timeL
incf FSR,F
call check_RAM_address
banksel timeH
movf timeH,W
movwf INDF ;keep timeH
incf FSR,F ;for next data
call check_RAM_address
return
; change ram address
check_RAM_address
bsf STATUS,C
movlw 0xba
subwf FSR,W
btfsc STATUS,C
goto 0x0000
movlw 0x7d
subwf FSR,W
skpz
return
movlw 0xa0
movwf FSR
return
noise
movlw 0x18 ; data = 26 to 27 bit
banksel counter
bsf STATUS,C
subwf counter,W
btfss STATUS,C
goto re_count
; got data
movlw 0x00
movwf FSR
return
re_count
goto 0x0000
;=============================================================
end
i use 16F684 to be RF remote decoder
normally, there are a lot of noise from out out of RF decoder module
i need to detect 28 bits code with 250-300 uSec pulse width
after i detected i need to send forward to another
i use this 684 like a pulse fillter...
my problem,
1. 16F684 can not dectect signal in first times i need to press remote two or tree times
2. i if i dont use "goto 0x0000" my 16F684 always "hank"
3. for " goto test " i think it should send pulse out forever but it isnt !!
it send out just one time and send only if there are an on change interrupt
why ???
and the last is ... i set its oscillator to be 8 Mhz its mean for 1 istruction it need
1/(8MHz /4) = 0.5 uSec but i try it to do
bsf PORTC,2
bcf PORTC,2
bsf PORTC,2
bcf PORTC,2
i got a pulse with pulse width 0.16uSec... what wrong? i try 3 CPU but the same results
list p=16F684
#include <p16F684.inc>
__CONFIG 0x34c4
FSR_temp equ 0xa0
counter equ 0xba
ii equ 0xbb
bit_bufferP equ 0xbc
bit_buffer equ 0xbd
timeH equ 0xbe
timeL equ 0xbf
status_temp equ 0x7e
w_temp equ 0x7f
bank0 macro
movlw 0x1f
andwf STATUS,F
endm
bank1 macro
bcf STATUS,IRP
bcf STATUS,RP1
bsf STATUS,RP0
endm
org 0x0000
clrf INTCON
clrf PCLATH ; ensure page bits are cleared
goto start
org 0x0004
goto interrupts_vector
start
;==============================================================
;== subrutine of initial all port and somefunction ===========
;==============================================================
;initial 16F684
banksel ANSEL
clrf ANSEL ; all analog pins are digital
banksel CMCON0
movlw 0x07
movwf CMCON0 ; off comparator
banksel WPUA
clrf WPUA ;disable pull up
banksel OPTION_REG
bcf OPTION_REG,7 ; disable pull up on PORTA
banksel TRISA
movlw b'00111111' ; RA5 as input RA0 i/p of comparator
movwf TRISA
;setup_interrupt_on_change on PORTA check TRISA on setup PORT
bsf INTCON,RAIE ;interrupt on change
banksel IOCA
movlw 0x01
movwf IOCA ; enable RA5 interrupt on change
;setup port C
banksel TRISC ; analog i/p RA2 =C2OUT RC0 = C2IN+ , RC4 =C1OUT RA0 = C1IN+
movlw b'00000000' ;RC5 is an input to disable decoder
movwf TRISC
banksel PORTC
movlw 0xff
movwf PORTC
;setup_timer1
banksel CMCON1 ; config T1G as comparator o/p
clrf CMCON1
banksel T1CON
movlw 0x04
movwf T1CON ;1:1 prescale
banksel PIE1
bcf PIE1,TMR1IE
;setup internal oscillator
banksel OSCTUNE
movlw 0x0F
movwf OSCTUNE
banksel OSCCON
movlw 0x75
movwf OSCCON ; use clock 8 Mhz
bsf INTCON,7
bsf INTCON,6
goto main
;//////////////////////////////////////////////////////////////
main
movlw 0x27
movwf FSR ; set address
banksel counter
clrf counter
banksel T1CON
bsf T1CON,TMR1ON
wait_signal
movf FSR,F
skpz
goto wait_signal
;===========================================================
;=========== now time to send data forward===================
;============================================================
test
;///////////////////////////////////////////////////////////
bcf INTCON,RAIE ;disable interrupt on change
bcf INTCON,GIE ;disable all interrupts
bcf INTCON,PEIE
banksel T1CON
bcf T1CON,TMR1ON ;stop timer1
;/////////////////////////////////////////////////////////
banksel TMR1H
clrf TMR1H
clrf TMR1L
call delay
;======================================================
; ======= time to send out data =======================
;========================================================
send_data
movlw 0x27
movwf FSR ; data
send_out
movf INDF,W
banksel PORTC
movwf PORTC
incf FSR,F ; index timeL
call check_RAM_address
movf INDF,W
sublw 0xff ; 0xff - W => W
banksel TMR1L
movwf TMR1L
incf FSR,F ;index timeH address
call check_RAM_address
movf INDF,W
sublw 0xff ; 0xff - W => W
banksel TMR1H
movwf TMR1H
call delay
incf FSR,F ; index next data
call check_RAM_address
decf counter,F
skpz
goto send_out
{ !!!! goto test !!!}
goto 0x0000
;===========================================================
;============================================================
;=====================delay =================================
;======= TMR1H and TMR1L need to be setted before call ====
;======= this subroutine =======================
;============================================================
delay
banksel PIE1
bsf PIE1,TMR1IE ; enable timer1 interrupt
bsf INTCON,PEIE
bsf INTCON,GIE
banksel T1CON
bsf T1CON,TMR1ON ;start timer1
banksel ii
movlw 0xff
movwf ii
wait_delay ;wait timer1 INT
banksel ii ; untilll ii == 0x00 clrf by timer1_INT
movf ii,F
skpz
goto wait_delay ; wait timer1 INT
banksel T1CON
bcf T1CON,TMR1ON ;stop timer1
banksel PIE1
bcf PIE1,TMR1IE ; disable timer1 interrupt
bcf INTCON,GIE
bcf INTCON,PEIE
return
;============================================================
;===================== end delay =================================
;============================================================
;====================================================================
;========== interrupts routine service detector ===================
;========== dectect the cause of interrupt ==============
;==================================================================
interrupts_vector
movwf w_temp
swapf STATUS,W
clrf STATUS
movwf status_temp ; keep data on status reg.
btfsc INTCON,RAIF ;interrupts is the most importante
call RA_INT
banksel PIR1
btfsc PIR1,TMR1IF ;interrupts is the most importante
call TMR1_INT
bcf STATUS,Z ; for skpz in main loop
swapf status_temp,W
movwf STATUS ; return data on w registor
swapf w_temp,F
swapf w_temp,W
bsf INTCON,PEIE
retfie
;/////////////////////////////////////////////////////////////
TMR1_INT
banksel PIR1
bcf PIR1,TMR1IF
banksel ii
clrf ii
return
;==================================================================
; =====interrupt on change of port RA5 is used to be input========
;==================================================================
RA_INT
banksel PORTA
movf PORTA,F ; cancle mismath condition
bcf INTCON,RAIF ; clear interrupt flag caused by RA5
;keep previous status of RA5
banksel bit_bufferP
movf bit_bufferP,W
banksel bit_buffer
movwf bit_buffer
banksel PORTA
movf PORTA,W ; cancle mismath condition
banksel bit_bufferP
movwf bit_bufferP
comf bit_bufferP,F ; inversion
;read timer
banksel TMR1H
movf TMR1H,W
banksel timeH
movwf timeH
banksel TMR1L
movf TMR1L,W
banksel timeL
movwf timeL
;clear timer
banksel TMR1H
clrf TMR1H
clrf TMR1L
;check time lower than limited
movlw 0x05 ; 0x04 163.84 uS 0x05 = 254 uSec
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto noise ; time less than 163.84 uS it is noise
;check time higher than limited
; timeH_more_than_163uS
movlw 0x09 ; 0x1500 = 900uS 0x0fff = 3840 * 0.16 = 614 uS
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto keep_bit1 ; time more than or equal 600 uS
;check time lower than limited
movlw 0x0b ; 0x04 163.84 uS 0x05 = 254 uSec
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto noise ; time less than limited
timeH_more_than_163uS
movlw 0x12 ; 0x1500 = 900uS 0x0fff = 3840 * 0.16 = 614 uS
banksel timeH
bsf STATUS,C
subwf timeH,W
btfss STATUS,C
goto keep_bit2 ; time more than or equal 600 uS
goto noise
keep_bit2 ; count 2 bit
banksel counter
incf counter,F
keep_bit1 ;count 1 bit
banksel counter
incf counter,F
banksel bit_buffer
movf bit_buffer,W
movwf INDF ;keep data
incf FSR,F
call check_RAM_address
banksel timeL
movf timeL,W
movwf INDF ;keep timeL
incf FSR,F
call check_RAM_address
banksel timeH
movf timeH,W
movwf INDF ;keep timeH
incf FSR,F ;for next data
call check_RAM_address
return
; change ram address
check_RAM_address
bsf STATUS,C
movlw 0xba
subwf FSR,W
btfsc STATUS,C
goto 0x0000
movlw 0x7d
subwf FSR,W
skpz
return
movlw 0xa0
movwf FSR
return
noise
movlw 0x18 ; data = 26 to 27 bit
banksel counter
bsf STATUS,C
subwf counter,W
btfss STATUS,C
goto re_count
; got data
movlw 0x00
movwf FSR
return
re_count
goto 0x0000
;=============================================================
end