Forum: Compiler & IDEs ARM7 LPC2368 Capture-Interrupt


von Andreas (Gast)


Lesenswert?

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
//  }
}

von Andreas (Gast)


Lesenswert?

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

von Clemens (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.