Forum: Mikrocontroller und Digitale Elektronik "Low Frequency" Timer1/Sleep Problem


von Matthias P. (Gast)


Lesenswert?

Hallo Community,

normalerweise lässt sich ein Datenblatt ja immer wie ein Kochrezept 
lesen
aber irgendwie übersehe ich gerade irgendetwas...

Ich verwende einen PICLF1933 und verwende dabei den Low-Frequency 
Oscillator(31kHz). Mein Oszilloskop bestätigt den Takt des Prozessors.

Das komische nun ist, wenn ich den Timer konfiguriere und ihn auf "LP 
Osc disabled" stelle,  funktioniert der Timer einwandfrei und der 
Interrupt wird ausgelöst. Ich möchte meinen Pic aber im Sleep-Modus 
laufen lassen
und dazu soll laut Datenblatt das "T1OSCEN" Bit auf 1 gesetzt werden um 
den LP Oscillator zu verwenden.

NUR wird dann kein Interrupt mehr ausgeführt und egal ob das Bit gesetzt 
ist oder nicht. Der Sleep-Mode funktioniert nicht und ich erhalte beim 
Stoppen des PICs die Fehlermeldung: "PICkit 3 has halted with error(s)."

Nach ein wenig Recherche habe ich im Datenblatt unter 23.2.5 folgendes 
gefunden und verstehe das nicht so recht:

"The Compare mode is dependent upon the system
clock (FOSC) for proper operation. Since FOSC is shut
down during Sleep mode, the Compare mode will not
function properly during Sleep."

Kann ich die Compare Mode nicht im Sleep Mode verwenden?
Ich habe meine Timer bisher immer mit dem Compare Mode eingestellt,
daher weiß ich grad nicht weiter... Falls das das Problem ist: Wie kann 
ich den Timer ohne Compare Mode verwenden?

Habe soweit alle Bits soweit nach Datenblatt gesetzt aber irgendwas muss
ja nicht richtig eingestellt sein...

Vielen Dank für eure Zeit und Antwort(en)
PS: Meine Kommentare sind immer englisch :p


Datenblatt: http://ww1.microchip.com/downloads/en/DeviceDoc/41575A.pdf
1
 
2
// C O N F I G U R A T I O N   B I T S
3
4
#ifdef __DEBUG
5
__CONFIG(FOSC_INTOSC&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF&BOREN_ON&LVP_OFF&
6
WRT_ALL);  // Debug Configuration
7
#else
8
__CONFIG(FOSC_INTOSC&WDTE_ON&PWRTE_ON&MCLRE_OFF&CP_ON&BOREN_ON&LVP_OFF&
9
WRT_ALL);  // Configuration
10
#endif
11
12
13
14
//........
15
16
17
 // Oscillator Configuration
18
19
OSCCON = 0b10000010;    // 31 kHz (Low Frequency)
20
21
 // Timer Configuration
22
23
CCPR1H = _5_sec_H;     // Compare mode value -> HIGH bits
24
CPR1L = _5_sec_L;    // Compare mode value -> LOW bits
25
26
T1CON   = 0b00111101;    // System Clock FOSC, 1:8 Prescale, 
27
                                // LP Osc enabled, 
28
              // Do not synchronize             
29
                                // enable Timer 1
30
31
CCP1M3  = set;      // Compare Mode 
32
CCP1M2  = clear;    // Compare Mode
33
CCP1M1  = set;      // Compare Mode
34
CCP1M0  = set;      // Compare Mode
35
CCP1IF   = set;      // Set CCP1 Interrupt Flag 
36
                                // to cause a "start" interrupt 
37
CCP1IE  = set;      // Enable CCP1 Interrupt Enable bit
38
39
  
40
41
 // Interrupt Configuration
42
43
IOCBF   = clear;                // Clear IoChange Flag     
44
IOCBP2   = set;      // IOC detect positive edges
45
IOCBN2   = set;      // IOC detect negative edges
46
IOCBP0   = set;      // IOC detect positive edges
47
IOCBN0   = set;      // IOC detect negative edges
48
IOCIE   = set;       // Enable Interrupt on Change
49
50
PEIE   = set;      // Enable peripheral interrupts
51
GIE   = set;      // Enable port change interrupt
52
ei();        // Enable global interrupts
53
54
 // Sleep Mode 
55
SLEEP();

von Scotty (Gast)


Lesenswert?

Den Compare Mode brauchst du doch nur, wenn du einen PIN toggeln willst.
Wenn's reicht timergesteuert mittels Interrupt aus dem Sleep 
aufzuwachen, hilft dir vielleicht mein Beispiel von einem 18F2550 
weiter:
1
void Sleep30Us(unsigned char delay_multiplier)
2
{ TMR3IE = 1;         // enable Timer3 interrupt
3
  TMR3H = 0xFF;       // high byte, Timer3 counts upwards, -> delay_multiplier counts to trigger interrupt
4
  TMR3L = 0xFF - delay_multiplier;    // 32768 Hz -> 30,5 µsec * delay_multiplier
5
  T3CON = 0b11001111; // enable Timer3, clocked by Timer1 clock, no prescaler, 16 bit mode
6
  sleep();            // sleep until Timer3 interrupt, stopp Timer3 in interrupt routine!
7
}

von Matthias P. (Gast)


Lesenswert?

Danke für deine Antwort Scotty.
Das mit dem Timer ohne Compare Mode wusste ich gar nicht.
Tja man lernt nie aus :)

Der Timer läuft jetzt also:
1
  TMR1H = 0x200;       // high byte, Timer1 
2
  TMR1L = 0x200;     // low byte, Timer1 
3
4
  TMR1CS1 = 0;       // Clock source is FOSC
5
  TMR1CS0 = 1;       // Clock source is FOSC
6
  T1CKPS1 = 0;       // Prescale Value is 1:1
7
  T1CKPS0 = 0;       // Prescale Value is 1:1
8
  T1OSCEN = 0;       // LP Osc disabled
9
  nT1SYNC = 1;       // Don't synchronize external clock
10
  TMR1ON  = 1;       // Enable Timer 1
11
12
  TMR1IE = set;       // Set Timer1 Interrupt Enable Bit
13
  TMR1IF = set;       // Ser Timer1 Interrupt Flag at the beginning

Sobald ich allerdings die Sleep Instruction setzte, wird der Interrupt 
nicht
mehr ausgeführt... Und sobald ich das Debuggen stoppe bekomme ich die
Fehlermeldung: "PICkit 3 has halted with error(s)."
Das TO und PD Bit im STATUS Register sind beide gesetzt. Er geht also
gar nicht in den Sleep Mode...

Die Schaltplanregeln hab ich auch, soweit ich weiß, eingehalten.
http://www.mikrocontroller.net/attachment/131199/PICkit3.gif

Es muss ja an dem Sleep liegen. Ich weiß nur nicht warum.
Danke nochmal für eure Hilfe

von Scotty (Gast)


Lesenswert?

Nimm mal das Setzen des TMR1IF raus. Das Flag zeigt dir an, ob der TMR1 
übergelaufen ist und einen Interrupt ausgelöst hat. Muß dann unbedingt 
in der ISR gelöscht werden, sonst kommt man der ISR nicht mehr raus.
1
if(TMR1IF)       // check if Timer 1 caused interrupt
2
{  TMR1IF = 0;   // clear Timer1 interrupt
3
   TMR1ON = 0;   // disable Timer1
4
}

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.