Hallo, im zuge einer Studienarbeit muss ich mich in den ARM Controller etwas einarbeiten und ein kleines Programm schreiben, was auch auf dem Board MCB2300 realisiert wird. Das Programm soll mittels Capture-Interrupts (Zwei Signale kommen von einer externen Sensorplatine) den Timerwert aus TC ins CR laden. den berechneten Wert (Temeratur und Atmosphärischen Druck) muss dann auf dem Display ausgegeben werden. Nun hab ich festgestellt, dass ich nie in eine isr reinkomme, und weiß aber nicht warum... vlt kann mir ja jemand helfen... hier mein Code (mit initialisierungen und Kommentaren): #include <stdio.h> #include <stdlib.h> #include <LPC23xx.h> // LPC23xx definitions #include "lcd.h" // Graphic LCD function prototypes #define referenz_T 25.8 // Bei 25,8°C war Zähler TMR1 auf ca. 15.100 (PIC) #define referenz_TMR1_T 15100. // -Rechnerisch bei 15.009 aus f=263,2Hz #define referenz_p 1015. // Bei 1015hPa war Zähler TMR1 auf 9082 (PIC) #define referenz_TMR1_p 9082. // -Rechnerisch bei 9087 aus f=1.76087kHz // Unterschied wegen Laufzeiten... __irq void temp_hisr (void); //Prototyp High-Interrupt-Service-Routine // Timer1 P0.23 Anschluss 13 an Buchsenleisten __irq void druck_lisr (void); //Prototyp Low-Interrupt-Service-Routine //Timer0 P0.4 Anschluss 116 an Buchsenleisten const float ref_T=referenz_TMR1_T*referenz_T; const float ref_p=referenz_p/referenz_TMR1_p; int time_T=0, time_p=0; int temp_vorkomma=0, temp_nachkomma=0, druck=0; const unsigned char einheit_T[16]="temp/°C: ", einheit_p[16]="druck/hPa: "; const unsigned char komma[2]=",", leer[5]=" "; char newValueFlag_T=0, newValueFlag_p=0; void init(void) { // LCD-Anzeige initialisieren LCD_init(); LCD_on(); LCD_cls(); LCD_gotoxy(1,1); //Spalte, Zeile LCD_puts ("temp/°C: "); LCD_gotoxy(1,2); //Spalte, Zeile LCD_puts ("druck/hPa: "); // Ein/Aus-Gänge festlegen PINSEL0 = 0x00000300; //CAP2.0 pin function select -->Input P0.4 (Druck) PINSEL1 = 0x00003000; //CAP3.0 pin function select -->Input P0.23 (Temperatur) //Für PINSEL1 J6(POT1) öffnen!!! // Interrupts Inititalisiern VICVectAddr4 = (unsigned long)temp_hisr; //Set Timer0(CAP0) interrupt vector VICVectAddr5 = (unsigned long)druck_lisr; //Set Timer1(CAP1) interrupt vector VICIntEnable = 0x00000030; //Timer0 und Timer1 Interrupt Enable VICVectCntl4 = 0xF; //Timer0 lowest priority -->Druck VICVectCntl5 = 0xE; //Timer1 higher priority -->Temperatur // Timer0 Initialisieren (auch capture-modul 2) T0TCR=1; //enables Timer0 T0CTCR=0; //Timer mode T0CCR=0x0140; //CR2 laden mit TC0, interrupt enabled on rising edge // Timer1 Initialisieren (auch capture-modul 3) T1TCR=1; //enables Timer1 T1CTCR=0; //Timer mode T1CCR=0x0A00; //CR3 laden mit TC1, interrupt enabled on rising edge } int main(void) { int backup_T=0; //Lokale Variable um Globale Variable time_p abzuspeichern, damit Interrupt nicht beim abspeichern int backup_p=0; //Lokale Variable um Globale Variable time_p abzuspeichern, damit Interrupt nicht beim abspeichern float puffer_T=0; // dient als Zwischenspeicher der errechneten Temperatur unsigned char lcd_tvor[8]; unsigned char lcd_tnach[8]; unsigned char lcd_p[8]; //zur konvertierung int->char der ergebnisse init(); while(1) { // Temperatur berechnen und ausgeben if(newValueFlag_T==1) //newValue abfragen, damit nur Ausgabe gemacht wird, if(newValueFlag_T==1) //newValue abfragen, damit nur Ausgabe gemacht wird, //wenn neuer Wert vorhanden. Nur ein CCP-Takt zum Ausgeben, und nicht konstant. //Somit kann nur im worst case beim Abspeichern in backup_T ein interrupt dazwischen funken { //INTCONbits.GIEH=0; // disable Interrupts for display backup_T=time_T; //time_T=CCP-Wert, time_T in backup_T speichern, damit zwischenzeitlicher Interrupt bei der Ausgabe den Wert nicht kaputt macht puffer_T= ref_T / backup_T; //Temp errechnen und als komma-Zahl abspeichern temp_vorkomma = (int) puffer_T; //Vorkomma-Wert errechnen temp_nachkomma = (int) ((puffer_T - temp_vorkomma)*10); //Nachkomma-Wert errechnen sprintf(lcd_tvor, "temp_vorkomma is %d", temp_vorkomma); //int in char (hier string) für Ausgabe konvertieren sprintf(lcd_tnach, "temp_nachkomma is %d", temp_nachkomma); //int in char (hier string) für Ausgabe konvertieren VICIntEnClr = 0x30; LCD_gotoxy(13,1); LCD_puts (lcd_tvor); //int ausgeben??? LCD_puts (","); LCD_puts (lcd_tnach); //int ausgeben? -int in char umwandeln ito? LCD_puts (" "); VICIntEnable = 0x30; //INTCONbits.GIEH=1; newValueFlag_T=0; //All interrupt enabled } // Druck berechnen und ausgeben if(newValueFlag_p==1) //newValue abfragen, damit nur Ausgabe gemacht wird, //wenn neuer Wert vorhanden. Nur ein CCP-Takt zum Ausgeben, und nicht konstant. //Somit kann nur im worst case beim Abspeichern in backup_p ein interrupt dazwischen funken { backup_p=time_p; //time_p=CCP-Wert, time_p in backup_p speichern, damit zwischenzeitlicher Interrupt bei der Ausgabe den Wert nicht kaputt macht druck = (char) (ref_p * backup_p); sprintf(lcd_p,"druck is %d", druck); //int in char (hier string) für Ausgabe konvertieren VICIntEnClr = 0x30; //INTCONbits.GIEH=0; // disable Interrupts for display LCD_gotoxy(13,2); LCD_puts (lcd_p); // int in char umwandeln //LCD_puts (leer); VICIntEnable = 0x30; //INTCONbits.GIEH=1; //All interrupt enabled newValueFlag_p=0; } }; } __irq void temp_hisr (void) { // if(PIR2bits.CCP2IF==1) // { T1TC=0; // Timer0 starts with value 0 time_T=T1CR1; // Abspeichern des eingefangenen Wertes von TMR3 T1IR=1; // reset CAP Interrupt newValueFlag_T=1; // newValue setzen VICVectAddr = 0; // Acknowledge Interrupt // } } __irq void druck_lisr(void) { // if(PIR1bits.CCP1IF==1) // { T0TC=0; // Timer1 starts with value 0 time_p=T0CR0; // Abspeichern des eingefangenen Wertes von TMR1 T0IR=1; // reset CAP Interrupt newValueFlag_p=1; // newValue setzen VICVectAddr = 0; // Acknowledge Interrupt // } }
Zur ergänzung noch: manche Kommentare gehören zum PIC wo das ganze schon läuft Vielen Dank schon mal im Voraus für die Hilfe. Gruß Andreas
bist du da weiter gekommen? ich habe im prinzip das gleiche problem. ich moechte auch was ueber cap0.0 einlesen, aber es wird nie in die isr gesprungen. ein kleiner unterschied ist, dass ich sowohl bei ansteigender flanke als auch bei abfallender flanke in die isr springen moechte. in der keil debug session kann ich sehen, dass wenn der cap0.0 pin auf high ist, ist im CR0 register ein konstanter wert. ist cap0.0 auf low, so wird im CR0 immer der aktuelle TC wert gespeichert. also irgendwie so halb scheint das board den flankenwechsel mitzubekommen, aber ein interrupt wird nicht ausgeloest... :-/ habe mal mein zusammengekürztes progrämchen angehängt.
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.