Interrupt mit Bootloader von Sprut
Dienstag, 22. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  Timer (Assembler)  |  Interrupt mit Bootloader von Sprut « vorheriges nächstes »
Seiten: [1] 2 Nach unten Drucken
Autor Thema: Interrupt mit Bootloader von Sprut  (Gelesen 5577 mal)
 
deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« am: Mai 26, 2008, 09:31:54 »

Habe einen PIC 18F2550. Mit dem komme ich soweit auch sehr gut klar. Allerdings stellt sich mir jetz ein Problem.

Ich versuche eine Uhr zu basteln. Angezeigt wird auf einer 8x16 LED Matrix.

Jetzt will ich aber per Interrupt natürlich die Uhrzeit erhöhen, wie auch im Datenblatt des PICs beschrieben, aber ich brenne den PIC per Bootloader über USB.
D.h. mein Programm kann erst ab 0x800 anfangen.
Laut Datenblatt wird aber immer ein Sprung zu 0x8 bzw. 0x18 ausgeführt. Das bringt mein Programm durcheinander.

Kann man etwas dagegen unternehmen? Dem PIC sagen, dass der Interrupt erst nach 0x808 springen soll oder sowas?
Gespeichert
Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 373



Profil anzeigen
« Antworten #1 am: Mai 26, 2008, 12:52:41 »

Hallo,

Zitat
Laut Datenblatt wird aber immer ein Sprung zu 0x8 bzw. 0x18 ausgeführt. Das bringt mein Programm durcheinander.

das verstehe ich nicht, was bringt was in deinem Programm durcheinander? Normalerweise stehen doch an den Interrupt-Einsprungadressen nur die GOTOs zu den Service-Routinen. Da dürfte es doch egal sein, ob deren Code dies- oder jenseits von 800h steht.

Zitat
Kann man etwas dagegen unternehmen? Dem PIC sagen, dass der Interrupt erst nach 0x808 springen soll oder sowas?

Wie gesagt, entweder verstehe ich dich falsch oder die Antwort wurde oben schon geschrieben.

Gruss,
Edson
Gespeichert
deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #2 am: Mai 27, 2008, 13:52:56 »

so sieht das programm aus. alles unnötige hab ich rausgeschnitten:
Code:
List p=18F2550
#include <P18F2550.inc>

CONFIG     PLLDIV = 2
CONFIG     PWRT = ON           
CONFIG     BOR = OFF           
CONFIG     WDT = OFF           
CONFIG     LVP = OFF     

loops equ 0x31
loops2 equ 0x32
loops3 equ 0x33
merker equ 0x34
counter1 equ 0x35
counter2 equ 0x36
loops4 equ 0x37
loops5 equ 0x38
clock1 equ 0x39
clock2 equ 0x40
clock3 equ 0x41
loops6 equ 0x42
loops7 equ 0x43
al4rm equ 0x44

org 0
goto main

;Interrupt

org 8
goto RTCisr

main

;************************************************;
;******* Init ***********************************;
;************************************************;

; einstellen von RB0 & RB1 auf input

movlw   B'00000011'        ; RB0,1 inputs
movwf   TRISB

iorwf   TRISB, f          ; + RC2=CCP1 output

movlw B'00000000'
movwf TRISA

movlw B'01000011'
movwf TRISC

movlw D'0'
movwf al4rm


;############ RTC Init ######################

RTCinit
MOVLW 80h ; Preload TMR1 register pair
MOVWF TMR1H ; for 1 second overflow
CLRF TMR1L
MOVLW b'00001111' ; Configure for external clock,
MOVWF T1CON ; Asynchronous operation, external oscillator
CLRF clock3 ; Initialize timekeeping registers
CLRF clock2
MOVLW d'12'
MOVWF clock1
BSF PIE1, TMR1IE ; Enable Timer1 interrupt
; RETURN

;------------------------------------------------;
;---------------- Auswertung --------------------;
;------------------ Stunden ---------------------;
;------------------------------------------------;

lauf
call Stunden
goto lauf

;Stunden
;..................das programm an sich......................


RTCisr

BSF TMR1H, 7 ; Preload for 1 sec overflow
BCF PIR1, TMR1IF ; Clear interrupt flag56
INCF clock3, F ; Increment seconds
MOVLW d'59' ; 60 seconds elapsed?
CPFSGT clock3
RETFIE ; No, done
CLRF clock3 ; Clear seconds
INCF clock2, F ; Increment minutes
MOVLW d'59' ; 60 minutes elapsed?
CPFSGT clock2
RETFIE ; No, done
CLRF clock2 ; clear minutes
INCF clock1, F ; Increment hours
MOVLW d'23' ; 24 hours elapsed?
CPFSGT clock1
RETFIE ; No, done
MOVLW d'01' ; Reset hours to 1
MOVWF clock1

RETFIE ; Done

end

ok ich habe das problem jetz mit dem pic18simulator soweit lokalisiert, dass es daran liegt, dass das TMR0IF bit im INTCON register nicht gesetzt wird und damit auch kein interrupt ausgelöst wird durch überlauf des timer1. der timer1 sollte aber korrekt initialisiert worden sein. siehe programm oben.
« Letzte Änderung: Mai 27, 2008, 14:41:36 von deathks » Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #3 am: Mai 27, 2008, 15:26:41 »

Im Bootloader selber steht folgendes:

Code:
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
void _high_ISR (void)
{
    _asm goto RM_HIGH_INTERRUPT_VECTOR _endasm
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
void _low_ISR (void)
{
    _asm goto RM_LOW_INTERRUPT_VECTOR _endasm
}

Das bedeutet, dass ein Interrupt zunächst an die Stelle 0x08 bzw. 0x018 springt. Von dort wird er auf 0x808 bzw. 0x818 umgeleitet. In deinem Code musst du nun darauf achten, dass der Code bei 0x800 startet, und die Interruptvektoren bei 0x808 bzw. 0x818 liegen:

Code:
org 0x800     ; Neue Startadresse
goto main

;Interrupt

org 0x808     ; High Int.
goto RTCisr            ; CALL VERWENDEN !!!

Falls du Zeitkritsche Interrupts hast, sei noch bemerkt, dass das Vektorremapping eine Latenz von 2 Befehlszyklen (durch das goto) hervorruft.


Gruß
Stefan

« Letzte Änderung: Mai 28, 2008, 09:11:31 von Stampede » Gespeichert

deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #4 am: Mai 28, 2008, 06:53:27 »

ok ich habe das problem jetz mit dem pic18simulator soweit lokalisiert, dass es daran liegt, dass das TMR0IF bit im INTCON register nicht gesetzt wird und damit auch kein interrupt ausgelöst wird durch überlauf des timer1. der timer1 sollte aber korrekt initialisiert worden sein. siehe programm oben.
ja das mit dem bootloader haben wir mittlerweile erstmal vorweg gelassen. trotzdem danke. dann wissen wir ja, dass das so funktioniert.

wie im quote beschrieben, weiß ich jetzt aber, dass der TMR1 beim überlauf das überlauf bit nicht setzt. obwohl ich der meinung bin, dass alles richtig eingestellt wurde. code steht ja oben.
im PIR1 register wird das interrupt flag für TMR1 gesetzt, aber es wird definitiv kein interrupt ausgelöst.
« Letzte Änderung: Mai 28, 2008, 07:51:20 von deathks » Gespeichert
mogli
Hero Member
*****
Offline Offline

Beiträge: 580



Profil anzeigen
« Antworten #5 am: Mai 28, 2008, 08:45:03 »

schau mal ob die interrupt freigegeben sind -zur sicherheit

kontrolliere das T1RUN bit -

teste den timer mal mit internen takt vielleicht ist die externe schuld daran

welche funktion hat dies  BSF TMR1H, 7 ; Preload for 1 sec overflow
Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #6 am: Mai 28, 2008, 09:10:14 »

Zitat
im PIR1 register wird das interrupt flag für TMR1 gesetzt, aber es wird definitiv kein interrupt ausgelöst.
Ist ja auch kein Wunder, du aktivierst die Interrupts ja gar nicht:

Code:
        ; INIT:
bsf RCON, IPEN         ; Prioritätslevel aktiviert (falls nötig)
bsf INTCON, GIEH ; INT EIN

Dann sind im Code einige Fehler:

Code:
org 0
goto main

;Interrupt

org 8
goto RTCisr       ; // CALL VERWENDEN

main                                 ; // ENDLOS SCHLEIFE EINFÜGEN !!!!
                         

Korrekt muss das so heißen:

Code:

org 0x000
goto INIT

;+++++++++++++++++++++++++++++++++++++
; HIGH PRIORITY INTERRUPT SUBROUTINE
org 0x008
call hi.int, FAST ; fast
;+++++++++++++++++++++++++++++++++++++

INIT
;************************************************;
;******* Init ***********************************;
;************************************************;

; einstellen von RB0 & RB1 auf input

movlw   B'00000011'        ; RB0,1 inputs
movwf   TRISB

iorwf   TRISB, f          ; + RC2=CCP1 output

movlw B'00000000'
movwf TRISA

movlw B'01000011'
movwf TRISC

movlw D'0'
movwf al4rm

        bsf RCON, IPEN         ; Prioritätslevel aktiviert (falls nötig)
        bsf INTCON, GIEH ; INT EIN

main                                             ; Endlosschleife
goto main


Die ISR muss dann so enden:
Code:
        RTCisr
        [...]
pop
retfie FAST

Das FAST nutzt ein schnellspeichern von W, PCLATH, etc. Bei manchen alten Revisisionen der PIC ist ja noch ein Bug, dass man die Kombination FAST und POP nutzen muss. Ich glaube, das ist aber größtenteils behoben, sodass es auch ohne gehen sollte. Wichtig ist jedoch, dass die ISR mit einem CALL aufgerufen wird, und nicht über ein GOTO !!!

Gruß
Stefan
Gespeichert

deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #7 am: Mai 28, 2008, 09:59:18 »

so ... habs nu soweit abgeändert, wie ihr mir das empfohlen habt, aber leider keine besserung.

so sieht mein code jetzt aus:
Code: (asm)
List p=18F2550
#include <P18F2550.inc>

CONFIG     PLLDIV = 2
CONFIG     PWRT = ON
CONFIG     BOR = OFF
CONFIG     WDT = OFF
CONFIG     LVP = OFF

loops equ 0x31
loops2 equ 0x32
loops3 equ 0x33
merker equ 0x34
counter1 equ 0x35
counter2 equ 0x36
loops4 equ 0x37
loops5 equ 0x38
clock1 equ 0x39
clock2 equ 0x40
clock3 equ 0x41
loops6 equ 0x42
loops7 equ 0x43
al4rm equ 0x44

org 0
goto main

;Interrupt

org 8
call RTCisr,FAST

main

movlw B'10100000'
movwf INTCON

bsf INTCON,GIEH

bsf T1CON,T1RUN

;############ RTC Init ######################

RTCinit
MOVLW 80h ; Preload TMR1 register pair
MOVWF TMR1H ; for 1 second overflow
CLRF TMR1L
MOVLW b'00001111' ; Configure for external clock,
MOVWF T1CON ; Asynchronous operation, external oscillator
CLRF clock3 ; Initialize timekeeping registers
CLRF clock2
MOVLW d'12'
MOVWF clock1
bsf PIE1,TMR1IE ; Enable Timer1 interrupt

lauf
goto lauf

. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .

RTCisr
BSF TMR1H, 7 ; Preload for 1 sec overflow
BCF PIR1, TMR1IF ; Clear interrupt flag56
INCF clock3, F ; Increment seconds
MOVLW d'59' ; 60 seconds elapsed?
CPFSGT clock3
RETFIE ; No, done
CLRF clock3 ; Clear seconds
INCF clock2, F ; Increment minutes
MOVLW d'59' ; 60 minutes elapsed?
CPFSGT clock2
RETFIE ; No, done
CLRF clock2 ; clear minutes
INCF clock1, F ; Increment hours
MOVLW d'23' ; 24 hours elapsed?
CPFSGT clock1
RETFIE ; No, done
MOVLW d'01' ; Reset hours to 1
MOVWF clock1

POP
RETFIE FAST ; Done

welche funktion BSF TMR1H, 7 ; weiß ich nicht genau. es erhöht den tmr1 halt. der code stammt aus dem datenblatt des 18f2550. ist für eine RTC.

das GIEH hatte ich gesetzt. habs nur vergessen mit einzufügen bzw. habs aus versehen rausgeschnitten beim kopieren hier ins board.
movlw b'10100000'
movwf INTCON
hatte ich drin.
habe jetzt auch das ISR mit einem call aufgerufen und das FAST angefügt.
endlosschleife war vorher auch schon drin. hatte ich ebenfalls vergessen.

ansonsten ist nun alles, was der initialisierung und dem interrupt dient, hier im aktuellen code. leider läuft es immernoch nicht im simulator.

bzw. vielleicht teste ich ja auch falsch.
ich starte das programm und warte, bis es in der endlosschleife hängt. dann setzte ich in TMR1H und TMR1L alle bits und bringe über die beiden pins, wo der oszillator dran ist (PORTC0 und 1) den TMR1 zum überlaufen. das TMR1F bit im PIR1 register wird dann auch gesetzt.
aber immernoch kein interrupt.
« Letzte Änderung: Mai 28, 2008, 10:09:23 von deathks » Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #8 am: Mai 28, 2008, 10:07:29 »

Du brauchst zu jeder Abbruchbedingnung das POP und das RETFIE,FAST, wenn du FAST verwendest. Versuche es mal ohne, also FAST und POP weg, denn in den neueren Erratas steht nichts mehr von dem Bug.
Läuft der Timer1 Oszillator überhaupt? Mal mit OSZI oder Frequenzmesser geprüft? Wie stellst du überhaupt fest, dass dein Code nicht geht, so ohne jede Form von Ausgabe?
Uch würde INTCON, GIEH als letztes einschalten, das ist nämlich der "Hauptschalter" für alle Interrupts.
Gespeichert

deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #9 am: Mai 28, 2008, 10:21:30 »

ja das ganze programm enthält noch viele I²C routinen ... etc.. am ende solls halt eine komplette Uhr sein, die auf einer 8x16 LED matrix angezeigt wird. und die matrix wird per I²C bus angesteuert.

lies bitte nochmal meinen letzten post. da hab ich einmal beschrieben, wie ich das teste.

der oszillator funktioniert. habe das mit einem oszilloskop gemessen. die ganze platine funktioniert auch. inklusive I²C bus und der LED matrix.
nur erst im nachhinein kam mir die idee dass eine uhr per interrupt genauer ist, als mit endlosen warteschleifen Zwinkernd
Gespeichert
Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 969



Profil anzeigen WWW
« Antworten #10 am: Mai 28, 2008, 10:57:24 »

Zitat
leider läuft es immernoch nicht im simulator
Der Simulator baut manchmal Mist, da hilft nur testen in der echten Schaltung.

Dann kann ich dich noch auf das Errata des Timer1 verweisen: http://ww1.microchip.com/downloads/en/DeviceDoc/80329a.pdf (vgl Example 2)
Möglicherweise ist das der Grund, dass der Interrupt nicht erkannt wird. Ob das Problem auch für Timer3 zutrifft (der ja auch mit dem T1OSC arbeiten kann) weiß ich nicht.
Die fehlenden POP's in der ISR hast du eingefügt?
Gespeichert

deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #11 am: Mai 28, 2008, 11:00:56 »

mh nee habe jetzt alle POPs und FAST rausgenommen, wie du gesagt hattest.

am code selber kannst du keine fehler mehr entdecken oder?
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #12 am: Mai 28, 2008, 23:12:48 »

Zitat
das TMR1F bit im PIR1 register wird dann auch gesetzt. aber immernoch kein interrupt.

Wenn das IPEN-Bit im RCON Register nicht gesetzt ist, zählt der Timer1-Interrupt zu den Peripheral-Interrupts, d.h. GIE und PIE im INTCON-Register müssen gesetzt werden, damit ein Interrupt ausgelöst wird.


Viele Grüße

Bernd
Gespeichert

deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #13 am: Juni 02, 2008, 06:58:22 »

jaa L&#228;chelnd das war der entscheidende hinweis. jetzt läuft (zumindest softwareseitig) alles.
vielen dank an alle.
Gespeichert
deathks
Newbie
*
Offline Offline

Beiträge: 19


Profil anzeigen
« Antworten #14 am: Juni 02, 2008, 10:15:23 »

ahh vielleicht doch noch ein kleines problem.

jetzt läuft alles. interrupt, anzeige, alles bestens. nur der quarz ist irgendwie sehr ungenau.
wir benutzen einen 32,768 kHz quarz mit 2 x 18 pF kondensatoren. und der timer läuft ohne vorteiler schon bei ca. 55 sekunden über.
« Letzte Änderung: Juni 02, 2008, 10:22:51 von deathks » Gespeichert
Seiten: [1] 2 Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.057 Sekunden mit 19 Zugriffen.
 
Top! Top!