PWM2 and Timer1 conflict

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
melillo
Posts: 44
Joined: 13 Oct 2010 16:41
Location: Montreal, Quebec, Canada
Contact:

PWM2 and Timer1 conflict

#1 Post by melillo » 19 Dec 2014 21:53

Hi folks,

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
}
Do you have any suggestions to solve that problem?

Thanks in advance and have a nice day!

Marc

User avatar
darko.minic
Posts: 747
Joined: 01 Dec 2014 11:10

Re: PWM2 and Timer1 conflict

#2 Post by darko.minic » 22 Dec 2014 15:43

Hello,

Can you send me your whole project (zipped project folder), so I can be able to reproduce the problem?

Regards,
Darko

melillo
Posts: 44
Joined: 13 Oct 2010 16:41
Location: Montreal, Quebec, Canada
Contact:

Re: PWM2 and Timer1 conflict

#3 Post by melillo » 22 Dec 2014 17:26

Hi Darko,

Thank you but it won't be necessary because I solved the problem. After testing, the culprit appeared to be in this line:

Code: Select all

      T1CON.T1OSCEN = 1;// bit 3 Timer1 Oscillator Enable Control: bit 1=on
By setting T1OSCEN to 0, the PWM2 now works perfectly when Timer1 is in function. Even after studying the datasheet, I still don't understant how T1OSCEN affects PWM2.

Thank you again!
Marc

Post Reply

Return to “mikroC PRO for PIC General”