This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Using Timer0 and Timer1

Other Parts Discussed in Thread: TMS320F28335

I'm trying to setup Timer0 and Timer1 to run in my program. I do not want them to interrupt, but rather, I'd like timer0 to count up and only stop when I stop it, and I'd like to take the final value of timer0, work some math on the number, then use it to set the period of timer1. I found the reference in SPRUFB0D, but it's a bit confusing about how to go about setting this up... can anyone help me out?

  • Anthony Scarnici said:

    I'm trying to setup Timer0 and Timer1 to run in my program. I do not want them to interrupt, but rather, I'd like timer0 to count up and only stop when I stop it, and I'd like to take the final value of timer0, work some math on the number, then use it to set the period of timer1. I found the reference in SPRUFB0D, but it's a bit confusing about how to go about setting this up... can anyone help me out?

    You are not obligated to configure the CPU Timer 0 and CPU Timer 1 to generate interrupts.  There is a bit field that disables the interrupt generation upon the timer register counting down to 0.

    You may want to consult some examples that are available on the TMS320F28335 Product Folder.  You didn't explicitly mention this part number, but based on the document you reference, I assume you are using the TMS320F28335.

    C2833x/C2823x C/C++ Header Files and Peripheral Examples

     

  • I'm sorry,I forgot to refernce the processor - it is  the TMS320F28335 - and I have been through the product folder already. I could find nothing on timers in there. Here's where I'm at:

    I figured out how to, and then disabled the interrupts already. But I am a bit confused about how to set up the timers. The code example shows:

    ConfigCpuTimer(&CpuTimer0, 150, 1000000);

    I have already gotten this far setting up timer1 and timer0:

    CpuTimer0Regs.TCR.bit.TIE = 0;   // Disable Timer0 interrupt

    CpuTimer1Regs.TCR.bit.TIE = 0;         // Disable Timer1 interrupt

    CpuTimer0Regs.TCR.bit.FREE = 0;        // FREE bit - setting for timer0 to handle breakpoints in debug mode - free run = 0

    CpuTimer1Regs.TCR.bit.FREE = 0;   // FREE bit - setting for timer1 to handle breakpoints in debug mode - free run = 0

    CpuTimer0Regs.TCR.bit.SOFT = 0;   // SOFT bit - sets timer0 to halt after next decrement of TIMH:TIM (hard stop)

    CpuTimer1Regs.TCR.bit.SOFT = 0;        // SOFT bit - sets timer1 to halt after next decrement of TIMH:TIM (hard stop)

      

    CpuTimer0Regs.TPR.bit.PSC =            // not set yet...

    CpuTimer0Regs.TCR.bit.TRB =1;          // Timer0 Reload Bit - when set, TIMH:TIM gets loaded with the value in PRDH:PRD and PSCH:PSC with TDDRH:TDDR

    CpuTimer1Regs.TCR.bit.TRB =1;          // Timer0 Reload Bit - when set, TIMH:TIM gets loaded with the value in PRDH:PRD and PSCH:PSC with TDDRH:TDDR

    EPwm1Regs.TBCTL.bit.CTRMODE = 0;   // count up and start

    for setting the interrupt, but what about just setting the timer? What goes in place of the pointer? basically, I want to tell it to cound down from a certain number, I'll stop it periodically, save the value, and start it again. The prescaler is a little fuzzy to me. Could you please give a breif breakdown and an example of usig the timer0 without the interupts, as well as reading the remaining value after the timer is stopped by software? One example code snippet is not really enough information for a beginner with this particular processor! Thanks!!

  • In particular, I'm looking for  better explanation of how to load period values, and how to work with the prescalar and timer divide down registers.

  • Consider the timer as a 32 bit down-counter. When the counter reaches 0, the counter is reloaded with the period value. This duration will be (period * input CLK period).

    Now if you want a longer period than (SYSCLK * 2^32 ~ 53 seconds) you can pre-scale the input clock using the 8-bit TDDR, which extends the period by another 8 bits, where PSC is your lsb. So the total time read from the counters will be ~3.8 hours. Reading the two separate counters in sync will be tricky though.

    But if you don't care about the timer resolution you can consider the pre-scalar as just an integer divider of SYSCLK and use 32-bit TIM counter for rough timing.

    If the timer is running (TCR.TSS == 0), reloading will be automatic - when the counter reaches zero. You have the option to reload the counter using TCR.TRB bit, set to 1 to reload 32 bit counter (TIM) with PRD and 8 bit pre-scalar (PSC) with TDD.

    Simple steps to do to configure a timer:

     

      /*

      * Timer 2 - used as 32bit 80MHz clock down-counter.

      */

    CpuTimer2Regs.TCR.bit.TSS = 1;         // 1 = Stop timer, 0 = Start/Restart Timer

    CpuTimer2Regs.PRD.all =  0xFFFFFFFF;  // Initialize timer period to maximum

    CpuTimer2Regs.TCR.bit.TRB = 1;         // 1 = reload timer now

    CpuTimer2Regs.TCR.bit.TIE = 0;         // 0 = Disable/ 1 = Enable Timer Interrupt

    CpuTimer2Regs.TCR.all = 0;             // TSS = 0 = Start/Restart Timer

     

    Later in your code you read the counter (all 32 bits) by 

    Uint32 l_nCountNow = CpuTimer2Regs.TIM.all;

     

     

     

  • Thanks J - that clears a bit of stuff up. Bear with my questions...

    If I want the timer to count down to 0 at a 40 Hz rate, and I'm running at 150Mhz, I divide to get 150Mhz/40Hz = 3750000 = 0x00393870 and that would be my PRD.all value that I load correct? And if I don't want to scale it I can load all zero's into the prescalar and divide down registers? Is there a way to make the timer NOT reload and restart when it reaches 0? Or does that require interupt sequences? The rest, I think I've figured out...

     

    Tony

     

  • Hey Tony, Correct. What is the point in having the counter stopped at 0? You can monitor the TCR.TIF flag for the underflow event even if Interrupt is disabled.

    -Joe

  • I'm looking to follow a sine wave and see if it phase shifts so stopping the counter will enable me to find that (I have another timer running as well - complicated crap that I dreamed up in my office...lol)

    But thanks for all the help!!!

  • One other question, the Example_2833xCpuTimer.c file has the following code in it:

    // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any // of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2833x_CpuTimers.h), the // below settings must also be updated.

     CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0   

     CpuTimer1Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0   

     CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0

     

    What do they mean by "precise timing" and how will writing the bits individually change that if anything?

     

    If I write:

     

    CpuTimer1Regs.TCR.all = 0x0420;

     

    will this reload the TIMH:TIM and then instantly start the timer? Or is this statement mostley used when cycle count is critical?

    Tony

     


  • Hi,

    I want to calculate duration using timer.. To test, I used Timer0 and the delay routine..

    I configured the timer 0 to interrup each 1ms, to compare the timer value But there a mistake. 

    //###########################################################################

    #include "DSP2833x_Device.h"
    #include <stdio.h>

    // Prototype statements for functions found within this file.
    void Gpio_select(void);
    void InitSystem(void);
    void delay_loop(long);

    //External functions
    extern void InitSysCtrl(void);
    extern void InitPieCtrl(void);
    extern void InitPieVectTable(void);
    extern void InitCpuTimers(void);
    extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);
    //Interrupt ISR
    interrupt void cpu_timer0_isr (void);

    //###########################################################################

    // main code 
    //###########################################################################
    void main(void)
    {
    int counter=0; // binary counter for digital output
    int time;
    InitSysCtrl(); // Basic Core Init from DSP2833x_SysCtrl.c

    EALLOW;
    SysCtrlRegs.WDCR= 0x00AF; // Re-enable the watchdog 
    EDIS; // 0x00AF to NOT disable the Watchdog, Prescaler = 64

    DINT; // Disable all interrupts

    Gpio_select(); // GPIO9,GPIO11,GPIO34 and GPIO49 as output (LEDs @ peripheral explorer)

    InitPieCtrl();

    InitPieVectTable();

    EALLOW;
    PieVectTable.TINT0 = &cpu_timer0_isr;
    EDIS;

    InitCpuTimers();

    ConfigCpuTimer(&CpuTimer0, 150, 1000);

    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

    IER |= 1;

    EINT;
    ERTM;

    //while(1)

    counter++;
    if(counter&1) GpioDataRegs.GPASET.bit.GPIO9 = 1;
    else GpioDataRegs.GPACLEAR.bit.GPIO9 = 1;
    if(counter&2) GpioDataRegs.GPASET.bit.GPIO11 = 1;
    else GpioDataRegs.GPACLEAR.bit.GPIO11 = 1;
    if(counter&4) GpioDataRegs.GPBSET.bit.GPIO34 = 1;
    else GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1;
    if(counter&8) GpioDataRegs.GPBSET.bit.GPIO49 = 1;
    else GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1;

    CpuTimer0Regs.TCR.bit.TSS = 0; // start timer0

    delay_loop(1000000);
    CpuTimer0.InterruptCount = 0;
    EALLOW;
    SysCtrlRegs.WDKEY = 0x55; // service WD #1
    EDIS;

    time = CpuTimer0.InterruptCount *  1000 ;   // 1000 µs

    printf("%d = ", time);

    }
    }

    void Gpio_select(void)
    {
    EALLOW;
    GpioCtrlRegs.GPAMUX1.all = 0; // GPIO15 ... GPIO0 = General Puropse I/O
    GpioCtrlRegs.GPAMUX2.all = 0; // GPIO31 ... GPIO16 = General Purpose I/O
    GpioCtrlRegs.GPBMUX1.all = 0; // GPIO47 ... GPIO32 = General Purpose I/O
    GpioCtrlRegs.GPBMUX2.all = 0; // GPIO63 ... GPIO48 = General Purpose I/O
    GpioCtrlRegs.GPCMUX1.all = 0; // GPIO79 ... GPIO64 = General Purpose I/O
    GpioCtrlRegs.GPCMUX2.all = 0; // GPIO87 ... GPIO80 = General Purpose I/O

    GpioCtrlRegs.GPADIR.all = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO9 = 1; // peripheral explorer: LED LD1 at GPIO9
    GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // peripheral explorer: LED LD2 at GPIO11

    GpioCtrlRegs.GPBDIR.all = 0; // GPIO63-32 as inputs
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34
    GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49
    GpioCtrlRegs.GPCDIR.all = 0; // GPIO87-64 as inputs
    EDIS;
    }

    interrupt void cpu_timer0_isr(void)
    {
    CpuTimer0.InterruptCount++;

    EALLOW;
    SysCtrlRegs.WDKEY = 0xAA; // service WD #2
    EDIS;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }
    void delay_loop(long end)
    {
    long i;
    for (i = 0; i < end; i++)
    {
    asm(" NOP");
    EALLOW;
    SysCtrlRegs.WDKEY = 0x55;
    SysCtrlRegs.WDKEY = 0xAA;
    EDIS;
    }

    //===========================================================================
    // End of SourceCode.
    //===========================================================================

    Any solution ?!

    Thank you