www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Pic24FJ256GB Problem mit Timer1 Interrupt


Autor: Casi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich beginne gerade mit der µP Programmierung und habe mir für den Anfang 
ein PIC24 Starterkit mit einem PIC24FJ256GB106 kontroller gekauft. Auch 
was die Programmiersprache C angeht habe ich noch kein Vorwissen.
Ich habe es mir zur Aufgabe gemacht eine LED auf dem Developmentboard im 
Sekundentakt blinken zu lassen. Hierzu möchte ich einen Timer1 einsetzen 
der sekündliche einen Interrupt auslöst und dabei den Zustand der LEDs 
wechselt. Den Timer möchte ich mit einem externen 32kHz Oszillator 
ansteuern. Ich vermute, dass das Oszillator Enable Bit (SOSCEN) nicht 
eingeschaltet ist. Doch jedes Mal wenn ich das entsprechede Register 
OSCCON konfiguriere ist zu sehen, dass sich das Register wie von 
Zauberhand selber umkonfiguriert. Nachfolgend der Quellcode meines 
Programmes. Hat jemand eine Idee was ich falsch mache?

Vielen Dank.

Gruß
Carsten

#include <p24FJ256GB106.h>


int R = 0;
int GB =0;



void __attribute__((_interrupt_, _shadow_)) _T1Interrupt(void)
{
  GB^=0x1111;
  R^=0x1111;
  IFS0bits.T1IF = 0; //Reset Timer1 interrupt flag and Return from ISR
}



int main()
{
  T1CON        = 0x00;    //Stops the Timer1 and reset control reg.
  TMR1         = 0x00;    //Clear contents of the timer register
  PR1          = 32700;   //Load the Period register with the value 
0x8CFF
  IPC0bits.T1IP = 0x01;   //Setup Timer1 interrupt for desired priority 
level
                // (this example assigns level 1 priority)
  IFS0bits.T1IF = 0;       //Clear the Timer1 interrupt status flag
  IEC0bits.T1IE = 1;       //Enable Timer1 interrupts
  T1CON = 0x8002;       //Start Timer1 with prescaler settings at 1:1 
and
                //clock source set to the external clock in the
                //asynchronous mode
  OSCCON =0x0402;
  PORTG=GB;
  PORTB=R;
  TRISG=0b1111110000111111;
  TRISF=0b1111111111001111;

  while (1)
    {
      PORTG=GB;
      PORTF=R;
    };

}

