mikimtb
Newbie level 1
- Joined
- Dec 16, 2010
- Messages
- 1
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,296
Hi everybody, my name is Miroslav and I'm from Serbia.
I'm trying to write a code for controlling four RC servo motors with PIC18F4550. Till now I finished all things about USB HID and UART communication, and it's working perfectly.
Today I try to write a code for timer0 configuration. Because I have four motors to control, I need timer0 interrupts on every ~5ms. I configured timer0 as 16bit timer/counter, increment on internal clock, with prescaler of 1:2. After that I configured interrupt priority low for timer0 and enable timer0 interrupt. With timer0 prescaler 1:2 I have to write offset of 35398 into TMR0H:TMR0L and timer will overflow on every 5ms (30137*0.083us * 2 = 5002us).
Firstly, I tested this in main loop and its work perfectly. Code for my test is below:
After proofing this with oscilloscope, I changed the code to do the same thing with interrupt. The code is below:
Again I had PWM signal on RB0 pin but the frequency wasn't 200Hz. Instead that frequency is 193kHz. I try to change prescaler value, or offset value but the frequency is constant 193kHz. In code above I didn't copy RCONbits.IPEN = 1; for interrupt priority enables. This configuration is in picInit function.
Does somebody had problem like this? I mentioned that I had uart and usb communication, does that can be a problem? I'm using PIC C18 compiler.
- - - Updated - - -
I found the error,
INCONBits.TMR0IF; has to be INCONBits.TMR0IF = 0;
I was blind almost four hour, wtf.
I'm trying to write a code for controlling four RC servo motors with PIC18F4550. Till now I finished all things about USB HID and UART communication, and it's working perfectly.
Today I try to write a code for timer0 configuration. Because I have four motors to control, I need timer0 interrupts on every ~5ms. I configured timer0 as 16bit timer/counter, increment on internal clock, with prescaler of 1:2. After that I configured interrupt priority low for timer0 and enable timer0 interrupt. With timer0 prescaler 1:2 I have to write offset of 35398 into TMR0H:TMR0L and timer will overflow on every 5ms (30137*0.083us * 2 = 5002us).
Firstly, I tested this in main loop and its work perfectly. Code for my test is below:
Code:
void TIMER0Init(void)
{
T0CONbits.TMR0ON = 0; // Disable TMR0
T0CONbits.T08BIT = 0; // Timer0 is 16bit timer/counter
T0CONbits.T0CS = 0; // Internal clock source
T0CONbits.PSA = 0; // Prescaler enabled
T0CONbits.T0PS2 = 0; // 1:2 Prescaler ratio
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 0;
/* Make Timer0 interrupt low priority */
INTCON2bits.TMR0IP = 0;
/* Enalbe TMR0 interrupt*/
INTCONbits.TMR0IE = 0;
/* Enable all low priority interrupts */
INTCONbits.GIEL = 0;
/*Clear TMR0 interrupt flag*/
INTCONbits.TMR0IF = 0;
/* Write Timer0 offset for ~5ms interrupt */
TMR0H = 0;
TMR0L = 0;
T0CONbits.TMR0ON = 1; // Start the timer
.
.
.
// infinite loop inside main function
while(1)
{
#if defined(USB_POLLING)
// If we are in polling mode the USB device tasks must be processed here
// (otherwise the interrupt is performing this task)
USBDeviceTasks();
#endif
// Process USB Commands
processUsbCommands();
// Process UART Commands
processUartCommand();
// timer0 test
timerValuePtr = (unsigned char*)&timerValue;
*timerValuePtr = TMR0L;
timerValuePtr++;
*timerValuePtr = TMR0H;
if(timerValue >= 30137)
{
PORTBbits.RB0 ^= 1;
timerValue = 0;
TMR0H = 0;
TMR0L = 0;
}
// timer0 test end
}
After proofing this with oscilloscope, I changed the code to do the same thing with interrupt. The code is below:
Code:
void TIMER0Init(void)
{
T0CONbits.TMR0ON = 0; // Disable TMR0
T0CONbits.T08BIT = 0; // Timer0 is 16bit timer/counter
T0CONbits.T0CS = 0; // Internal clock source
T0CONbits.PSA = 0; // Prescaler enabled
T0CONbits.T0PS2 = 0; // 1:2 Prescaler ratio
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 0;
/* Make Timer0 interrupt low priority */
INTCON2bits.TMR0IP = 0;
/* Enalbe TMR0 interrupt*/
INTCONbits.TMR0IE = 1;
/* Enable all low priority interrupts */
INTCONbits.GIEL = 1;
/*Clear TMR0 interrupt flag*/
INTCONbits.TMR0IF = 0;
/* Write Timer0 offset for ~5ms interrupt */
TMR0H = 138;
TMR0L = 70;
T0CONbits.TMR0ON = 1; // Start the timer
}
// Low-priority ISR handling function
#pragma interruptlow lowPriorityISRCode
void lowPriorityISRCode()
{
// Application specific low-priority ISR code goes here
// TMR0 interrupt
if(INTCONbits.TMR0IF)
{
TMR0H = 138; // Write offset for 5ms overflow
TMR0L = 70;
PORTBbits.RB0 ^= 1; // Toggle PORTB.0
INTCONbits.TMR0IF; // Clear interrupt flag
}
}
Again I had PWM signal on RB0 pin but the frequency wasn't 200Hz. Instead that frequency is 193kHz. I try to change prescaler value, or offset value but the frequency is constant 193kHz. In code above I didn't copy RCONbits.IPEN = 1; for interrupt priority enables. This configuration is in picInit function.
Does somebody had problem like this? I mentioned that I had uart and usb communication, does that can be a problem? I'm using PIC C18 compiler.
- - - Updated - - -
I found the error,
INCONBits.TMR0IF; has to be INCONBits.TMR0IF = 0;
I was blind almost four hour, wtf.
Last edited: