Forum: Mikrocontroller und Digitale Elektronik PIC 16F630 Timer1 Problem (Assembler)


von Road Runner (Gast)


Lesenswert?

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

von Road Runner (Gast)


Lesenswert?

Irgendwie hat das anhängen der Datei nicht funktioniert, desshalb hier 
noch der Link zu meinem ASM File
http://home.zhwin.ch/~hoinmic/Taktgen.asm

von Aleksandar (Gast)


Lesenswert?

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

von Aleksandar (Gast)


Lesenswert?

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

von tastendrücker (Gast)


Lesenswert?

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.

von Road Runner (Gast)


Lesenswert?

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.

von St182 (Gast)


Lesenswert?

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

von Aleksandar (Gast)


Lesenswert?

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

von Road Runner (Gast)


Lesenswert?

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

von tastendrücker (Gast)


Lesenswert?

>Kann mir jemand dieses Phänomen erklähren?

PIC defekt?

von Road Runner (Gast)


Lesenswert?

Nein, der PIC ist IO. ich habs noch mit einem zweiten Versucht, und der 
hat genau gleich reagiert.

von Aleksandar (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.