Hi All,
trying to get Timer1 working with a 32.678kHz crystal. Using a PIC16LF1937 on a board which one of my co workers has used before.
Crystal is on the T1OSCIN and OUT pins.
What happens: RE2 goes high for 0.5sec and goes low again as expected in a loop. RD1 goes high and stays high....
Code:
#include <pic.h>
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
//#define _XTAL_FREQ 4000000UL
#define _XTAL_FREQ 32000000UL
//#define _XTAL_FREQ 4000000
#pragma config CPD=OFF, BOREN=OFF, IESO=OFF, FOSC=INTOSC, FCMEN=OFF, MCLRE=OFF, WDTE=OFF, CP=OFF, PWRTE=ON, CLKOUTEN=OFF, LVP=ON, PLLEN=ON
unsigned int wat = 0;
int main(void) {
TRISD1 = 0;
TRISE2 = 0;
//internal 32kHz clock
OSCCONbits.SCS = 0b00;
OSCCONbits.IRCF = 0b1110;
OSCCONbits.SPLLEN = 1;
// configure Timer1
T1CONbits.TMR1CS = 2; //clock source as 10, external crystal
T1CONbits.T1OSCEN = 1; // enable external oscillator
T1CONbits.nT1SYNC = 0; // sync external clock with system clock
T1CONbits.TMR1ON = 1; // enable Timer1
// setup Timer1 interrupt flags to default
PIR1bits.TMR1IF = 0; //Timer1 Overflow Interrupt not pending
PIE1bits.TMR1IE = 1; //Timer1 Overflow interrupt enable
INTCONbits.PEIE = 1; // peripheral interrupt enable
ei();
// main loop
while (1) {
PORTEbits.RE2 = 0;
__delay_ms(500);
PORTEbits.RE2 = 1;
__delay_ms(500);
}
return 0;
}
void interrupt isr()
{
if (TMR1IF && TMR1IE) {
TMR1IF = 0; // clear flag
INTCONbits.GIE = 1;
wat++;
if (wat > 1) {
PORTDbits.RD1 = ~PORTDbits.RD1;
wat = 0;
}
return;
}
}
Any help would be appreciated, Ive been trying to get this going all day with help from the datasheet...
You haven't configured the ANSEL registers so neither pin should do anything.
Also you should write/modify port LAT registers to avoid read/modify/write issues (probably doesn't matter here).
You could check the 32kHz crystal is actually oscillating.
You haven't configured the ANSEL registers so neither pin should do anything.
Also you should write/modify port LAT registers to avoid read/modify/write issues (probably doesn't matter here).
You could check the 32kHz crystal is actually oscillating.
Set the ANSEL regs to 0x00 and now works!!! Thanks!
But the LED i have connected to RD1 oscillates about 0.25 Hz, shouldnt it be oscillating at 32kHz?
Set the ANSEL regs to 0x00 and now works!!! Thanks!
But the LED i have connected to RD1 oscillates about 0.25 Hz, shouldnt it be oscillating at 32kHz?
Timer 1 is a 16 bit up counter which interrupts on overflow so it will interrupt every 2 seconds and you toggle the LED every other interrupt.
The timer 1 hardware isn't very friendly for doing anything faster than 0.5Hz if you want to maintain an accurate total count of 32kHz cycles.
Ah right, I wanted to use this timer for a second timer. Not handy if its running at 0.5 Hz? I now have a 2 second timer
.
EDIT: Had a brainwave and used the prescaler (T1CKPS) to do this, but unfortunately only makes it slower and not speeds up like I thought it would. Haha.
Ah right, I wanted to use this timer for a second timer. Not handy if its running at 0.5 Hz? I now have a 2 second timer.
If you preset the timer registers to -32k in the interrupt handler it will overflow 1 second later.
However, if you can't afford to miss a clock cycle you need to take the interrupt and preset the timer before the next 32kHz clock. Being able to do that depends on how fast the PIC is running and what else it is doing. Using the prescaler could give you more time or you could spin and wait for a clock in the interrupt handler to give you enough time for the timer register loading. Presetting the timer with its current value -32k would mean you have relatively ages to get round to servicing the interrupt.