PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC umprogrammieren



Atmelbeginne
01.09.2008, 07:55
Guten Morgen!

Ich habe da mal wieder eine Frage. :-b

Folgendes habe ich vor:

Ich brenne eine XY.asm Datei auf einen PIC. Danach verbaue ich den PIC in eine Schaltung die von einem PC aus gesteuert wird. Beim beenden der Anwendung wäre es sehr hilfreich irgendwelche Daten ( z.B. ein Flag oder ein Zahlenwert ) ind den PIC zu schreiben, an der er sich nach Wiederinbetriebnahme "erinnert". Meinen Recherchen bei Google hat ergeben, das dieses nicht so einfach ist, da nur in den flüchtigen speicher geschrieben werden kann, der sich nach dem Abschalten löscht. Es müsste eine geänderte XY.asm DAtei auf den PIC gebrannt werden. Das könnte man offensichtlich mit ISCP realisieren. Das Thema habe ich aber garnicht verstanden. ](*,) ](*,)

Daher meine Frage: Gibt es einen Weg einen Wert in den PIC zu schreiben der beim erneuten Start noch vorhanden ist? (dynamisch)

Kann man in einen PIC in der Schaltung (nicht PIC-Brenner) ein Register dauerhaft beschreiben?

Im voraus vielen Dank!!

T.J.
01.09.2008, 08:26
Hat denn dein PIC kein EEPROM?

Atmelbeginne
01.09.2008, 08:28
Wie soll ich deine Frage verstehen??

Duke of Doom
01.09.2008, 09:30
Ja das geht.... Prinzipiell gibt es zwei Möglichkeiten. Die meisten pics haben einen internen e2prom in den du daten speichern kannst. Einige pic (z.B. 18-serie aufwärts) können auch in ihren eigenen programmspeicher schreiben.

Atmelbeginne
01.09.2008, 10:57
Ja super. Ich verwende einen PIC16F628A. Gibt es da einen Ausdruck wie das verfahren heisst??

the_Ghost666
01.09.2008, 11:29
Schau im Datenblatt unter EEPROM, der PIC hat einige EEPROM Bytes, die du bis zu 1Mio mal beschreiben kannst, die bleiben auch ohne Betriebsspannung über 20 Jahre erhalten. Im Datenblatt unter Punkt 13 oder Seite 91.
Du musst die spezielle Befehlsfolge aus dem Datenblatt abarbeiten um erfolgreich die Daten zu schreiben. Einfach mal aus dem Datenblatt in deinen ASM Code kopieren und testen.

Atmelbeginne
01.09.2008, 11:33
Vielen Dank

Habe gerade schon gesucht und gefunden. Daß das Datenblatt wieder wichtig ist habe ich mir gedacht :D

Zudem habe ich eine interessante Seite bei Sprut gefunden:

http://www.sprut.de/electronic/pic/programm/eeprom/eeprom.html

theborg
01.09.2008, 12:45
Ja das geht.... Prinzipiell gibt es zwei Möglichkeiten. Die meisten pics haben einen internen e2prom in den du daten speichern kannst. Einige pic (z.B. 18-serie aufwärts) können auch in ihren eigenen programmspeicher schreiben.

hi eigentlich geht das in den flaschschreiben schon ab den >16f870ern

mfg tb

the_Ghost666
01.09.2008, 16:29
ja, das stimmt, es gibt auch 16er Reihen, die das beherrschen. Das ist ne nette Sache für Bootloader, aber weniger geeignet um nur ein paar Daten abzulegen, denn der Flash muss z.b. immer Blockweise beschrieben werden, während der EEPROM einfach Byteweise geht.
Interessant wird es, wenn große Speichermengen auftauchen. Aber man sollte bedenken, dass mal Flash nur 10000-100000x beschreiben kann, demnach eignet er sich für Datenlogger eher nicht. Auch die SD-Karten machen irgendwann schlapp, aber die sind einfacher ausgetauscht wenn man nach einigen Jahren das Controll-Programm längst vergessen hat.

Atmelbeginne
01.09.2008, 16:32
Der EEProm wird nur 1 mal bei der ersten Verwendung beschrieben. Danach bleibt der Wert ein LEben lang.....

the_Ghost666
01.09.2008, 16:55
Dann würd ich dir auf jeden Fall dazu raten, den Wert im EEPROM abzulegen, einfach weil es bequemer ist. Du kannst mit nem ICSP-Programmer auch das EEPROM separat auslesen, ohne das Programm im Controller zu beeinflussen, das ist vielleicht beim Debuggen einfacher. Es sei denn, du brauchst mehr als 128Byte.

