Hallo,
ich habe mir anhand von Stefan Froede´s Schaltung und einer Schaltung von http://www.sprut.de/index.htm einen IR-ATX-Einschalter auf PIC 16F84-Basis gebaut. Der Prozessor ist leicht aufzutreiben und kann mit einer primitiven Schaltung programmiert werden. Ich würde das ganze auch mal gerne öffentlich machen, falls Interesse besteht, hab aber noch ein kleines Problem:
Es klappt soweit super, aber die Schaltung ist noch "vergesslich", d.h. wenn der Strom weg ist, also die Schaltung z.B. abgeklemmt wird, vergißt sie auch den gelernten Code. Mein Problem ist, dass das Speichern im und/oder Auslesen aus dem Eeprom nicht klappt.
Kennt sich jemand in PIC-Programmierung aus (bin absoluter Neuling)? Es geht konkret um das Speichern/Auslesen der Variablen gr_m und co_m.
Der von mir modifizierte Code sieht folgendermaßen aus:
list p=16f84
; sprut (zero) Bredendiek 06/2001
;**************************************************************
; Includedatei für den 16F84 einbinden
#include <P16f84a.INC>
; Variablennamen vergeben
w_copy Equ 0x20 ; Backup für Akkuregister
s_copy Equ 0x21 ; Backup für Statusregister
gr_m Equ 0x22 ; gespeicherte Gruppe
co_m Equ 0x23 ; gespeicherters Commando
ar Equ 0x27
gr_e Equ 0x28 ; empfangene gruppe
cycl_1 Equ 0x29 ; zähler
cycl_2 Equ 0x2A ; zähler
cycl_3 Equ 0x2B ; zähler füe empfangsbitschleife
data_1 Equ 0x2C ; datenpuffer low-teil
data_2 Equ 0x2D ; datenpuffer high-teil
co_e Equ 0x2E ; empfangenes commando
#define bank0 bcf STATUS,RP0 ;select bank 0
#define bank1 bsf STATUS,RP0 ;select bank 1
magic macro ;magic EEPROM write sequence
movlw 55H
movwf EECON2^80H
movlw 0AAH
movwf EECON2^80H
endm
;**************************************************************
; los gehts mit dem Programm
org 0
goto Init
; Port A/B auf Ausgabe stellen
Init
bcf INTCON, GIE ; Interupts ausschalten
movlw B'00000000'
movwf PORTA
movwf PORTB ; Anzeige dunkel
bsf STATUS, RP0 ; auf Bank 1 umschalten
movlw B'11110000' ; PortA RA0-RA3 output
movwf TRISA
movlw B'00000000' ; PortB alle output
movwf TRISB
bcf STATUS, RP0 ; auf Bank 0 zurückschalten
; gelerntes aus EEPROM lesen
; Gruppencode
clrf EEADR ;Gruppencode bei Adresse 0
call ee_rd
movf EEDATA,w ;read EEPROM
movwf gr_m; ;Gruppencode speichern
; Commando
incf EEADR,f ;Commando bei Adresse 1
call ee_rd
movf EEDATA,w ;read EEPROM
movwf co_m; ;Commando speichern
clrf gr_e
clrf co_e
clrw
;**********************************************************
;**********************************************************
;*
;* pollen der leitung
;*
;* RC-5 bus pollen
;* empfangene signale auf LED ausgeben
;*
;**********************************************************
;**********************************************************
pollen
call empfangen ;IR empfangen
btfsc PORTA,3 ; falls Jumper3 gesetzt dann Lernen
call lernen
btfsc PORTA,3
goto pollen
movfw gr_e ; gruppenadresse
subwf gr_m, w
btfss STATUS,Z
goto aus
ein
clrw
movfw co_e ; code
subwf co_m, w
btfss STATUS,Z
goto aus
bsf PORTA, 0 ; A0 ein
bsf PORTB, 0 ; LED ein
call pause100ms ;100ms warten
bcf PORTA, 0 ; A0 aus
bcf PORTB, 0 ; LED aus
clrf gr_e
clrf co_e
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
goto next
aus
clrw
movfw gr_e ; code
sublw 0
btfsc STATUS,Z
goto next
movfw co_e ; code
sublw 0
btfsc STATUS,Z
goto next
clrf gr_e
clrf co_e
next
goto pollen
; zum anlernen eines neuen Befehls
lernen
startlernen
call empfangen ;IR empfangen
movfw gr_e ; gruppenadresse
sublw D'0'
btfsc STATUS,Z
goto startlernen
clrw
movfw co_e ; code
sublw D'0'
btfsc STATUS,Z
goto startlernen
; im EEPROM speichern
; Gruppencode
MOVLW 0;
MOVWF EEADR ; Address to write
movfw gr_e
MOVWF EEDATA
call ee_wr
; Commandocode
MOVLW 1;
MOVWF EEADR ; Address to write
movfw co_e
MOVWF EEDATA
call ee_wr
; speichern
movfw gr_e
movwf gr_m
movfw co_e
movwf co_m
clrf gr_e
clrf co_e
; 5mal langsam blinken
bank0
bsf PORTB, 0 ; LED ein
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bcf PORTB, 0 ; LED aus
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bsf PORTB, 0 ; LED ein
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bcf PORTB, 0 ; LED aus
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bsf PORTB, 0 ; LED ein
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bcf PORTB, 0 ; LED aus
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bsf PORTB, 0 ; LED ein
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bcf PORTB, 0 ; LED aus
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bsf PORTB, 0 ; LED ein
call pause100ms ;100ms warten
call pause100ms ;100ms warten
bcf PORTB, 0 ; LED aus
; ca. 1sek warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
call pause100ms ;100ms warten
return
;**********************************************************
;
; einen RC-5-code mit polling empfangen
;
; gruppencode: gr_e
; commando : co_e
;
;**********************************************************
; vor dem aufruf wenigstens 1 ms low pegel abwarten !!
empfangen
btfss PORTA, 4
goto empfangen ; warten auf high
empfangenL
btfsc PORTA, 4
goto empfangenL ; warten auf low, 1/2-Bit vorbei
call viertelbit ; 1/4 nach bitmitte
btfsc PORTA, 4
goto Fehler ; war nur spike
clrf data_1 ; datenpuffer löschen
clrf data_2
movlw D'13' ; 13 bits bei syncronisation
movwf cycl_3
;
; 3/4 nach bitanfang wird wert gelesen, invertiert
; und eingeschrieben
; dann wird auf die flanke gewartet, die das neue bit einleitet
; nach der flanke wird bis 3/4 bit gewartet und dann neu begonnen
;
call halbbit ; 1/4 des 2. Bits
nextbit
rlf data_1,f
rlf data_2,f
bcf data_1, 0 ; angenommen leitung ist low (0)
btfsc PORTA, 4 ; leitung abfragen
bsf data_1, 0 ; leitung ist high (1), in datenpuffer
; warten auf pegeländerung
call anders ; Bitmitte
call viertelbit ; 3/4 Bit
call halbbit ; 1/4 nach bitanfang
decfsz cycl_3,f ; alle 13 bit + startbit empfangen?
goto nextbit
movfw data_1
movwf co_e
bcf co_e, 6
bcf co_e, 7 ; auf 6 bit begrenzen
rlf data_1,f
rlf data_2,f
rlf data_1,f
rlf data_2,f ; gruppe nach data_2
movfw data_2
movwf gr_e
bcf gr_e, 7
bcf gr_e, 6
bcf gr_e, 5 ; auf 5 bit begrenzen
; 2. stoppbit zum 7 commandobit machen
btfss data_2, 6
bsf co_e, 6 ;2. Stoppbit invers -> 7.commandobit
movfw co_e
Fehler
return
;**************************************************************
;
; warten darauf, dass die leitung RA0 dem inversen wert in 'data_1, 0' entspricht
;
; zeitbegrenzt auf ca. ein halbes bit
;
;**************************************************************
anders
; movlw D'22' ; 22 x (10 MHz)
movlw D'9' ; 9 x ( 4 MHz)
movwf cycl_1
a_1
movlw D'32' ; 100 takte
movwf cycl_2
a_2
decfsz cycl_2,f
goto a_2
btfsc PORTA, 4 ; portpegel abfragen
goto a_high
a_low ; portpegel ist 0
btfsc data_1, 0 ; ist sollwert=0 ?
return ; high-low flanke
goto a_weiter
a_high ; portpegel ist 1
btfss data_1, 0 ; ist sollwert=1 ?
return ; low-high flanke
a_weiter
decfsz cycl_1,f
goto a_1
return ; keine flanke gefunden
;**************************************************************
;
; zeitverzögerung um ein viertelbit = 444,5 us ca. 1100 takte (10 MHz)
; 445 takte (04 MHz)
;
; zeitverzögerung um ein halbbit = 889 us ca. 2200 takte (10 MHz)
; 889 takte (04 MHz)
;
;**************************************************************
pause ;2ms für 45
movlw D'45'
goto l_0
pause_l ;ca 12ms für 255
movlw D'255'
goto l_0
viertelbit
; movlw D'11' ; 11 x (10 MHz)
movlw D'9' ; 9 x ( 4 MHz)
goto l_0
halbbit
; movlw D'22' ; 22 x (10 MHz)
movlw D'18' ; 18 x ( 4 MHz)
l_0
movwf cycl_1
l_1
; movlw D'32' ; 100 takte (10 MHz)
movlw D'15' ; 49 takte ( 4 MHz)
movwf cycl_2
l_2
decfsz cycl_2,f
goto l_2
decfsz cycl_1,f
goto l_1
return
pause100ms ; Pause von ca. 100ms
call pause_l ;12ms warten
call pause_l ;12ms warten
call pause_l ;12ms warten
call pause_l ;12ms warten
call pause_l ;12ms warten
call pause_l ;12ms warten
call pause_l ;12ms warten
call pause_l ;12ms warten
return
ee_rd
bank1
bsf EECON1^80H,RD ;start read
bank0
return ;read will be complete on return
; ee_wr
;
; Writes byte in EEDATA to EEPROM location at EEADR. Interrupts
; should be disabled before calling ee_wr.
ee_wr
bank1
magic ;invoke magic sequence
bsf EECON1^80H,WR ;start write
ee_wr1 btfsc EECON1^80H,WR ;write complete?
goto ee_wr1 ;no
bank0
return
end
Alles anzeigen