I built a device based on a PIC18F4620, where a LED is driven by the PWM1 controller of the PIC. The LED must be flashed according to a certain sequence. For this purpose, I use Timer1 to time the sequence. The intensity of the LED is set by the PWM1 duty cycle.
Everything is running fine. But I have been asked to add another LED, whose intensity is determined independently of the first LED. So, I connected that second LED on the PWM2 controller.
Now the problem. When I power the PIC, the first LED is off and TIMER1 doesn't run. The second LED works ok, I can control its intensity by setting the PWM2's duty cycle. BUT, when I start TIMER1 (by calling StartMyTimer()), my first LED flashes as I want, BUT THE SECOND LED TURNS OFF, AND COMES BACK WHEN I STOP TIMER1.
I don't want the second LED (controlled by PWM2) to turn off when I start Timer1. I read the PWM functions in the library rely on Timer2, so I'm a bit confused.
Here are some bit of codes that I use (not the full program is listed here). Initialization() is called on power up. The PIC is running on an external 4Mhz clock.
Code: Select all
void Initialization ( void )
{
ADCON1 = 0x0F; // PORTA digital
CMCON = 0x07; // disable comparators
TRISA = 0b00001000; // PORTA: output, except RA3
LATA = 0x00;
TRISB = 0x00;
TRISC = 0x00;
TRISD = 0x00;
background = (ushort)EEPROM_Read(EE_BACKGROUND);
Lcd_Init();
CLRSCR();
Lcd_Cmd(_LCD_CURSOR_OFF);
Delay_1ms();
PWM1_Init(5000); // PWM running at 5kHz
Delay_1ms();
PWM1_Start();
PWM1_Set_Duty(0);
Delay_1ms();
PWM2_Init(5000);
Delay_1ms();
PWM2_Start();
PWM2_Set_Duty(background);
}
void StartMyTimer(void)
{
bk_intcon = INTCON; // bk_...: global variables
bk_pir1 = PIR1;
bk_pie1 = PIE1;
bk_t1con = T1CON;
bk_ipr1 = IPR1;
bk_tmr1h = TMR1H;
bk_tmr1l = TMR1L;
// Timer1 Registers:
// Prescaler=1:1; TMR1 Preset=64536; Freq=1 000.00Hz; Period=1.00 ms
T1CON.T1CKPS1 = 0;// bits 5-4 Prescaler Rate Select bits
T1CON.T1CKPS0 = 0;//
T1CON.T1OSCEN = 1;// bit 3 Timer1 Oscillator Enable Control: bit 1=on
T1CON.T1SYNC = 1;// bit 2 Timer1 External Clock Input Synchronization Control bit: 1=Do not synchronize external clock input
T1CON.TMR1CS = 0;// bit 1 Timer1 Clock Source Select bit: 0=Internal clock (FOSC/4) / 1 = External clock from pin T13CKI (on the rising edge)
T1CON.TMR1ON = 1;// bit 0 enables timer
TMR1H = 0xFC; // preset for timer1 MSB register
TMR1L = 0x18; // preset for timer1 LSB register
// Interrupt Registers
INTCON = 0; // clear the interrpt control register
INTCON.TMR0IE = 0; // bit5 TMR0 Overflow Interrupt Enable bit...0 = Disables the TMR0 interrupt
PIR1.TMR1IF = 0; // clear timer1 interupt flag TMR1IF
PIE1.TMR1IE = 1; // enable Timer1 interrupts
INTCON.TMR0IF = 0; // bit2 clear timer 0 interrupt flag
INTCON.GIE = 1; // bit7 global interrupt enable
INTCON.PEIE = 1; // bit6 Peripheral Interrupt Enable bit...1 = Enables all unmasked peripheral interrupts
}
void StopMyTimer ( void )
{
PIE1 = bk_pie1;
PIR1 = bk_pir1;
T1CON = bk_t1con;
INTCON = bk_intcon;
IPR1 = bk_ipr1;
TMR1H = bk_tmr1h;
TMR1L = bk_tmr1l;
}
void interrupt() // every 1 millisecond
{
TMR1H = 0xFC; // preset for timer1 MSB register
TMR1L = 0x18 + 10; // preset for timer1 LSB register
tic_flick--; // counter for flash
tic_sectimer--; // counter for seconds timer
// counter for flash elapsed
if ( (tic_flick == 0) && (flicker_on == TRUE) ) {
LATA.F0 = LATA.F1 = ledonoff; // send current state to led
ledonoff = 1 - ledonoff; // toggle led state
tic_flick = tic_flick_cnt; // reload counter
}
if ( tic_sectimer == 0 ) { // 1 second reached
clockdisplay_dirty = TRUE; // must refresh display
tic_sectimer = 1000; // reload counter
}
PIR1.TMR1IF = 0; // interrupt must be cleared by software
PIE1.TMR1IE = 1; // reenable the interrupt
}
Thanks in advance and have a nice day!
Marc