Atmelbeginne
01.09.2008, 20:47
Ich habe nun ein wenig Code geschrieben, der aber nicht so will wie ich das möchte:



; PIC auswaehlen
list p=16f628a

;---------------------------------------------------------------------------------

; Include Datei fuer PIC
#include <p16f628a.inc>

;---------------------------------------------------------------------------------

; Config Word
; Im Config Word werden Parameter gesetzt die in der *.inc Datei vordefiniert sind.
; Dort stehen alle Funktionen die Verfuegbar und aufrufbar sind

__config _MCLRE_ON & _PWRTE_OFF & _XT_OSC & _WDT_OFF

;---------------------------------------------------------------------------------

; Adressen deklarieren

; EEPROM lesen
; In diesem Beispiel wird der Wert aus der EEPROM-Adresse 0x00 benoetigt
; Dafuer wird die Adresse in das EEPROM-Adressregister geschrieben
BANKSEL EEADR ; In Bank mit Register EEADR wechseln
MOVLW 0x00 ; EEPROM-Adresse 0x00
MOVWF EEADR ; EEPROM-Adresse in Register schreiben

; Jetzt wird im EECON1-Register das EEPGD-Bit (Bit 7) geloescht
; und das RD-Bit (Bit 0) gesetzt. Damit wird der Inhalt der EEPROM
; Speicherstelle ins EEDATA-Register kopiert.
BCF EECON1, 7 ; Loeschen EEPGD-Bit
BSF EECON1, 0 ; Setzen RD-Bit

; Jetzt wird das Bitwort aus dem EEDATA-Register in das
; Arbeitregister W gelesen
MOVF EEDATA, W ; EEDATA-Register einlesen
MOVWF 0x20



end


Der Code funktioniert bis dahin wo er die Adresse im Arbeitsregister hat. Wenn ich aber dann sage das er den Inhalt in die Adress 0x20 schreiben soll, will er immer in die Adresse 0x0A0 schreiben..... ](*,)
KAnn hier jemand einen Fehler ekennen???

the_Ghost666
01.09.2008, 21:33
Bank select Fehler, EEDATA usw liegen alle in BANK1, es gibt aber kein 0x20 in bank1, nur in bank0, schau im Datenblatt auf Seite 18.
Der Befehl Banksel EEADR stellt die BankSel-Bits auf Bank1 um, du musst vor deinem Befehl auf Bank0 schalten oder mit der anderen Speicherzelle arbeiten.

mach aus den letzten beiden Zeilen:
MOVF EEDATA,W
BANKSEL TMR0
MOVWF 0x20

statt BANKSEL TMR0 (ich musste nur n Namen aus BANK0 nehmen, kannst auch PORTA oder so nehmen, statt TMR0)
kannst du auch

BCF STATUS,RP0
BCF STATUS,RP1

schreiben


PS:
Ich merke schon, dass du ein Beginner bist, aber warum ist dein Nick Atmelbeginner, wenn du mit PICs arbeitest? *G*

Atmelbeginne
01.09.2008, 22:50
Danke für den Tip. Das war mein Fehler. Jetzt funzt es...

Jo, ich bin ein Beginner, aber adfür komme ich schon sehr gut zurecht. Nur das eine oder andere sind flüchtigkeitsfehler.... :^o