Autor: Lehrmann Michael (ubimbo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eher die Vermutung, dass du gar keinen Output schaltest.

Casi schrieb:
> Doch jedes Mal wenn ich das entsprechede Register
> OSCCON konfiguriere ist zu sehen, dass sich das Register wie von
> Zauberhand selber umkonfiguriert.

Wie siehst du das? ICD ?

Wie sieht's mit Config-Bits aus ? (bitte mal reiposten)

Bitte poste deinen C Code nochmal und versuch es zu Formatieren (hier im 
Forum) d.h. in eckigen Klammern davor avrasm und danach wiederin eckigen 
Klammern /avrasm zu posten. Sonst ist's nicht schön zu lesen

Bist du denn sicher, dass der PIC anläuft ?

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Soweit ich weiss nutzt das Starterkit den internen Oszillator für den
Systemclock.

Versuch mal folgenden Code:

#include <p24FJ256GB106.h>

_CONFIG2(IESO_OFF & PLL_96MHZ_ON & PLLDIV_DIV2 & FNOSC_FRCPLL & POSCMOD_NONE) // Primary osc disabled, FRC OSC with PLL, USBPLL /2
_CONFIG1(JTAGEN_OFF & ICS_PGx2 & FWDTEN_OFF)        // JTAG off, watchdog timer off

int main( void )
{

  OSCCON = 0x1102;    // Enable secondary oscillator, use FRC oscillator
  CLKDIV = 0x0000;    // FRC post-scaler (1:1), USB postscaler (1:1), CPU postscaler (1:1)

  RPINR2bits.T1CKR = 37;  // Timer1 Externer Clock an RPI 37

  // Timer 1 init
  TMR1 = 0;                   // Timer1 Register löschen
  PR1 = 32700;                // Interruptintervall für Timer1 setzen 
  IFS0bits.T1IF = 0;          // Timer1 Interrupt Flag löschen
  T1CONbits.TCS = 1;          // Externer Clock
  T1CONbits.TCKPS = 0;        // Timer1 Input Clock Teilverhältnis 1:1
  IEC0bits.T1IE = 1;          // Timer1 Interrupt aktivieren
  T1CONbits.TON = 1; 

  // LED Init
  TRISFbits.TRISF4 = 0;      // PIN auf Output schalten
  TRISFbits.TRISF5 = 0;      // PIN auf Output schalten

  while(1)      // main loop
  {
    Nop();
    Nop();
  }
}

void __attribute__((__interrupt__, no_auto_psv)) _T1Interrupt(void)
  {               
  
  LATFbits.LATF4 = LATFbits.LATF4 ^ 1;
  LATFbits.LATF5 = LATFbits.LATF5 ^ 1;
  
  IFS0bits.T1IF = 0;                 // Timer1 Interrupt Flag löschen 
  return;
  }


Gruss Manuel

Autor: Casi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

erstmal danke für Eure Hilfe.

Zu Michael:
Doch ich hatte die Outputs geschaltet. Es war auch möglich die Diode an 
oder auszuschalten (abhängig von PORTF, PORTG). Nur blinken war nicht 
möglich. Was meinst Du mit ICD?

Zu Manuel:
Ich habe jetzt mal Deinen Quellcode übernommen, aber auch damit blinkt 
die LED nicht. Eine LED (die rote) ist dauerhaft an. Ich habe mir das 
Ganze mal mit dem Debugger angeschaut. Die Interrupt Service Routine 
wird nicht aufgerufen. Für mich sieht es so aus als wenn der Timer nicht 
läuft. TMR1 ist permanent 0x0000. Bei meinem Code hat der Timer 
gearbeitet. Bei Deinem Code lässt sich allerdings das OSCCON Register 
ändern. Das hat bei mir nicht funktioniert. Kann das an den ersten 
beiden Code Zeilen liegen, dass sich das OSCCON Register ändern lässt?

Anbei ein Screenshot von den Registern.

Gruß
Carsten

Autor: Casi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich habe jetzt mal den internen Timer eingeschaltet. Ist das korrekt?

T1CONbits.TCS = 0;

Der Timer läuft jetzt, aber ein Interrupt kommt immer noch nicht.

Gruß
Carsten

Autor: Casi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat niemand mehr eine Idee?

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man benötigt eine spezielle Befehlsfolge, um das OSCCON-Register zu 
beschreiben. Microchip stellt diese in einem Macro zur Verfügung. 
Versuche mal

__builtin_write_OSCCONL(0b1100010);

danach sollte das SOSCEN Bit auch gesetzt sein.

Gruß, Dirk

Autor: Master Snowman (snowman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe nicht gründlich alle zeilen von oben durchgedacht, und auch 
habe ich noch nie gehört, dass es ein procedere zum beschreiben von 
OSCCON gibt (jedoch können gewisse bits in einem register nicht immer 
geschrieben sondern nur gelesen werden, da sie sich immer mal wider 
verändern, weil sie über den status der hardware aufschluss geben). 
anyway, was ich oft bei problemen bei anderen feststelle, ist, dass sie 
versuchen alle register manuell zu beschreiben und irgendwo, dann was 
nicht richtig ist (widersprüchliche konfiguration etc.). da den fehler 
zu suchen ist zeitraubend. statt der manuellen konfiguration verwendet 
man besser in einem ersten schritt die von Microchip gegebenen 
funktionen wie OpenTimer1() etc., damit ersparst du dir viele 
fehlerquellen und leserlicher ist's auch.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.