list p=16f84a include "p16f84a.inc" __CONFIG B'11111111111010' INTCON equ 0Bh OPTION_REG equ 81h STATUS equ 03h R0 equ 0Ch R1 equ 0Dh GBYTE equ 0Eh CBYTE equ 0Fh TR0 equ 01h ; Bit definition INTF equ 1 T0IF equ 2 INTE equ 4 T0IE equ 5 C equ 0 RB0 equ 0 ;Timer Prescale-bits PS0 equ 0 PS1 equ 1 PS2 equ 2 INIT bsf STATUS,RP0 ; wähle Bank1 ;Interrupt config bsf INTCON,INTE ; Enables RB0/INT External Interrupt bsf INTCON,T0IE ; Enables TMR0 Overflow Interrupt movlw B'10010001' ; Interrupt on falling edge of RB0/INT pin ; TMR0 Clock Source: Internal instruction cycle clock ; Prescaler is assigned to Timer0 module ; Prescale 1:4 movwf OPTION_REG ;Port config movlw B'00000001' ; PortB alle output ausser RB0 movwf TRISB movlw B'00000000' ; PortA alle output movwf TRISA call RA0_OFF MAIN btfsc PORTB, RB0 ;Skip wenn Pin 0 von PORT B auf Null geht (warte auf anfang) goto MAIN W1 btfss PORTB, RB0 ;Skip wenn Pin0 wieder auf "eins" geht goto W1 ;7mal für 2.Startbit, Toggle-Bit und Geräte-Code movlw #07h movwf R0 S1 btfsc PORTB, RB0 ;Wenn aktueller Zustand "1" => warte max 1000µs auf "0" goto waitNull btfss PORTB, RB0 ;Wenn aktueller Zustand "0" => warte max 1000µs auf "1" goto waitEins S2 decfsz R0 goto S1 goto MAIN istNull ;Also von 1 auf 0 => Bit ist 1 ;speichern des Bits im Carry bsf STATUS, C rlf GBYTE,f goto S2 istEins ;Also von 0 auf 1 => Bit ist 0 ;speichern des Bits im Carry bcf STATUS, C rlf GBYTE, f goto S2 waitNull ;1000µs / 8µs = 125d 255-125 = 130d => 82h ;Prescaler auf 1:8 - 010 PS2:PS0 bcf OPTION_REG,PS0 bsf OPTION_REG,PS1 bcf OPTION_REG,PS2 movlw #82h movwf TR0 bcf INTCON, T0IF ;TimerFlag rücksetzen T1 btfss PORTB, RB0 ;Ist Pin0 noch "1"? goto istNull ;Nein! gehe zu istNull btfss INTCON, T0IF ;Ist die Zeit abgelaufen? goto T1 ;Nein, dann Warte auf "0" an Pin0 goto MAIN ;Wenn Zeit abgelaufen return waitEins ;1000µs / 8µs = 125d 255-125 = 130d => 82h ;Prescaler auf 1:8 - 010 PS2:PS0 bcf OPTION_REG,PS0 bsf OPTION_REG,PS1 bcf OPTION_REG,PS2 movlw #82h movwf TR0 bcf INTCON, T0IF ;TimerFlag rücksetzen T2 btfsc PORTB, RB0 ;Ist Pin0 noch "0"? goto istEins ;Nein! gehe zu istEins btfss INTCON, T0IF ;Ist die Zeit abgelaufen? goto T2 ;Nein, dann Warte auf "0" an Pin0 goto MAIN ;Wenn Zeit abgelaufen return RA0_ON bcf STATUS,RP0 ; wähle Bank0 movlw #01h movwf PORTA return RA0_OFF bcf STATUS,RP0 ; wähle Bank0 movlw #00h movwf PORTA return end