Eine Frage habe ich auch noch. Ich würde gerne eine Pause von ca. 2 Sekunden mit einbauen. Ich kann mir zwar ausrechnen wie lange ein interner Takt dauert( T=1/F) Bei 4Mhz und Taktrate 1 intern zu 4 extern kommt da ungefähr 1µs raus. Wie kann ich aber sagen das eine Pause von 1000000 internen Takten machen soll bevor ein Sprung erfolgen kann.....
8-[ 8-[ 8-[

the_Ghost666
02.09.2008, 09:59
Sowas erledigst du entweder mit Warteschleifen, oder mit der Timerhardware und einem Interrupt.
Ich poste mal meine Standardschleife:


;---Warte 10xakku mikrosekunden, für 12MHz---------------------------------------------------------
;---Nutzt TEMP1 und TEMP2 als Zähler---------------------------------------------------------------
WAIT_10US
MOVWF TEMP1
WAIT1
MOVLW D'6'
MOVWF TEMP2
WAIT2
DECF TEMP2
BTFSS STATUS,Z
GOTO WAIT2

NOP
DECF TEMP1
BTFSS STATUS,Z
GOTO WAIT1
NOP
RETURN
;--------------------------------------------------------------------------------------------------



Um diese Schleife für 4Mhz anzupassen, musst du die Zahlenwerte ändern. Ausserdem brauchst du 2 Variablen, die die Zählstände beinhalten, hier TEMP1 und TEMP2. Durch Änderung der Zahlenwerte kannst du natürlich auch eine viel längere Schleife machen, aber weil wir nur Byte-Variablen haben, kann eine Schleife maximal 256x durchlaufen werden.
Ich hab hier eine innere Schleife, die bei WAIT2 bis zum GOTO WAIT2 geht, und eine äußere Schleife von WAIT1 bis GOTO WAIT1.
Die NOP Befehle habe ich als Finetouning eingebaut, um auf möglichst genau die gewünschte Zeit zu kommen.
Du kannst auch noch eine dritte Schleife um alles setzen und auch ne vierte, um die Wartezeit zu verlängern.
Im Code schreibst du dann nurnoch

MOVLW D'100'
CALL WAIT_10ms

und er macht alles selbst, bis nach der gewünschten Zeit (im Beispiel 100x10ms, also 1sek) das Unterprogramm durch ist und es weiter geht.

Mit dem MPLAB-Simulator kann man sowas übrigens hervorragend testen, weil er direkt anzeigen kann, wie lange man von einem Befehl zum nächsten braucht.
Wenn du mehr zu den Timer-Interrupts wissen willst, schau mal bei Sprut, ich hab mir alles über diese Seite beigebracht.

Atmelbeginne
02.09.2008, 18:56
Erst mal ein Dickes Dankeschön an dieses Forum. Hier wird einem sehr gut geholfen!!!


Ich habe auch einen Weg gefunden den Prozess nicht mehr als nötig zu stören. In den gewünschten 2 sek wollte ich sicher sein das eine Operation sicher ausgeführt ist. Nun habe ich mich ein wenig mit Flags auseinander gesetzt und festgestellt das nach der Ausführung meines Befehls das Zero Flag gesetzt wird. Ich brauche nun dieses Flag in einer Schleife nur abzufragen. Erst wenn das Flag gesetzt ist weitermachen.....

Jetzt habe ich eigendlich soweit alles alles verstanden und würde den Code gerne auf einen PIC brennen. Bisher lief alles störungsfrei in einem Simulator.

Ich habe mir eine Platine erstellt bei der ich die Anschlüsse für einen externen Resonator vorgesehen habe. Auch hier habe ich mal wieder eine Frage:

Ich habe in meinem ConfigWord



__config _MCLRE_ON & _PWRTE_OFF & _XT_OSC & _WDT_OFF


den XT_OSC angegeben. Kann ich jetzt einfach an den PortA an den Pins RA6 und RA7 einen Quarz mit 2 Keramikkondensatoren anschliessen?? Oder benötigt das eine weitere Konfiguration. Mein gesamter Code ist oben gelistet.

Vielen Dank im Voraus!!

the_Ghost666
02.09.2008, 19:32
Moin,

als Tip zu den Flags: natürlich können auch andere Operationen das Zero-Flag setzen. Deswegen würde ich dir raten, nach Abschluss des Programmteils mit der Operation eine eigene Flag-Variable zu nehmen und auf diese zu testen. Ich weiß jetzt zwar nicht, was du genau machst, aber bei mir ist eigentlich auch immer eine Speicherzelle für 8 Flags in Benutzung.
Wenn du diese auch noch in den Bereich zwischen 70h und 7Fh ablegst, so brauchst du für den Zugriff nichtmal die Bank wechseln.

Ja, das mit dem Quarz oder Keramikresonator geht genauso wie du sagtest. Du darfst mit XT max. 4Mhz dran haben, bei nem Quarz musst du mit der große der Kondesatoren aufpassen, zu groß und der schwingt nicht an. Schau am besten im Datenblatt, ich glaub ich nehm immer 15pF.

Um bei den Config-Words sicher zu gehen, füge ich immer alle ein, die möglich sind. Low Voltage Programming immer abschalten, sonst wird ein Pin von PortB nichtmehr als IO zur Verfügung stehen, Power Up-Timer schadet eigentlich nie, die 72ms merkst du eh nicht, wenn es nicht drauf ankommt. Brown Out würd ich abschalten, wenn du weißt, dass es ne sichere Spannungsversorgung ist, kannst du es anlassen, aber wenn der Innenwiderstand zu groß ist, und du ne recht starke Last einschaltest (z.B. ne IR-Diode für ne Fernbedienung, meine ziehen etwa 100mA), könnte das ausreichen den BrownOutReset auszulösen. Die Code Protection lass ich immer aus, ich bin eh der einzige, der an meine Controller geht.