Issues using multiple timers with PIC18F4550

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Hi,
I have been working on this issue for a week and cannot seem to get anything to work as expected. I assume I am missing a step. I want to get two LEDs flashing at different rates using two timers. I found this tutorial which was very helpful to get one LED to work. However when I tried to modify it to work with two timers both LEDs flash at the same rate and that should not be the cases since I played around with the speeds and the rates were still the same. Could anyone point out what I am doing wrong for some reason I just cannot understand timers in PIC compared to the other microcontrollers I have used.

Also if there is a more efficient way of doing this that requires less code that would be great if someone could show me that way.

Thanks
I am using the 18F4550 in MPLABX with XC8
config.h
Rich (BB code):
#ifndef CONFIG_H
#define	CONFIG_H

#ifdef	__cplusplus
extern "C" {
#endif




#ifdef	__cplusplus
}
#endif

#endif	/* CONFIG_H */

#include <xc.h>

//#pragma config CONFIG1L = 0x0
__CONFIG(1, PLLDIV_1 & CPUDIV_OSC1_PLL2 & USBDIV_1);
//#pragma config CONFIG1H = 0x8
__CONFIG(2, FOSC_INTOSCIO_EC & FCMEN_OFF & IESO_OFF);
//#pragma config CONFIG2L = 0x19
__CONFIG(3, PWRT_OFF & BOR_OFF & BORV_3 & VREGEN_OFF);
//#pragma config CONFIG2H = 0x1E
__CONFIG(4, WDT_OFF & WDTPS_32768);
//#pragma config CONFIG3H = 0x83
__CONFIG(5, CCP2MX_ON & PBADEN_ON & LPT1OSC_OFF & MCLRE_ON);
//#pragma config CONFIG4L = 0x85
__CONFIG(6, STVREN_ON & LVP_ON & ICPRT_OFF & XINST_OFF);
//#pragma config CONFIG5L = 0xF
__CONFIG(7, CP0_OFF & CP1_OFF & CP2_OFF & CP3_OFF);
//#pragma config CONFIG5H = 0xC0
__CONFIG(8, CPB_OFF & CPD_OFF);
//#pragma config CONFIG6L = 0xF
__CONFIG(9, WRT0_OFF & WRT1_OFF & WRT2_OFF & WRT3_OFF);
//#pragma config CONFIG6H = 0xE0
__CONFIG(10, WRTC_OFF & WRTB_OFF & WRTD_OFF);
//#pragma config CONFIG7L = 0xF
__CONFIG(11, EBTR0_OFF & EBTR1_OFF & EBTR2_OFF & EBTR3_OFF);
//#pragma config CONFIG7H = 0x40
__CONFIG(12, EBTRB_OFF);
main.c
Rich (BB code):
#include <xc.h>
#include <plib/timers.h>
#include "config.h"

#define _XTAL_FREQ 800000
#define USE_AND_MASKS

int i =0;
unsigned char Timer0Config;
unsigned char Timer1Config;
void SetupClock(void);

void main(int argc,char** argv)
{
    SetupClock();
    TRISBbits.RB4=0;
    LATB4=1;
    TRISBbits.RB3=0;
    LATB3=1;

    Timer0Config = TIMER_INT_ON & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256 ;
    T1CON=0b11110101;
    Timer1Config = T1CON;
    OpenTimer0(Timer0Config);
    WriteTimer0(0xE17B);
    OpenTimer1(Timer1Config);
    WriteTimer1(0xE17B);
    PIR1bits.TMR1IF = 0;
    INTCONbits.TMR0IF = 0;
    ei();

    while(1)
    {
    }

}
void SetupClock()
{
    OSCCONbits.IRCF0 = 1;
    OSCCONbits.IRCF1 = 1;
    OSCCONbits.IRCF2 = 1;
}

void interrupt TImerOverflow()
{
    if(INTCONbits.TMR0IF ==1)
    {
        LATB4 =~LATB4;
        INTCONbits.TMR0IF = 0;
        WriteTimer0(0xE17B);
    }
     if(PIR1bits.TMR1IF ==1)
    {
        LATB3 =~LATB3;
        PIR1bits.TMR1IF = 0;
        WriteTimer1(0xE17B);
    }
}
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
UPDATE:

After playing around with timers I was able to get something to work. However even though I have one prescaler at 1:4 and the other at 1:8 and set both the TMR0IF and TMR1IF to overflow 10 times before their respective LEDs should come on and they seem to both come on at the same time. So my question is is there something I am missing to configure to get the two different prescalers to work and they are actually just using one timer or something else?

The config.h file is the same as previously posted and below is the new main.c.

Thanks
Rich (BB code):
#include <xc.h>
#include <plib/timers.h>
#include "config.h"
#include<stdint.h>

