Archiv verlassen und diese Seite im Standarddesign anzeigen : PortB Interrupt bei PIC18FSerie
Hallo,
Ich bin grade dabei mich mit den Pics vertraut zu machen und habe da ein paar nette Lernbeispiele im Netz gefunden. Nur die sind fast alle für den PIC16. Ich benötige allerdings den PIC18F2550.
Die meisten Beispiele sind ohne große Schwierigkeiten übertragbar, allerdings versuch ich jetzt schon geraume Zeit einen Interrupt auszulösen. Ohne Erfolg.
Kann mir bitte jemand weiterhelfen?
Momentan hab ich folgendes in meinem Programm:
Main:
goto Interrupt
;goto Polling
;goto Buzzer
;goto Blinklicht
;goto Lauflicht
; Interrupt für RA4
Interrupt
movlw b'11110000' ;PortB = Ausgang(0-3)/Eingang(4-7)
movwf TRISB
movlw 0x00
movwf PORTB
clrf INTCON ; GIE aus
bsf INTCON, RBIE ; RBIF kann wecken
; pull-up ein
bcf INTCON, RBIF
intvec
nop
goto intvec
intvector
movlw 0xFF
movwf PORTB
bcf INTCON, INT0IF
retfie
Die intcon register dürften allerdings falsch gesetzt sein, denn wenn den RB4 nach unten ziehe passiert genau garnix!
Ich bitte um Hilfestellung...
Danke!
Michi
Meine Erfahrungen sind allerdings auch eher PIC16F...
allerdings glaub ich, daß auch die 18F.. die Spec.Func.Register in verschiedenen Banks hat.
Wenn es so ist, mußt du deine Init-Routinen in der richtung mal überprüfen.
Ich werd' mir mal so ein Datenblatt anschauen, dann bin ich vielleicht schlauer.
clrf INTCON ; GIE aus
hum... Also bei deinem Testprogramm ist mir grad eines aufgefallen. DU löscht intcon und setzt dann RBIE, aktivierst aber den Globalen Interrupt nicht wieder. Meine bevorzugten Chip sind auch die aus der 16F-Reihe, doch glaub ich nicht, dass sie soooo anders wären, dass man den GIE nicht mehr setzten müsste, damit ein Interrupt auftritt.
Versuch mal auch die Zeile "bsf INTCON,GIE" hineinzugeben, vielleicht hilft es ;). Ansonsten, beim 18F ha man ja 2 Interrupt-Vektoren, das kann auch eine Quelle für Fehler sein (falsche Priority eingestellt), aber, ka, wie das geht.
MfG
Mobius
€dit: Aja, ansonsten, weitere Fehlerquellen sind wie immer, Analogeingänge, Comparator, alle anderen "Module" des PICs, die mit den einzelnen Pins gemuxt sind.
Moin Moin,
bei dem PIC habs selbst noch nicht gemacht aber Datenblatt gelesen und da musst ja erstmal sämtliche Interrupts enable und es gibt 2 interrupt adressen für high und low priority
banks gibts nicht mehr bei 18F.... darauf musst nicht schauen
aber an PORTB können 3 Interrupts sein musst da noch die Channel einstellen usw da steht viel im Datenblatt zu
wenn ich da mal weiter mache kann dir meine initialisierung mal schicken iss aber noch nich getestet versuche mich grad ersma ne runde in java damit ich für den selben Prozessor ne Software schreiben kann die dann mit USB mit dem PIC Kommunizieren kann
MfG Daniel
Meiner Meinung nach sollte folgendes Programm funktionieren:
Main:
goto Init
intvec
movf PORTB
movwf test
btfsc test, 1 ;Led invertieren
goto aus
goto ein
aus ;Led aus
bcf PORTB,1
bsf INTCON, GIE ; Interupt generell erlauben
bcf INTCON, RBIF ; RBIF zurücksetzen (Interrupt erneut erlauben)
retfie
ein ;Led ein
bsf PORTB,1
bsf INTCON, GIE ; Interupt generell erlauben
bcf INTCON, RBIF ; RBIF zurücksetzen (Interrupt erneut erlauben)
retfie
;************************************************* *************
; das Hauptprogramm
Init
; RB0-Interrupt einstellen
movlw b'11111101' ;LED 1 = Ausgang (Rest = Eingang)
movwf TRISB
movlw 0x00
movwf INTCON
bsf INTCON, RBIE ; RBIF kann wecken
bsf INTCON, GIE ; Interupt generell erlauben
loop goto loop
Leider ist der PIC anderer Meinung... [-X
Ich werd' also weiter probieren müssen
lg
Michi
Also, da die Frage, wieso das nicht geht, mich auch interessiert, hab ich dein Programm mal durch den Simulator vom MPLab gejagt. Hier sind die Fehler:
bsf INTCON, GIE ; Interupt generell erlauben
Der Fehler liegt in dieser Zeile. Du darfst in einem Interrupt den GIE NICHT setzten, bevor du den Flag gelöscht hast, weil ansonsten sofort wieder ein Interrupt ausgelöst wird (und du wieder an den Anfang des Interrupts springst --> Unendlichschleife). Überhaupt, wieso setzt du ihn manuell? Der Befehl retfie macht das für dich automatisch ;).
Ansonsten, ziehst du die Pins gegen GND zum Auslösen des Interrupts? Weil dann musst du die internen Pull-Ups des µC einschalten (oder aber die Pins exterm mit Winderständen nach Vcc ziehen). Ach, ja, nur die Pins RB 4-7 haben die Möglichkeit einen Interrupt auszulösen.
MfG
Mobius
P.S.: Hab das Projekt, mit dem ich es getestet habe, als zip beigefügt. Der Stimulus funktioniert nur bedingt (Toggle, also es invertiert den besagten Pin), weil ich wegen den Einschränkungen des Simulators (Weak pull-ups on ports not implemented) ein nach-GND-ziehen nicht simulieren kann.
€dit: für alle, die die zip nicht herunterladen wollen, hier ist die src ;)
;************************************************* *****************************
; This file is a basic template for assembly code for a PIC18F2550. Copy *
; this file into your project directory and modify or add to it as needed. *
; *
; The PIC18FXXXX architecture allows two interrupt configurations. This *
; template code is written for priority interrupt levels and the IPEN bit *
; in the RCON register must be set to enable priority levels. If IPEN is *
; left in its default zero state, only the interrupt vector at 0x008 will *
; be used and the WREG_TEMP, BSR_TEMP and STATUS_TEMP variables will not *
; be needed. *
; *
; Refer to the MPASM User's Guide for additional information on the *
; features of the assembler. *
; *
; Refer to the PIC18Fx455/x550 Data Sheet for additional *
; information on the architecture and instruction set. *
; *
;************************************************* *****************************
; *
; Filename: *
; Date: *
; File Version: *
; *
; Author: *
; Company: *
; *
;************************************************* *****************************
LIST P=18F2550 ;directive to define processor
#include <P18F2550.INC> ;processor specific variable definitions
;************************************************* *****************************
;Configuration bits
; The __CONFIG directive defines configuration data within the .ASM file.
; The labels following the directive are defined in the P18F2550.INC file.
; The PIC18FX525/X620 Data Sheet explains the functions of the
; configuration bits.
__CONFIG _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_1_1L
__CONFIG _CONFIG1H, _FOSC_HS_1H & _FCMEM_ON_1H & _IESO_OFF_1H
__CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_OFF_2L & _BORV_46_2L & _VREGEN_OFF_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_1_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_OFF_3H
__CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L
__CONFIG _CONFIG6H, _WRTB_OFF_6H & _WRTC_OFF_6H & _WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H & _DEVID1 & _IDLOC0
;************************************************* *****************************
;Reset vector
; This code will start executing when a reset occurs.
ORG 0x0000
goto Main ;go to start of main code
;************************************************* *****************************
;High priority interrupt vector
; This code will start executing when a high priority interrupt occurs or
; when any interrupt occurs if interrupt priorities are not enabled.
ORG 0x0008
bra HighInt ;go to high priority interrupt routine
;************************************************* *****************************
;High priority interrupt routine
; The high priority interrupt code is placed here to avoid conflicting with
; the low priority interrupt vector.
HighInt:
btfsc PORTB, 1 ;Led invertieren
goto aus
goto ein
aus ;Led aus
bcf PORTB,1
; bsf INTCON, GIE ; Fehler, damit löst du einen erneuten Interrupt aus.
bcf INTCON,RBIF
retfie
ein ;Led ein
bsf PORTB,1
; bsf INTCON, GIE ; Fehler, damit löst du einen erneuten Interrupt aus.
bcf INTCON,RBIF
retfie
;************************************************* *****************************
;Start of main program
; The main program code is placed here.
Init
; RB0-Interrupt einstellen
movlw b'11111101'
movwf TRISB
bcf INTCON2,RBPU ;Interne Pullups aktivieren
clrf INTCON ; ist das gleiche wie movlw 0x00 und anschließend movfw INTCON
bsf INTCON, RBIE
bsf INTCON, GIE
return
Main:
call Init
loop
goto loop
;************************************************* *****************************
;End of program
END
Hey, jetzt funktionierts!!!
Besten Dank und schöne Grüße!!!
Michi
Hallo,
Ich hab noch ein bischen Totzeit eingebaut, dammit das ein - ausschalten auch wirklich "smooth" funktioniert und einen Register für den Zustand im PortB (Das direkte auslesen des PortB funktioniert aus irgendeinem Grund nicht).
Vielleicht steht ja jemand vor dem selben Problem, dann kann er ja den Code hier ganz gut gebrauchen...
CODE
HighInt:
btfsc test, 1 ;Led invertieren
goto aus
goto ein
aus ;Led aus
call totzeit ;Damit das ganze nicht so empfindlich ist :)
bcf PORTB,1
bcf test,1
bcf INTCON,RBIF ;Interruptflag löschen
retfie
ein ;Led ein
call totzeit ;Damit das ganze nicht so empfindlich ist :)
bsf test,1
bsf PORTB,1
bcf INTCON,RBIF ;Interruptflag löschen
retfie
;************************************************* *****************************
;Low priority interrupt routine
; The low priority interrupt code is placed here.
; This code can be removed if low priority interrupts are not used.
LowInt:
movff STATUS,STATUS_TEMP ;save STATUS register
movff WREG,WREG_TEMP ;save working register
movff BSR,BSR_TEMP ;save BSR register
; *** low priority interrupt code goes here ***
movff BSR_TEMP,BSR ;restore BSR register
movff WREG_TEMP,WREG ;restore working register
movff STATUS_TEMP,STATUS ;restore STATUS register
retfie
;************************************************* *****************************
;Start of main program
; The main program code is placed here.
;************************************************* *************
; das Hauptprogramm
Init
; RB0-Interrupt einstellen
movlw b'11111101'
movwf TRISB
movlw b'00000000'
movwf PORTB
bcf INTCON2,RBPU ;Interne Pullups aktivieren
clrf INTCON ;ganzes INTCON löschen
bsf INTCON, RBIE ;enables PortB Interrupts
bsf INTCON, GIE ;global interrupt enable
return
totzeit
movlw 0xFF
movwf bigcount
bigloop
decfsz bigcount
goto weiterloop
return
weiterloop
movlw 0xFF
movwf smallcount
smallloop
decfsz smallcount
goto smallloop
goto bigloop
Main:
call Init
loop
goto loop
; *** main code goes here ***
;************************************************* *****************************
;End of program
END
Moin Moin,
arbeite nun auch mit dem 18F2550.
Will mit dem PC bissel über USB Kommunizieren.
Im mom klappt aber nichtmal das brennen bzw sagt er so 43 Fehler im Programm (beim ersten mal hats geklappt)
hab eigentlich kein codeprotection drin und wenn sollte ja löschen
hattest das problem auch mal ? benutze P18 Software und Brenner 3
hast du externen oszillator ?
hab quarz erst bestellt und wollte es mit dem internen testen aber das klappt nicht so recht
hab programm geschrieben das eigentlich nur alle ports auf high setzen soll
hast du vielleicht lust sonst dein ganzen programm mal zu posten oder mir zu schicken mit config ? bekomme bald quarze die sind bestellt (20MHz) dann werde mir auch das Sprut Beispiel mal zu Herzen nehmen
MfG der Daniel
Hallo GHigh,
Ich zwar bin ein ziemlicher Neuling was Microcontroller angeht. Beschäftige mich jetzt bei einem Projekt damit zum ersten mal damit (und das gleich mit dem PIC18F2550). Ich werd dir aber helfen wo ich kann.
Ich verwende das PICDem 2 Plus Board mit incircuit Debuger. Das kostet zwar ne ordentliche Stange Geld, aber ohne dem wär' ich vermutlich aufgeschmissen. Vorallem das Onlinedebuggen ist zum kennenlernen reinstes Gold wert!!!
Momentan verwende ich auch noch den Standard eingestellten Oszillator (Intern) für meine Spielereien. Bald wird aber auch noch ein etwas flotterer externer dazukommen weil ich dann auch die USB Schnittstelle damit ansteuern möchte und dann das Gerät an den PC anschließen möchte. Hast du dir schon mal überlegt wie das funktionieren kann?
Ich verwende folgende Literatur: ISBN 3-8266-0698-1
Ist ziemlich trockenes Material und anstrengend zum lesen, aber wenn du was besseres (vielleicht sogar in Bezug auf PIC18F2550) findest bin ich sehr daran interessiert.
Anbei findest du ein paar Demoprojekte die ich zu Übungszwecken für den PIC18F2550 entwickelt habe. Mit dem Semikolon kannst du zwischen den einzelnen Programmen wechseln.
Es wär toll, wenn wir unsere Email-Adressen tauschen könnten und gewisse Hürden gemeinsam meistern könnten.
Schöne Grüße,
Michi
PS: Schick mir einfach eine Mail auf diese Adresse:
stroi(Klammeraffe)aon.at
Hey Michi,
beschäftige mich mit PICs ca. 1 Jahr.
Habe paar kleinere Projekte gemacht bissel Spannungsmessung LCD One-Wire Chip auslesen und so Spielereien hauptsächlich mit 16F628 und 16F819 mit AD Wandler.
Ist auch mein erster 18F will auch mit USB kommunizieren wie ich mir dsa vorstellt habe ... naja erstmal werde ich noch versuchen den Bootloader von Microchip auf den PIC zu bekommen und dann in Java oder so ne Software schreiben mit der ich mit dem PIC kommunizieren kann.
Allerdings komme ich mit Java API für Windows nich so klar.
Oder ich schaue mir C an ist ja alles "recht" ähnlich.
Und C lohnt sich ja auch für PICs weil Bootloader und USB Firmware komplett in C geschrieben ist von Microchip.
Kann übrigens brennen (lag am Brenner hab nun meinen guten alten genommen ^^ ) allerdings bekomme ich nen Rechteck an dem Pin heißt das der Interrupt sich immer wieder setzt sobald ich ihn einmal gesetzt habe...
Habe auch mal verzögerung eingebaut aber das macht die Frequenz des Rechtecks nur kleiner ^^
LIST P=18F2550, R=DEC ; Use the PIC16F819 and decimal system
#include <P18f2550.INC>
;************************************************* *****************************
;Variable definitions
; These variables are only needed if low priority interrupts are used.
; More variables may be needed to store other special function registers used
; in the interrupt routines.
CBLOCK 0x080
WREG_TEMP ;variable used for context saving
STATUS_TEMP ;variable used for context saving
BSR_TEMP ;variable used for context saving
loops
loops1
loops2
ENDC
CBLOCK 0x000
EXAMPLE ;example of a variable in access RAM
ENDC
org 0x00
goto Init
;************************************************* *****************************
;High priority interrupt vector
; This code will start executing when a high priority interrupt occurs or
; when any interrupt occurs if interrupt priorities are not enabled.
ORG 0x0008
bra HighInt ;go to high priority interrupt routine
;************************************************* *****************************
;Low priority interrupt vector and routine
; This code will start executing when a low priority interrupt occurs.
; This code can be removed if low priority interrupts are not used.
ORG 0x0018
movff STATUS,STATUS_TEMP ;save STATUS register
movff WREG,WREG_TEMP ;save working register
movff BSR,BSR_TEMP ;save BSR register
; *** low priority interrupt code goes here ***
movff BSR_TEMP,BSR ;restore BSR register
movff WREG_TEMP,WREG ;restore working register
movff STATUS_TEMP,STATUS ;restore STATUS register
retfie
;************************************************* *****************************
;High priority interrupt routine
; The high priority interrupt code is placed here to avoid conflicting with
; the low priority interrupt vector.
HighInt:
btfsc PORTA, 0 ;Led invertieren
goto aus
goto ein
aus ;Led aus
bcf PORTA,0
bcf INTCON,RBIF
call verz
retfie
ein ;Led ein
bsf PORTA,0
bcf INTCON,RBIF
call verz
retfie
Init
;Frequenzeinstellung
; movlw B'00001111' ;Maximum Frequency Tuning
; movwf OSCTUNE
movlw B'01100010' ;4 MHz System/Clock Internalt Osc/
movwf OSCCON
clrf PORTA
movlw 0x0F
movwf ADCON1 ;A/D auf Digital
movlw 0x07 ;Komperator aus
movwf CMCON
clrf TRISA
movlw B'00000010'
movwf TRISB
clrf TRISC
movlw B'11001000'
movwf INTCON
bsf INTCON2,RBIP
bcf INTCON2,RBPU
movlw B'01001000'
movwf INTCON3
Main
goto Main
; ---------------
; Verzögerung Einstellbar 250ms
; ---------------
verz movlw 4 ; einstellbar 1 = 250ms 4 = 1s
movwf loops
verz2 movlw 250
movwf loops1
verz3 movlw 200
movwf loops2
verz4 nop
nop
decfsz loops2,1
goto verz4 ; verz4 loop = 5us
decfsz loops1,1
goto verz3 ; verz3 loop = 1000us
decfsz loops,1
goto verz2 ; verz2 loop = 250000us x verz1
return
end
Vielleicht fällt euch ja was auf
MfG der Daniel
Edit: Wird der Interrupt eigentlich ausgelöst sobald einer der RB0:4 sich ändern (falling edge also von 5V auf Masse) oder kann ich das einstellen mit dem INT0 INT1 .... enable/disable ?
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.