hi
Seit kurzem bastle ich mit dem PIC 16F630 herum. Kleine Projekte mit
einem Interrupt an einem Pin hab ich problemlos hinbekommen, jedoch
komme ich mit diesem Projekt einfach nicht mehr weiter.
Nach der Port und Timer1 Initialisiertung wird auf PortA "0" immer
zwischen High und Low gewechselt (damit ich sehe, dass der pic läuft).
Der Timer1 interrupt wird jedoch nie ausgelöst. Um das zu prüfen, habe
ich in der Interruptroutine den PortA "1" auf High geschaltet (damit ich
sehen würde, wenn die Routine mindestens einmal durchlaufen würde).
Ich denke das ich irgend ein Flag bei der Timer1 Initialisierung
vergessen habe zu setzen, aber ich komme einfach nicht drauf was es sein
könnte.
thx schon mal
Hallo Road Runner BEEP BEEEP ;)
Bevor ich mir Dein Quelltext genauer ansehe, einige Bemerkungen:
1. Wenn der uC in die Interrupt-Routine einspringt, ist die gerade
aktive Bank unbekannt. Deswegen ist das ERSTE was man macht, Status und
W Register zu retten, denn gerade aktive Bank ist im STATUS gespeichert,
und neue Bank kann man erst ueber W setzen.
Deswegen kann der erste Befehl zum ausschalten von Timer1 schief gehen,
wenn der uC gerade in der Bank 1 ist.
Das ist auch der Grund, warum man w_temp und status_temp unbedinngt in
"shared memory" setzen soll. Das ist der Speicher, der bei meisten
16xPIC ab der Adresse 0x70 beginnt. Er ist aus allen Baenken verfuegbar.
Praktisch zeigen die Speicherbereiche
0xF0 - 0xFF
0x170 - 0x17F
0x1F0 - 01xFF
alle auf den Speicherberiech 0x70 - 0x7F (die Adressen hier habe ich als
Beispiel aus dem Datasheet von 16F87X genommen, bei 630 koennen die
Adressen anders sein, und die Anzahl der Baenke ist bestimmt kleiner).
2. Zweitens, brauchst Du den Timer1 in der Interruptbehandlugsroutine
NICHT auszuschalten. Du muesst Dich nur darum kuemmern, dass die Routine
mit Sicherheit beendet ist, bevor der naechste Interrupt kommt.
3. Und im Zussamenhang damit, wenn Du TMR1IF loeschst, gibst Du das
gruene Licht fuer die naechte Unterbrechung. Wenn sie eventuell schon
waehrend der Bearbeitung der letzten kommt, was man eigentlich durch die
Laenge der Bearbeitung meiden soll, gleich nach der Bearbeitung der
aktuellen Unterbrechung springt der arme 16F630 wieder in die ISR. Es
ist besser ein Interrupt zu "uebersehen" als stanedig in der ISR zu
haengen. Deshalb loescht man den Interrupt-Flag in der Regel kurz vor
dem Retten von W und STATUS - ist aber eher eine zweite
Sicherheitsstuffe.
4. Ich habe den Eindruck, dass Du Dich kaum um die Bankumschaltung
kuemmerst. Schau Dir Hilfe zum MACRO "banksel" Syntax ist banksel TRISA.
Lieber einige banksel Anweisungen zu viel, als zu wenig - dann
funktioniert das Programm MIT SICHERHEIT nicht, schreibt noch in
irgendwelche falsche Register und PIC kann sehr gut haengen bleiben.
Damit Du den Ueberblick nicht verlierst, habe ich die Arbeit fuer Dich
gemacht:
;***** VARIABLE DEFINITIONS
w_temp EQU 0x70 ; !!! PRUEFEN ob es fuer 630 stimmt !!!
status_temp EQU 0x71 ; variable used for context saving
ORG 0x004 ; interrupt vector location
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
banksel PORTA
BSF PORTA,1
MOVLW 0x80
MOVWF TMR1H
MOVWF TMR1L ; timer laden
BCF PIR1, TMR1IF ; Timer1 Interrupt-Flag löschen
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
Und ich habe Dein Code durch den Debugger gejaggt - alles funktioniert,
die hier genannten Bemerkungen haben keinen Einfluss auf den Code, weil
die main Routine so einfach ist. Klappt es bei Dir im Debugger?
Gruss, Aleks
ooops!
Ich habe mir jetzt den Datasheet fuer den 630 angesehen, er hat nur 64
Byte Data RAM und damit NUR EINE Speicherbank fuer "General Purpose
Register", damit sind alle Adressen "Shared memory" und damit ist es
egal wo man w_temp und status_temp ablegt.
Gruss noch mal,
Aleks
Ich kann nicht erkennen, dass Du die internen Pull-Up Widerstände
aktiviert hast - oder hast Du externe Pull-Up's?
Ohne Pull-Up's kannst Du nichts am Ausgang von PortA messen.
Thx für die Antworten aber es läuft noch nicht =(
@Aleks
Also ich hab das Programm so abgeändert wie du gesagt hast, aber es tut
sich nach dem brennen immer nur etwas am portA "0" (Abwechselnd high
low), der portA "1" bleibt weiterhin immer auf Low. Im MPLAB SIM läuft
das Programm einwandfrei.
@tastendrücker
Ich hab extrene Pull-down widerstände, an portA "0" läuft alles
einwandfrei. Wenn es etwas mit den wirderständen zu tun hätte, denke ich
würde der auch nicht funktionieren, oder?
Hier mal noch der link zum abgeändereten File (Änderungsidee von Aleks
hineingenommen):
http://home.zhwin.ch/~hoinmic/Taktgen_2.asm
Könnte es sein, dass beim brennen etwas schieff geht? Ich habe einen
ELNEC SMARTPROG2? Komisch ist einfach, dass das Programm in der
Simulation läuft und nach dem brennen nicht mehr.
Hallo.
Ich habe mir das ASM noch nicht angesehen, aber eine Sache in vorhinein:
man muß PEREPHERIE INTERUPT und den TMR 1 INTERUPT freigeben damit TMR
1 interupt ausgelöst werden kann.
MfG St182
Halloechen nochmal!
Nun ich dachte zuerst, es liegt daran, dass A0 und A1 auch als analoge
Eingaenge fuer den Comparator fundieren, aber das sollte eigentlich nur
bei einer Verwendung als Eingang eine Rolle spielen. Die beiden Pins
werden auch zum Programmieren benutzt, hast Du den Programmer getrennt?
Das einzige was mir noch einfaellt ist, einfach das gleiche mit dem
PORTC zu probieren, am sonsten habe ich keine Idee woran es liegen kann.
Normalerweise liefert der Simulator im MPLAB fast immer sehr reele
Ergebnisse.
Gruss,
Aleks
Hallo
Ich habe jetzt per Zufall das Problem beheben können. Es lag nicht man
Interrupt sondern Pin RA1 (PORTA,1) wenn ich als Ausgang RA2 (PORTA,2)
wähle Funktioniert alles perfekt.
Kann mir jemand dieses Phänomen erklähren? Beim PIC16F630 steht im
Datenblatt zu diesem PIN lediglich : RA1/Cin-/ICSPCLK
Danke allen die mir vorher probiert haben zu helfen
Gruss Michael
Datasheet 16F630:
Kapitel 3.1:
The ANSEL (9Fh) and CMCON (19h)
registers must be initialized to configure an
analog channel as a digital input. Pins
configured as analog inputs will read ‘0’.
Gleich in der Fortsetzung ist ein Beispiel gegeben, wie man die Pins als
digitale Pins definiert:
bcf STATUS,RP0 ;Bank 0
clrf PORTA ;Init PORTA
movlw 05h ;Set RA<2:0> to
movwf CMCON ;digital I/O
Der Grund, warum die analoge Eingaenge den Ausgang beeinflussen (wenn
das ueberhaupt die Ursache Deines Problems mit A0 und A1 ist) koennte
der Read/Write Cyklus sein.
Wenn das hilft, bitte hier berichten, dann lernen wir auch was :)
Wenn das nicht hilft, empfehle ich Dir Forum auf:
http://www.fernando-heitor.de
Dort gibt es wesentlich mehr Leute, die sich hauptsaechlich mit PICs
beschaeftigen.
Gruss,
Aleks