#define _XTAL_FREQ 800000
#define USE_AND_MASKS
unsigned char counter;
unsigned char counter1;
Init(void)
{
     OSCCON =01111110;
     TMR1 = 0;
TMR0 = 0;//Clear the TMR0 register
/*Configure Timer0 as follows:
- Use the internal instruction clock
as the source to the module
- Assign the Prescaler to the Watchdog
Timer so that TMR0 increments at a 1:1
ratio with the internal instruction clock*/
T0CON = 0b10000001;
T1CON = 0b11100101;
TRISBbits.RB4=0;
LATB4=0;
TRISBbits.RB3=0;
LATB3=0;
}
/*----------------------------------------------------------
Subroutine: main
Parameters: none
Returns: nothing
Synopsys: Main program function
-----------------------------------------------------------*/
main(void)
{
Init(); //Initialize the relevant registers
while(1)
{
//Poll the T0IF flag to see if TMR0 has overflowed
if (TMR0IF==1)
{
++counter;//if T0IF = 1 increment the counter
//variable by 1
TMR0IF = 0;//Clear the T0IF flag so that
//the next overflow can be detected
if (counter >10)
{
    LATB4=1;
}
}
if (TMR1IF==1)
{
++counter1;//if T0IF = 1 increment the counter
//variable by 1
TMR1IF = 0;//Clear the T0IF flag so that
//the next overflow can be detected
if (counter1 >20)
{
    LATB3=1;
}
}

}
 

RG23

Joined Dec 6, 2010
304
WriteTimer0(0xE17B);??????????

WriteTimer1(0xE17B)????????
___________________________________________________________
Load different values in the timer registers so that you get different rates
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
Enable the bit 5 of INTCON register in the main program before jumping to the interrupt

INTCONbits.TMR0IF = 1
Thanks that seemed to do the trick with the second code I posted. Should I also do this with the PIE1 for Timer1? I think the part that confuses me the most is how set up the timers properly. I understand I need to do the TXCON, but what other registers should I also look at? The INTCON for Timer0 and the PIE1 and PIR1 for Timers1 and 2?
 

Thread Starter

rkrutz

Joined Dec 2, 2009
29
WriteTimer0(0xE17B);??????????

WriteTimer1(0xE17B)????????
___________________________________________________________
Load different values in the timer registers so that you get different rates
Sorry that was from a test I was running, but even if I made WriteTimer1(0x70BD) so they were different by a half it came on at the same time. I will try the suggestion you made earlier on that code after dinner and hopefully that clears up the issue.

UPDATE:
So I changed INTCONbits.TMR0IF = 1; and made Timer1 go at 70DB and now the LEDs alternate. However no matter what I change the second timer to they still alternate at the same rate. Is this due to them being called one ofter the other in the same interrupt routine?
 
Last edited:

Thread Starter

rkrutz

Joined Dec 2, 2009
29
So I have been working with the second code I posted and it seems that no matter what I do to the if statements related to RB3 the LED at that pin always alternates with the LED on RB4. Since this even happens when I comment out those statements I am guessing there is something wrong with how I am using the timer. Could someone point out what I am doing wrong?

Rich (BB code):
/* 
 * Created on June 9, 2013, 5:13 PM
 */
#include <xc.h>
#include <plib/timers.h>
#include "config.h"
#include<stdint.h>

#define _XTAL_FREQ 800000
#define USE_AND_MASKS
unsigned char counter;
unsigned char counter1;
Init(void)
{
     OSCCON =01011110;
     TMR1 = 0;
TMR0 = 0;//Clear the TMR0 register
/*Configure Timer0 as follows:
- Use the internal instruction clock
as the source to the module
- Assign the Prescaler to the Watchdog
Timer so that TMR0 increments at a 1:1
ratio with the internal instruction clock*/
T0CON = 0b10000001;
T1CON = 0b11100101;
TRISBbits.RB4=0;
LATB4=0;
TRISBbits.RB3=0;
LATB3=0;
INTCONbits.TMR0IF = 1;
PIR1bits.TMR1IF = 0;
PIE1bits.TMR1IE = 1;
INTCONbits.TMR0IF = 1;
INTCONbits.TMR0IE = 1;
}
/*----------------------------------------------------------
Subroutine: main
Parameters: none
Returns: nothing
Synopsys: Main program function
-----------------------------------------------------------*/
main(void)
{
Init(); //Initialize the relevant registers
while(1)
{
//Poll the T0IF flag to see if TMR0 has overflowed
if (TMR0IF==1)
{
++counter;//if T0IF = 1 increment the counter
//variable by 1
TMR0IF = 0;//Clear the T0IF flag so that
//the next overflow can be detected
if (counter >10)
{
    LATB4=1;
}
}
/*if (TMR1IF==1)
{
++counter1;//if T0IF = 1 increment the counter
//variable by 1
TMR1IF = 0;//Clear the T0IF flag so that
//the next overflow can be detected
*/
if (counter1 >10)
{
    //LATB3=1;
}
}

}
 
Top