• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » Stellaris® ARM® Microcontrollers » Stellaris® ARM® LM3S Microcontrollers Forum » EK-LM3S9B90 pwm generation with Timer 1
Share
Stellaris® ARM® Microcontrollers
  • Forum
Options
  • Subscribe via RSS

EK-LM3S9B90 pwm generation with Timer 1

EK-LM3S9B90 pwm generation with Timer 1

This question is answered
newtothis
Posted by newtothis
on Sep 06 2011 11:09 AM
Intellectual980 points

I am trying to generate a pair of pwms with the EK-LM3S9B90 using a timer (Timer 1 specifically). The following code is used to setup the timer to yield two 10 kHz 50% duty cycle signals and output to pins PC4 and PC 5. When only one signal is generated, I get a neat 10 kHz 50% duty cycle signal. While trying to generate two signals one of the signals is unstable (looks like it is driven high with a pwm signal superimposed) and the other does not show any signal whatever. Sometimes, though the one pin shows a clean signal while the other continues to show a pwm superimposed on a "high" output. I tried using separate ports (Port E and Port C) to output the signal but faced the same problem. Would adding a few delay cycles help when initializing pins? The code is being compiled with CCS v4.

Once initialized the code runs an infinite loop and is periodically interrupted at intervals of 1 second to update the LED and UART.

 

 

void Init(void)

{

//

    // Set the clocking to run directly from the crystal to 80MHz.

    //

    ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |

                       SYSCTL_XTAL_16MHZ);

 

    //

    // Initialize the UART.

    //

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    GPIOPinConfigure(GPIO_PA0_U0RX);

    GPIOPinConfigure(GPIO_PA1_U0TX);

    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTStdioInit(0);

 

    //

    // Initialize LED (Port D Pin 0)

    //

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);

 

 

    //

    //Initialize Timer0

    //

    //

    // Enable the peripherals used by this example.

    //

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

    //

    // Enable processor interrupts.

    //

    ROM_IntMasterEnable();

 

    //

    // Configure the Timer0 for 32 bit timer operation, Timer1 for 10kHz 50% duty cycle PWM signals.

    //

    ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);

    ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PWM);

    ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_B_PWM);

    ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet());

    ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, 8000);

    ROM_TimerLoadSet(TIMER1_BASE, TIMER_B, 8000);

    ROM_TimerMatchSet(TIMER1_BASE, TIMER_A, 4000);

    ROM_TimerMatchSet(TIMER1_BASE, TIMER_B, 4000);

    //ROM_TimerControlLevel(TIMER1_BASE, TIMER_A, true);

    //ROM_TimerControlLevel(TIMER1_BASE, TIMER_B, false);

 

 

    ROM_GPIOPinConfigure(GPIO_PC4_CCP2);

    ROM_GPIOPinTypeTimer(GPIO_PORTC_BASE,GPIO_PIN_4);

    ROM_GPIOPinConfigure(GPIO_PC5_CCP3);

    ROM_GPIOPinTypeTimer(GPIO_PORTC_BASE,GPIO_PIN_5);

 

    //

    // Setup the interrupts for the timer timeouts.

    //

    ROM_IntEnable(INT_TIMER0A);

    ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

 

    // 

    // Setup the interrupt for pushbutton press (pull down)

    //

    ROM_GPIODirModeSet(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);

    ROM_GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

 

    //

    // Setup the interrupt for pushbutton press.

    //

    ROM_GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_LOW_LEVEL);

    ROM_IntEnable(INT_GPIOB);

 

    //

    // Set interrupt priorities

    //

    ROM_IntPrioritySet(INT_GPIOB, 0x00);

    ROM_IntPrioritySet(INT_TIMER0A, 0x00);

 

 

 

    //

    // Enable the timers.

    //

    ROM_TimerEnable(TIMER0_BASE, TIMER_A);

    ROM_TimerEnable(TIMER1_BASE, TIMER_A);

    ROM_TimerEnable(TIMER1_BASE, TIMER_B);

 

    g_uscount = 0;

    UARTprintf("\rcount = %d", g_uscount);

}

 

//*****************************************************************************

//

// The interrupt handler for the TIMER0 interrupt.

//

//*****************************************************************************

void

Timer0IntHandler(void)

{

    //

    // Clear the timer interrupt.

    //

    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

 

    //

    // Toggle the flag for the first timer.

    //

    HWREGBITW(&g_ulFlags, 0) ^= 1;

 

    //

    // Update the interrupt status on the display.

    //

    ROM_IntMasterDisable();

    if(++g_uscount > 9)

    {

    g_uscount = 0;

    }

    UARTprintf("\rcount = %d", g_uscount);

 

    ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, ~ROM_GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_0)); //Flip LED each second 

    ROM_IntMasterEnable();

}

 

