Gents,
forgive a second thread so quickly after the previous one, but I can't seem to crack this on my own. I wanted to use the TMR0 in the 16F887 to toggle an output for a very short period of time (20us), effectively creating a pulse. I thought interrupts would be perfect for this, but after an hour or so messing around with a scope and some test code, I can't seem to get the timings right. Here's the code I used for tests:
All the above does is wait for an interrupt from the TMR0 and change the state of pin RE0. Now here's a screenshot from the scope, connected to RE0:
**broken link removed**
As you can see it shows 283us between changes on RE0. Loading the timer with 0 and assigning to WDT means prescale of 1:1, so I would expect a change of state on RE0 every 255-256us, not 283us. That is a 27us error, rather big considering that I want a 20us pulse.
I've also popped the code into MPLAB Sim and timed it using a breakpoint and stopwatch. Again, identical result, 283us.
I'm surprised as I've got a PWM output, which I've checked with a scope and it's bang on precise, here's what I use:
Looking at the scope and what's produced by the PIC on RC2, I get a period of 623.6us and a pulse width of exactly 32us:
**broken link removed**
Does anyone know where the errors might be coming from? the code is stripped to bare minimum, but I still get the dreaded 20 odd us errors on whatever value I preload TMR0 with.
Regards,
T.
forgive a second thread so quickly after the previous one, but I can't seem to crack this on my own. I wanted to use the TMR0 in the 16F887 to toggle an output for a very short period of time (20us), effectively creating a pulse. I thought interrupts would be perfect for this, but after an hour or so messing around with a scope and some test code, I can't seem to get the timings right. Here's the code I used for tests:
Code:
void
main(void)
{
// initiate registers here used in the main code which I've deleted for testing the TMR0 interrupts
TRISE0 = 0; // configured as output
ANS0 = 0;
// internal OSC - 4Mhz
OSCCON = 0b01100101;
TMR0 = 0; //test tmr0 ints
INTCON = 0b10100000;
OPTION_REG = 0b00001000;
while(1) //Do this for loop forever!
{
} // end of global loop
} // end of main()
void interrupt ISR()
{
if (T0IF)
{
T0IF = 0; //clear flag
RE0 = !RE0; //toggle the output
TMR0 = 0; //reset timer
}
if (INTF)
{
//this code is for RB0 interrupts which I've disabled for testing the TMR0 interrupts
}
}
All the above does is wait for an interrupt from the TMR0 and change the state of pin RE0. Now here's a screenshot from the scope, connected to RE0:
**broken link removed**
As you can see it shows 283us between changes on RE0. Loading the timer with 0 and assigning to WDT means prescale of 1:1, so I would expect a change of state on RE0 every 255-256us, not 283us. That is a 27us error, rather big considering that I want a 20us pulse.
I've also popped the code into MPLAB Sim and timed it using a breakpoint and stopwatch. Again, identical result, 283us.
I'm surprised as I've got a PWM output, which I've checked with a scope and it's bang on precise, here's what I use:
Code:
PR2 = 38; //this means PWM period of 624us
CCP1CON = 0b00001100;
CCPR1L = 0b00000010; //set to 2, so pulse width is 2 x 16 = 32 with 16 prescaler
T2CON = 0b00000110; // Prescaler set to 16 on startup, TMR2 ON, Postscaler 1:1
Looking at the scope and what's produced by the PIC on RC2, I get a period of 623.6us and a pulse width of exactly 32us:
**broken link removed**
Does anyone know where the errors might be coming from? the code is stripped to bare minimum, but I still get the dreaded 20 odd us errors on whatever value I preload TMR0 with.
Regards,
T.