• Not Answered

Timer PWM Problem

Hello,

I have been wanting to use the CCP0 pin of the LM3S608 to generate PWM on the same (CCP0) pin. This doesn't happen,  I know there is some trivial issue. Could someone please correct me ?

void TimerInit(void)
{

SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

GPIOPinConfigure(CCP1_PIN);


GPIOPinTypeTimer(GPIO_PORTC_BASE, GPIO_PIN_5);


TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC | TIMER_CFG_B_PWM);


TimerLoadSet(TIMER0_BASE, TIMER_B, SysCtlClockGet());


TimerMatchSet(TIMER0_BASE, TIMER_B, TimerLoadGet(TIMER0_BASE, TIMER_B) / 2);


//TimerControlLevel(TIMER0_BASE, TIMER_B, true);

/* Enable Timer0A. */
TimerEnable(TIMER0_BASE, TIMER_B);

}

thanks
--
Shanjit Singh Jajmann

26 Replies

  • Hi Shanjit,

    The GPIOPinConfigure function is not applicable to the LM3S608.  You should instead use GPIOPinTypeTimer().  Also you mention CCP0 in your text, but your code uses CCP1.

    Regards,

    Sue

  • Along w/Sue's comments (you must eliminage the GPIOPinConfigure() call as she stated) try the following:

    a) Your PortC_GPIO_PIN_5 is CCP1 - as you state - but this requires that you employ "Half-Width" not Full Width timers.

    Thus your Code must change to: TimerConfigure(TIMER0_BASE, TIMER_CFG_B_PERIODIC | TIMER_CFG_B_PWM);  // only half-width timers can utilize Timer_B

    b) Believe this is all that is required to get you going.  Beware that the faster you run this timer - the less resolution will be available for your PWM.  The PWM capability is surprisingly good and none of the difficulties which impinge the more sophisticated PWM Modules of more advanced MCUs will effect your PWM.  (i.e. you may freely range from 0 - 100% PWM)

    Your confirming report will be appreciated - and "close the loop" for interested others...   Good luck...

     

  • In reply to cb1_mobile:

    Much Appreciated replies. Indeed, i am trying to get PWM working on the CCP1 pin (Typo). 

    cb1_mobile

    Along w/Sue's comments (you must eliminage the GPIOPinConfigure() call as she stated) try the following:

    a) Your PortC_GPIO_PIN_5 is CCP1 - as you state - but this requires that you employ "Half-Width" not Full Width timers.

    Thus your Code must change to: TimerConfigure(TIMER0_BASE, TIMER_CFG_B_PERIODIC | TIMER_CFG_B_PWM);  // only half-width timers can utilize Timer_B

    Oh yes! I overlooked this!

    b) Believe this is all that is required to get you going.  Beware that the faster you run this timer - the less resolution will be available for your PWM.  The PWM capability is surprisingly good and none of the difficulties which impinge the more sophisticated PWM Modules of more advanced MCUs will effect your PWM.  (i.e. you may freely range from 0 - 100% PWM)

    Ditto! 

    Your confirming report will be appreciated - and "close the loop" for interested others...   Good luck... 

    What i didn't understand was, why not to use the GPIOPinConfigure() function ? Also, removing that, doesn't make it work! 

    Total Code: http://pastebin.com/KwGsGwLv

    Just to be clear

    i have a LED at PC5/CCP1 pin on my LM3S608 board. I am trying to run a PWM on the pin so that i could get the effect on the LED. 

    thank you

    --

    Shanjit Singh Jajmann

  • Guru 47910 points

    In reply to Shanjit Singh:

    Almost looked like we had you up/running - and then you multi-quested - threw us a curve.

    So: have you changed TimerConfigure() (via cut/paste is safest) to include corrected parameter: TIMER_CFG_B_PERIODIC ???  Unclear to me if you really made this change...

    GPIOPinConfigure() - SW-DRL-UG does advise that this function is not available for your (dare I say) "class" MCU.  Highlight that function - right click - and you can review how the function is built - and the fact that it exploits mechanisms not present w/in your MCU.

    As your test gear is an Led have you tested it - and its series limiting R?  Suggest that you revert your code to non-PWM - change PC5 to basic output - and confirm that your Led monitor works in that manner. 

    Should the Led and PC5 work - change your PWM frequency to hard-coded 1000Hz and then further hard-code a variety of values into TimerMatchSet()...  Your values now are far too low...

  • In reply to cb1:

    guys, really appreciate all the comments but it seems that this has not been solved yet. I am in the same boat and I am using the same (almost) simple approach to mux the CCP pin to an LED output. the LED output does work, and I am using the LM4F120 launchpad kit to accomplish the simple task of output a clock like signal on an LED using timers. below is a snippet of my code, please tell me what I am doing wrong, I know its in the initialization somewhere but cant find whats broken. 

    #define PART_LM4F120H5QR true
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/timer.h"

    int main (void)

    {
    unsigned long period;
    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralEnable (SYSCTL_PERIPH_TIMER0);

    GPIOPinConfigure(GPIO_PF1_T0CCP1);
    GPIOPinTypeTimer(GPIO_PORTF_BASE,GPIO_PIN_1);

    GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE,GPIO_PIN_3);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3,0);

    TimerConfigure (TIMER0_BASE,TIMER_CFG_SPLIT_PAIR);
    //TimerControlLevel (TIMER0_BASE,TIMER_A,false);

    period = (SysCtlClockGet()/10)/2;

    TimerLoadSet(TIMER0_BASE,TIMER_B, period-1);
    //TimerLoadSet(TIMER0_BASE,TIMER_A, 50000);
    //TimerMatchSet (TIMER0_BASE,TIMER_A, 50000/3);

    IntEnable (INT_TIMER0B);
    TimerIntEnable (TIMER0_BASE,TIMER_TIMB_TIMEOUT);
    IntMasterEnable ();

    TimerEnable (TIMER0_BASE,TIMER_B);

    unsigned long i;

    while(1)
    {

    /*for (i=0;i<9;i++)
    {
    i = TimerGetperiod = (SysCtlClockGet()/30)/(i+1);
    TimerLoadSet(TIMER0_BASE,TIMER_A, period-1);
    SysCtlDelay(SysCtlClockGet()*5);
    }*/

    //
    //i = TimerValueGet(TIMER0_BASE,TIMER_A);
    }
    }

    really appreciate your help. 

  • In reply to Bakr Younis:

    Bakr Younis
    to mux the CCP pin to an LED output. the LED output does work

    Are you certain that you've "mux'ed" the CCP pin to PF_3?  We see where you've cleared PF_3 - but nowhere does PF_3 appear to be, "Set!"

    Unlike simpler MCUs - most ARM devices do "not" directly output their Timer signal.  To achieve your goal I'd expect to see a, "toggle" of PF_3 during your timer interrupt service...

  • In reply to cb1_mobile:

    Hi cb1,

    my code snippet was a bit confusing since I was doing more than just muxing the CCP to a GPIO, what I was trying to say that the port works on the LM4F120 launchpad, i can access it. what I really wanted is to channel the counting to portF pin1. the muxing tool shows that can be done. portF pin3 was just a GPIO that  i was using for testing. I tried a bunch of timer configuration settings but none of them worked and even I tried enabling the interrupts to see if the timer is firing and also no use. could it be my includes and libraries ? (didnt get any errors). there are other posts on the forum that talk about this but none seem to discuss this muxing issue. by the way, my ultimate goal is to perform PWM and channel that to a GPIO, but if I cant get the simple timer to work then its a moot point.

    any hints would be most appreciated

  • In reply to Bakr Younis:

    ok, I think I am half way there, I got a PWM to work with interrupts (not optimal code ... dont laugh please) what I did:

    my main:

    // clock set

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    // GPIO set

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3,0);

    //timer0 set to periodic + PWM

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_A_PERIODIC|TIMER_CFG_A_PWM);

    // PWM period

    ulPeriod = (SysCtlClockGet() / 40);

    //load period in timer0A
    TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod-1);

    //load match value in compare register
    TimerMatchSet(TIMER0_BASE,TIMER_A, ulPeriod-30000);

    //interrupts setup and enable

    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT|TIMER_TIMA_MATCH);
    IntMasterEnable();

    //enable timer

    TimerEnable(TIMER0_BASE, TIMER_A);

    .....

    my handler:

    void Timer0IntHandler(void)
    {
    // Clear the timer interrupt
    //unsigned long intStatus =0;
    if (TimerIntStatus (TIMER0_BASE,true) & TIMER_TIMA_MATCH)
    {
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_MATCH);
    //GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,!GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1));
    if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
    }

    // Read the current state of the GPIO pin and
    // write back the opposite state
    if (TimerIntStatus (TIMER0_BASE,true) & TIMER_TIMA_TIMEOUT)

    {
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    //GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1)^1);
    if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
    {
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
    }
    else
    {
    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
    }
    }

    }

    i want to write this so that the output of the PWM directly goes to the GPIO (PORTF PIN1 or PIN2 or PIN3 are allready connected to LED on the LM4F120 launchpad board) by muxing the timer0 output to the GPIO and let the proper TimerConfigure flags + TimerEnable do the job.

    in stellarisware peripheral examples folder, there is a timers sub folder with a PWM example showing how to do the pin muxing and the proper timerconfigure, has anybody did muxing successfully on the launchpad board ? are there any gotchas that I should be aware of ? I heard I cant use TCCP0 since its locked and needed to be unlocked before I can GPIOConfigure it ?

    if any body can throw me a bone that would be great.

    pwm.c
  • Guru 26035 points

    In reply to Bakr Younis:

    Hi,

    Sometimes problems should be solved beginning with the end (specifications, schematics, what you have at hand..) - in your case: launchpad has the LEDs connected to PF1, PF2, PF3 - you want use PWM to set on/off the LED at PF1 - but reading the micro user manual, page 659, table 11-2: PF1 is the pin for T0CCP1; same page, table 11-1: T0CCP1 is the capture input/pwm out for TimerB, while in your program you use TimerA. Why? (or I am wrong guessing your goals...)

    Suppose you will succeed to use the PWM, here it is a new problem: what if I want to manage all LEDs on board, how you will do that with only one 16-bit timer, for all LEDs? - just think about, all I want to emphasize is do not try to waist the resources...

    Petrei

  • In reply to Bakr Younis:

    Pardon - you have "so much" going on - very hard to give crisp/clear response.  KISS (simplify) ALWAYS Works best for our small group.

    Suggest that you clearly list your written design objectives - then devise a plan of attack for each one.  Try to avoid complications and "over-optimization" in the beginning - instead a, "Quick, Dirty" Mission Accomplished should be the goal.  Later - as/if required - you can tweak/refine...