Hallo zusammen, ich arbeite mit PIC18F4550 MPLAB und Compiler C mit frequenz 20MHz. und en Takt brauch 02µS aber mein Programm scheint nicht zu funktionnieren. so sieht es aus: #include "Test.h" #include <p18F4550> unsigned int task0_counter=0; unsigned int task1_counter=0; unsigned int task2_counter=0; #define TASK0_COUNTER_MAX 100 #define TASK1_COUNTER_MAX 200 #define TASK2_COUNTER_MAX 500 //100*200*500*0.2µS=2S void interrupt(unsigned char PORTBbitsRB1, unsigned char PORTDbitsRD0) { T1CONbits.TMR1ON=1; T1CONbits.TMR1CS=0; T1CONbits.T1SYNC=1; T1CONbits.T1OSCEN=1; T1CONbits.T1CKPS0=1; T1CONbits.T1CKPS1=1; T1CONbits.T1RUN=1; T1CONbits.RD16=0; PIR1bits.TMR1IF=1; PIR1bits.CCP1IF=1; PIR1bits.SSPIF=1; if(task0_counter > TASK0_COUNTER_MAX) { task1_counter++; if(task1_counter > TASK1_COUNTER_MAX) { task2_counter++; if(task2_counter > TASK2_COUNTER_MAX) { task0_counter++; } } if((task0_counter == TASK0_COUNTER_MAX)&&(task1_counter == TASK1_COUNTER_MAX)&&(task2_counter == TASK2_COUNTER_MAX)) { PORTBbits.RB1=PORTDbits.RD0; task0_counter=0; task1_counter=0; task2_counter=0; } } } void main () { TRISB=0; TRISD=0x0F; while(1) { interrupt(PORTBbits.RB1,PORTDbits.RD0); PORTBbits.RB1=PORTDbits.RD0; } } aber es funktioniert nicht. Hilfe
wie immer wenn man keine Antwort kriegt: Einfach nur den Code zu posten ist einfach zu wenig! Sollen wir jetzt raten was Du machen willst???
Hallo das ist noch das code #include "Test.h" #include <p18F4550> unsigned int task0_counter=0; unsigned int task1_counter=0; unsigned int task2_counter=0; #define TASK0_COUNTER_MAX 100 #define TASK1_COUNTER_MAX 200 #define TASK2_COUNTER_MAX 500 //100*200*500*0.2µS=2S void interrupt(unsigned char PORTBbitsRB1, unsigned char PORTDbitsRD0) { T1CONbits.TMR1ON=1; T1CONbits.TMR1CS=0; T1CONbits.T1SYNC=1; T1CONbits.T1OSCEN=1; T1CONbits.T1CKPS0=1; T1CONbits.T1CKPS1=1; T1CONbits.T1RUN=1; T1CONbits.RD16=0; PIR1bits.TMR1IF=1; PIR1bits.CCP1IF=1; PIR1bits.SSPIF=1; if(task0_counter > TASK0_COUNTER_MAX) { task1_counter++; if(task1_counter > TASK1_COUNTER_MAX) { task2_counter++; if(task2_counter > TASK2_COUNTER_MAX) { task0_counter++; } } if((task0_counter == TASK0_COUNTER_MAX)&&(task1_counter == TASK1_COUNTER_MAX)&&(task2_counter == TASK2_COUNTER_MAX)) { PORTBbits.RB1=PORTDbits.RD0; task0_counter=0; task1_counter=0; task2_counter=0; } } } void main () { TRISB=0; TRISD=0x0F; while(1) { interrupt(PORTBbits.RB1,PORTDbits.RD0); PORTBbits.RB1=PORTDbits.RD0; } } ich moechte gern ein Verzögerung für ein Clock von z.B 2S realisiert ohne for und while (ausser main Programm)
hallo im Anhang ein Beispielcode für den Pic18F1320 mit Interrupt auf Timer1 gerhard
@rapeur Ähm, also eine kleine Erläuterung wäre ganz nett, es ist absolut unverständlich was das Programm tun soll - und auch in C schreibt man immer mit Kommentar... ;-) Also erstmal ist die Routine "interrupt" keine echte Interrupt-Routine, sondern ein schlecht gewählter name. Geht das überhaupt durch den Compiler? Braucht der PIC nicht ein bisl mehr initialisierung?
>Wird beim PIC eine Interrupt-Serviceroutine als normale C-Funktion >aufgerufen??? >Hallo >Ja >Gruß Hallo Jein, siehe Gerhard. In der main-loop ruft man sie nicht auf. Gruß
Hallo Kommutator, ich moechte gern eine funktion mit verzögerung realisiert. nehmen wir ich duch den Clock das macht PORTBbits.RB1=PORTDbits.RD0; den Port B1 enthalt 2S später den wert von Port D0. ich habe realisiert mit ein For schleife aber für das Programm pass nicht gut, deshalb wurde ich empfehlen mit interrupt zu machen. das problem ist ich habe noch nicht ein interrupt bearbeiten deshalb ist es neu für mich.ich moechte gern dass , die verzögerung kein einfluss auf das gesamte Programm nur wo ich will.und das ist das problemm. interrupt ist neu fur mich Gruß
Also, in der INT-Routine wird der Timer0 gestartet und versch. INT-Flags gesetzt (kann die Software gar nicht, geht nur in Hardware). Die INT-Enable-Bits werden nirgends gesetzt. In der Int-Routine werden 3 Zähler nacheinander hochgezählt. Erst Task0_Counter bis er über 100 ist. Ab dann wird bei jedem Durchlauf Task1_Counter hochgezählt, bis er 200 erreicht, ab dann wird Task2_Counter hochgezählt, bis er 500 erreicht, weil dann Task0_Counter weitergezählt wird. Die IF-Bedingung wird eigentlich nie erfüllt. Was soll das ganze ? Wozu brauchst Du den Timer0 ? Was hat das mit 20MHz zu tun ?
Hallo, ich sollte nur einfach und ich habe ein test Platine wo ich überprüfen kann. Und bei mein Test platine kann ich nicht die verzögerung merken. 20MHz ist die Frequenz von Quartz. Warum wird die IF bedingungen nicht erfüllt? Ich brauche Timer und ein Verzögerung zu realisiert.
Haste bei deiner Entwicklungsumgebung keinen Debugger? Wenn du das Programm auf einen bestimmten Pic laufen lassen willst brauchste außerdem einen Simulator. Lötkünstler <Mit der Lizenz zum löten>
Hallo Das MPLAB hat einen Debbuger, aber ich habe noch nicht benutzt. ich habe immer mit Oscilloscope gemessen. Aber wenn mann ein Verzögerung von 2S hat, kann man auf Platine merken oder? Rapeur
Das Programm muß erst mal Fehlerfrei arbeiten,sonst haben Messungen
keinen
Sinn,außerdem kann man mit dem normalen Oszilloskop nur periodische
Signale messen.Debugging/Simulation ist jedenfalls der vernünftigere Weg
Fehler zu finden.Ich würde mich mal angewöhnen das Programm zu
kommentieren weil
es sonst nur schwer nachvollziehbar ist.
>void interrupt(unsigned char PORTBbitsRB1, unsigned char PORTDbitsRD0)
ist die Syntax ohne Trennungspunkte korrekt (PORTBbits.RB1 ?)
Fiel mir nur auf.
Mehr kann ich leider nicht dazu beitragen.
Lötkünstler
<Mit der Lizenz zum löten>
Wie wird in deutschland eigendlich kommentiert? - Ausschließlich englisch oder ist es abhängig von der Firmenphilosophie?
Die Kommentierung soll ein Nachvollziehen des Programms erleichtern. Wenn man nach einer gewissen Zeit Änderungen durchführen will sind sinnreiche Kommentare hilfreich und Kollegen sind dann Dankbar wenn die diese Ausgabe übernehmen müssen. Bei Nationalem Gebrauch in der Landessprache sonst englisch. Lötkünstler <Mit der Lizenz zum löten>
in der main-Funktion von dir rufst du den interrupt auf, als wenn es eine Funktion wäre.... Das geht so nicht!!! Ein Interrupt ist immer unter gewissen Bedinungen aufgerufen! z.B. Wenn ein Flankenwechsel an einem PIN oder ein Timerüberlauf stattgefunden haben. Dann wird das Programm(egal, welche zeile gerade abgearbeitet wird) unterbrochen und es wird der code an der stelle des Interrupts ausgeführt. Danach springt der Ablauf dann wieder an die Stelle im Programm, wo er geendet(interrupted) hat. außerdem solltest du dir noch mal die counter angucken, weil das so nicht läuft! ich würde das nach folgendem prinzip aufbauen: unsigned counter bis maximalen wert zählen lassen, bei maximalem wert nächsten counter inkrementieren. So ist sichergestellt, dass der zweite counter immer periodisch!!! inkrementiert wird, das ist so bei dir nicht der fall!
Siehe im Beitrag von karlheinz buchegger (moderator) Beitrag "Große Zahl aus drei Variablen" Da sind es 8-bittige unsigned Vars
Also, zunächst kann ich mir nicht verkneifen mich den vorangegangenen Kommentaren anzuschließen! Was musst Du machen: a) Test den Code in MPLAB, indem Du den den Debugger->select Tool->MPLAB SIM einstellst. Dann kannst Du schritt für schritt dein Programm ausführen lassen. b) der neu zu schreiben. Vorschlag für die Implementierung: Nimm den Timer1 um die Verzögerung zu realisieren per interrupt-betrieb. Nimm einen zweiten interrupt der ausgelöst wird, wenn der Pegel sich am gewünschten Eingang verändert (Dazu musst du evtl. den Port B nehmen), initialisiere und starte dann den timer. Läuft der Timer ab, löst er den timer-interrupt aus der den Wert ausgibt und den timer-interrupt wieder abdreht. Wenn Du jetzt eine 2S Verzögerung haben willst, wirds zusätzlich komliziert, denn dann musst du jede Änderung innerhalb der 2S abspeichern, d.h. einen Zeitstempel wann sich das Signal verändert hat. Wenn Du nur ein langsam änderndes Signal am Eingang hast, also seltener als 2S kannst Du dir das sparen. Und dann ist da noch das Problem wenn das Eingangssignal nicht ganz sauber ist ....
ich habe noch so gebasteln. keine fehler aber funktionniert nicht #include <p18F4550.h> #include <stdio.h> #include <delays.h> unsigned char counter ; void main () { TRISB=0; TRISD=0x07; INIT(); // Timer0_isr(); while(1) { INIT(); if(INTCONbits.T0IF) { ++counter; PORTDbits.RD4=PORTDbits.RD0; //PORTBbits.RB1=delay(PORTDbits.RD0); PORTBbits.RB1=delay(PORTDbits.RD0); //INTCONbits.T0IF=0; } } } #include "Test.h" #include <p18F4550.h> unsigned char task0_counter=0; #define TASK0_COUNTER_MAX 8000000 //unsigned char counter; //counter variable to count // the number of TMR0 overflows unsigned char counter1 ; void INIT(void) { // TMR0=0; //Clear the TMR0 register TMR0H=20; // Configure Timer0 T0CONbits.TMR0ON=0; T0CONbits.T08BIT=0; T0CONbits.T0CS=0; T0CONbits.T0SE=1; T0CONbits.PSA=1; T0CONbits.T0PS2=1; T0CONbits.T0PS1=0; T0CONbits.T0PS0=0;//1:32 Prescale value INTCONbits.T0IF=1; if(INTCONbits.T0IF) { task0_counter++; // zahl bis TASK0_COUNTER_MAX } } void Timer0_isr(void) { INTCONbits.INT0IE=1; INTCONbits.INT0IF=1; INTCONbits.GIE=1; if(INTCONbits.T0IE && INTCONbits.T0IF) { INTCONbits.T0IF=0; // zahl bis 255 und incrementieren counter ++counter1; } } char delay(unsigned char PORTDbitsRD0) { Delay10KTCYx(200); return PORTDbitsRD0; hilfe
>hilfe
Du stocherst blind rum. So geht das nicht.
Beim mcc18 ist doch ein Beispiel für
TMR0 Interrupt dabei.
Siehe Anhang.
Hallo Zusammen ich bedanke mich für ihre Beitrage ich habe noch so Probiert und es funktionniert immer noch nicht. das ist mein neues Code #include <p18F4550.h> unsigned float task0_counter=0; unsigned float task1_counter=0; #define TASK0_COUNTER_MAX 250 #define TASK1_COUNTER_MAX 250 void Timer0_isr(void) { T0CONbits.TMR0ON=1; T0CONbits.T08BIT=1; T0CONbits.T0CS=1; T0CONbits.T0SE=0; T0CONbits.PSA=0; //Prescaler T0CONbits.T0PS2=1; T0CONbits.T0PS1=1; T0CONbits.T0PS0=1; //256:1 if(INTCONbits.T0IF) {//watre Zeit von TASK0_COUNTER_MAX*TASK1_COUNTER_MAX*51,2µ task0_counter++; // zahl bis TASK0_COUNTER_MAX if(task0_counter == TASK0_COUNTER_MAX) { task1_counter++; //zahl bis TASK1_COUNTER_MAX if(task1_counter == TASK1_COUNTER_MAX) { // task1_counter=0; //INTCONbits.T0IF=0; } } } task0_counter=0; task1_counter=0; // PORTBbits.RB4^=1; } void Timer0_ISR(void) { INTCONbits.T0IE=1; INTCONbits.T0IF=1; RCONbits.IPEN=1; INTCONbits.GIE=1; INTCONbits.PEIE=1; INTCONbits.RBIE=0; INTCONbits.TMR0IE=1; RCONbits.TO=0; RCONbits.PD=0; if((INTCONbits.T0IE)&&(INTCONbits.T0IF)) { INTCONbits.T0IE=0; if(INTCONbits.GIE==1) { } } } void main () { TRISB=0; TRISD=0xFF; INIT(); TMR0L=131; while(1) { } } Port D4 sollte blinken mit 2s Verzögerung.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.