PWM Timer LM3S9B90
Report Abuse
  • Reply
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
All Replies
  • Lela Garofolo
    Posted by Lela Garofolo
    on Sep 08 2011 13:14 PM
    Genius17450 points

    Hi,

    I have duplicated your issue.  In the process of debugging it, the issue is the GPIOAFSEL and GPIOPCTL registers are being incorrectly written.  The way you code is written, it should work.  I am looking into why the API is not setting it correctly.  The order of them in you code shouldn't cause an issue, as the write should be ORed in.  I will continue working on this and send a update and recommendation. 

    Lela

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Lela Garofolo
    Posted by Lela Garofolo
    on Sep 08 2011 17:10 PM
    Genius17450 points

    I finally got it working...Te issue with the GPIOAFSEL and GPIOPCTL registers, came from another API overwriting it them that I had inserted in the debugging process.  The issue is the API ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);  You have it twice, once for A_PWM and the second for B_PWM.  Evidently...you have OR the TIMER_CFG_A_PWM | TIMER_CFG_B_PWM in the same TimerConfigure API or the 2nd write will write over the first one.  Again, I would have thought it wouldn't matter...but in stepping through the code, and the driverlib code I found that the A and B pair need to be done in the same API call.

    I took everything out of your code that did not pertain to the issue...the working code for PC4 and PC5 is:

     ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
      
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
     GPIOPinConfigure(GPIO_PA0_U0RX);
     GPIOPinConfigure(GPIO_PA1_U0TX);
     ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
     UARTStdioInit(0);
     
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
     ROM_IntMasterEnable();

        ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);
    // ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_A_PWM);
    //    ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR | TIMER_CFG_B_PWM);
       
        ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, 8000);
        ROM_TimerLoadSet(TIMER1_BASE, TIMER_B, 8000);
        ROM_TimerMatchSet(TIMER1_BASE, TIMER_A, 4000);
        ROM_TimerMatchSet(TIMER1_BASE, TIMER_B, 4000);

        GPIOPinConfigure(GPIO_PC4_CCP2);
        GPIOPinTypeTimer(GPIO_PORTC_BASE,GPIO_PIN_4);
        GPIOPinConfigure(GPIO_PC5_CCP3);
        GPIOPinTypeTimer(GPIO_PORTC_BASE,GPIO_PIN_5);


        ROM_TimerEnable(TIMER1_BASE, TIMER_A);


        ROM_TimerEnable(TIMER1_BASE, TIMER_B);
       
     while (1)
     {}   

    Please let me know if you have any other issues.

    Lela

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • newtothis
    Posted by newtothis
    on Sep 09 2011 08:20 AM
    Intellectual980 points

    Thanks for that. Couple of questions:

    - When debugging how did you watch the values of the registers? I included the lm3s9b90.h and tried to add the appropriate register to the watch window, but it wont recognize the register. Even adding watch variables didnt cut it. How did you do it? 

    -Can I invert one of Timer 1A and Timer1b and not the other? I tried using ROM_TimerControlLevel(TIMER1_BASE, TIMER_A, true) and then TIMER1_CTL_R |= (1 <<6); to do it but either of them wasnt successful. What am I doing wrong?

    PWM Timers CCSV4 LM3S9B90
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • newtothis
    Posted by newtothis
    on Sep 09 2011 16:14 PM
    Intellectual980 points

    Well I figured out the register bit (view drop down menu !). Sorry about that, but still cant get the active low/high combination working.

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Lela Garofolo
    Posted by Lela Garofolo
    on Sep 13 2011 16:13 PM
    Verified Answer
    Verified by newtothis
    Genius17450 points

    Yes, you can invert Timer 1A and not Timer1B...All you need to do is ROM_TimerControlLevel(TIMER1_BASE, TIMER_A, true).   I inserted it into the code that I pased above, and it worked for me.

    Let me know if you continue to have an issue.

    Lela

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Bakr Younis
    Posted by Bakr Younis
    on Oct 11 2012 23:38 PM
    Prodigy180 points

    Hi Lela,

    I am facing a similar problem trying to implement the a PWM from timer0 on portF on part LM4F120H5QR used in the stellaris launchpad EK-LM4F120XL. I have been searching the posts and forum for somebody to find out what am I doing wrong but no luck yet. I had a version of this code perform PWM through interrupts where state of LED changed at match and at timeout, but I should have to use interrupts and I want to get a free running PWM multiplexed to a GPIO directly (PF1 in this case)

    data sheet for LM4F120H5QR mentions that I can configure PF1 to be T0CCP1 and redirect the PWM output from timer0B to that pin, that pin is connected to an LED that would help me see the PWM in action since I dont have a scope handy. below is my code and the loop runs but nothing is happening on the LED, I am suspecting something in the configuration of the pins is not in order. please see my code snippet.

    //#define PART_LM4F120H5QR
    #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/rom_map.h"
    #include "driverlib/timer.h"
    #include "driverlib/pin_map.h"

    int main (void)

    {

    unsigned long ulPeriod;

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

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

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    GPIOPinConfigure(GPIO_PF1_T0CCP1);
    GPIOPinTypeTimer(GPIO_PORTF_BASE,GPIO_PIN_1);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_B_PERIODIC|TIMER_CFG_B_PWM);

    ulPeriod = SysCtlClockGet() / 40;
    TimerLoadSet(TIMER0_BASE, TIMER_B, ulPeriod-1);
    TimerMatchSet(TIMER0_BASE,TIMER_B, ulPeriod-30000);

    TimerEnable(TIMER0_BASE, TIMER_A);

    while(1)
    {


    }
    }

    any hints on what am I doing wrong would be appreciated. 

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Lela Garofolo
    Posted by Lela Garofolo
    on Oct 22 2012 15:49 PM
    Genius17450 points

    Bakr,

    Apologies for the delayed response...

    You code had a couple issues, PF2 and PF3 are on Timer 1, had Timer 0 in your code.  TIMER_CFG_PERIODIC sets ulConfig for a Full-width periodic timer.  For PWM mode on timer A and B, you want to set it for two half-width timers using parameter, TIMER_CFG_SPLIT_PAIR.    Then the value based on ulPeriod and system clock is greater than 16 bits for both ulValue writes to API's TimerLoadSet and TimerMatchSet.  It will still do the write, but will only write 16-bits.  Bits 24:16 need to be handled by writing to the prescale registers.

    Your code working...

     SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

     SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); 
     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
     
     GPIOPinConfigure(GPIO_PF2_T1CCP0);
     GPIOPinConfigure(GPIO_PF3_T1CCP1);

     GPIOPinTypeTimer(GPIO_PORTF_BASE,GPIO_PIN_2 | GPIO_PIN_3);
     
     TimerConfigure(TIMER1_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PWM | TIMER_CFG_B_PWM);

    ulPeriod = SysCtlClockGet() / 40;
    TimerLoadSet(TIMER1_BASE,TIMER_A, ulPeriod-1);
    TimerPrescaleSet(TIMER1_BASE,TIMER_A,0xF);
    TimerLoadSet(TIMER1_BASE, TIMER_B, ulPeriod-1);
    TimerPrescaleSet(TIMER1_BASE,TIMER_B,0xF);
    TimerMatchSet(TIMER1_BASE,TIMER_A, ulPeriod-30000);
    TimerMatchSet(TIMER1_BASE,TIMER_B, ulPeriod-30000);
    TimerPrescaleMatchSet(TIMER1_BASE,TIMER_A,12);
    TimerPrescaleMatchSet(TIMER1_BASE,TIMER_B,12);


    TimerEnable(TIMER1_BASE, TIMER_A | TIMER_B);


    while(1)
    {}
    }

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • Bakr Younis
    Posted by Bakr Younis
    on Oct 23 2012 22:35 PM
    Prodigy180 points

    no worries, 

    I know you guys are helping people all the time with more complicated issues, I did find the solution on another thread after digging into the rgb.c shipped with stellarisware for the EK-LM4F120XL board. The split pair is what got me and obviously the way I was handling the 16 bits matchset was also problematic for accurate timing but know its more clear and I thank you for that. I noticed that when I was debugging that only the 16 bit mattered and I should have scaled accordingly. I never used the prescalares before but ill read up on them and I again thank you for your dedication and most valued help.

    Bakr

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • roman kovalev
    Posted by roman kovalev
    on Mar 06 2013 14:58 PM
    Prodigy20 points

    Hello Lela,

    I have the similar issue on my stellaris launchpad. After whole day coding with no effect I start googling and found this thread.

    I just copy and paste your code above and only BLUE LED blinking by PWM. If I change last line to

    TimerEnable(TIMER1_BASE, TIMER_B);

    I can see GREEN LED blinking, but can't make them blinking together..

    Please help to investigate.

    Regards,

    Roman

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
  • roman kovalev
    Posted by roman kovalev
    on Mar 06 2013 15:24 PM
    Prodigy20 points

    Hello,

    My apologizes for post above. Your example works correctly, it's too late, I did'nt see green LED...

    thanks.

    Roman

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
TI E2E™ Community
  • Support Forums
  • Blogs
  • Videos
  • Groups
  • Site Support & Feedback
  • Settings
TI E2E™ Community Groups
  • TI University Program
  • Make the Switch
  • Microcontroller Projects
  • Motor Drive & Control
Other Communities
  • Deyisupport
  • Designsomething.org
  • beagleboard.org
  • TI on Element 14
  • TI on TechXchangeSM
Other Technical & Support Resources
  • WEBENCH® Design Center
  • Product Information Centers
  • Technical Documents
  • TI Design Network
  • TI Technical Articles
  • TI Training

All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
embedded processors, along with software, tools and the industry’s largest sales/support staff.

© Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy Policy | Terms of Use