Hey guys, I'm trying to do software PWM at 100Hz for a RGB LED. I am using the PIC18F4550 and c18 LITE compiler. The main issue I am having is getting the interrupt to work. I have looked over AN1074 and how to calulate a 100Hz signal with 32 steps (1/100Hz = 10ms/32 => 312uS).
According to the application note => 256 - ( (312uS) / (Prescale x (1/(48MHz/4)) ) ) => 256 - ( 312uS / (16 * (83.33nS)) ) => 22
So I am trying to set timer0 to interrupt every 312uS. I have it set to low priority for now, but I can always change it to high priority. So, my question is, why isn't the below code working properly? Do I need to use high priority? Is the TMR0L the wrong value? Am I using the wrong prescaler? Any help is appreciated. Thank you.
Global area interrupt
Timer and interrupt configurations in main
According to the application note => 256 - ( (312uS) / (Prescale x (1/(48MHz/4)) ) ) => 256 - ( 312uS / (16 * (83.33nS)) ) => 22
So I am trying to set timer0 to interrupt every 312uS. I have it set to low priority for now, but I can always change it to high priority. So, my question is, why isn't the below code working properly? Do I need to use high priority? Is the TMR0L the wrong value? Am I using the wrong prescaler? Any help is appreciated. Thank you.
Global area interrupt
Code:
// Global area
// Interrupt (see pg. 99 of PIC18F4550 datasheet)
//______________________________________
//Declare interrupt function
void timer_isr(void);
#pragma code low_vector=0x18
void low_PWM_interrupt (void)
{
_asm
GOTO timer_isr
_endasm
}
#pragma code
//code for defining interrupt function
#pragma interruptlow timer_isr
void timer_isr(void)
{
//what you want the interrupt to do goes here
//Check timer0 iunterupt flag
if (INTCONbits.TMR0IF==1 )
{
//Code that tests interrupt
int x;
for(x =0;x<=100;x++)
{
LEDPin1=1;LEDPin2=0;LEDPin3=1;
Delay10KTCYx(100); // must wait at least 212.5mS (120*100000*4/48e6) for 48Mhz
Delay10KTCYx(100); // must wait at least 212.5mS (120*100000*4/48e6) for 48Mhz
Delay10KTCYx(100); // must wait at least 212.5mS (120*100000*4/48e6) for 48Mhz
Delay10KTCYx(100); // must wait at least 212.5mS (120*100000*4/48e6) for 48Mhz
Delay10KTCYx(100); // must wait at least 212.5mS (120*100000*4/48e6) for 48Mhz
LEDPin1=1;LEDPin2=1;LEDPin3=0;
}
//TMR0L=22; //see calculation in main
INTCONbits.TMR0IF=0; //clear timer0 interrupt flag
}
}
//_______________________________________________
Timer and interrupt configurations in main
Code:
// Set up interrrupt control register pg. 101 of pic18f4550 datasheet
INTCONbits.GIE = 1; // Enable global and high priority interrupts
INTCONbits.GIEL = 1; // Enable low priority interrupts
RCONbits.IPEN = 1; // Enables proirity levels on interrupts
//Added
T0CONbits.TMR0ON=1; // Turn timer on = 1
T0CONbits.T08BIT=1; // 8bit = 1, 16 bit = 0
T0CONbits.T0CS=0; // Internal instuction clock cycle = 0
T0CONbits.T0SE=0; // transistion on high CLK
T0CONbits.PSA=0; // prescaler is assigned = 0
T0CONbits.T0PS2=0;
T0CONbits.T0PS1=1;
T0CONbits.T0PS0=1;
TMR0H=0; // Ensure high bytes of timer register are 0 since using 8bit timer and not 16bits
TMR0L=22; // Using 100Hz for LEDs => 1/100Hz => 10mS, if using 32 steps => 10mS/32 => 312uS interrupt period
// Resets Timer0 counter based on calculation for PWM (256 - (InterruptPeriod / Prescale x Tcy)
// Prescaler is set to ensure resultant value of the below equation is 255 or less
// 256 - ( (312uS) / (Prescale x (1/(48MHz/4)) ) ) => 256 - ( 312uS / (16 * (83.33nS)) ) => 22
// 48Mhz is divided by 4 since each instruction takes 4 clock cycles
//___
INTCONbits.TMR0IE=0; // Enables Timer0 interrupt
INTCONbits.TMR0IF=0; // Clear timer interupt flag
INTCON2bits.TMR0IP=0; // Overflow interrupt priority bit (0=low priority, 1=high priority)
Last edited: