Sign in to follow this  
Followers 0
lawrence_jeff

Using Hardware PWM on Tiva Launchpad

32 posts in this topic

PWM is much easier on the new Launchpad using the PWM peripherals, here is a working example using the 3 onboard LEDs.

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/pwm.h"

int
main(void)
{    unsigned long ulPeriod;

    //Set the clock
   SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC |   SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

   //Configure PWM Clock to match system
   SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

   // Enable the peripherals used by this program.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);  //The Tiva Launchpad has two modules (0 and 1). Module 1 covers the LED pins
    ulPeriod = SysCtlClockGet() / 200; //PWM frequency 200HZ

    //Configure PF1,PF2,PF3 Pins as PWM
    GPIOPinConfigure(GPIO_PF1_M1PWM5);
    GPIOPinConfigure(GPIO_PF2_M1PWM6);
    GPIOPinConfigure(GPIO_PF3_M1PWM7);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    //Configure PWM Options
    //PWM_GEN_2 Covers M1PWM4 and M1PWM5
    //PWM_GEN_3 Covers M1PWM6 and M1PWM7 See page 207 4/11/13 DriverLib doc
    PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC); 
    PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC); 

    //Set the Period (expressed in clock ticks)
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, ulPeriod);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, ulPeriod);

    //Set PWM duty-50% (Period /2)
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,ulPeriod/2);
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,ulPeriod/2);
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_7,ulPeriod/2);

    // Enable the PWM generator
    PWMGenEnable(PWM1_BASE, PWM_GEN_2);
    PWMGenEnable(PWM1_BASE, PWM_GEN_3);

    // Turn on the Output pins
    PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT |PWM_OUT_6_BIT|PWM_OUT_7_BIT, true);

    //Do nothing
    while(1)
    {

    }

}
igor, bluehash, maqsudbek and 1 other like this

Share this post


Link to post
Share on other sites

hi, i'm studying the pwm on a lm4f120hq, when I build the main.c i've the following error:

 

#20 identifier "GPIO_PF1_M1PWM5" is undefined 

 

it is about the lines:

 

//Configure PF1,PF2,PF3 Pins as PWM
GPIOPinConfigure(GPIO_PF1_M1PWM5);
GPIOPinConfigure(GPIO_PF2_M1PWM6);
GPIOPinConfigure(GPIO_PF3_M1PWM7);

 

how can I solve this problem?

 

THANKS!!!
 

Share this post


Link to post
Share on other sites

Unfortunately ,I'm not getting any PWM output on the Led's  ,

I copy pasted the same code .

 

 

 

This code worked for me. Are you getting any errors or warnings?

Share this post


Link to post
Share on other sites

No I tried it again ,
I am not getting any errors and warnings .

What am i expected to observe in the LED's

I just see a whitish light without any fading .
I tried matching the dutycycle and changing the period according to my needs to achieve fading  ,but to no avail .

Share this post


Link to post
Share on other sites

Solving undefined identifiers error:

#define GPIO_PB6_M0PWM0         0x00011804
#define GPIO_PB7_M0PWM1         0x00011C04
#define GPIO_PB4_M0PWM2         0x00011004
#define GPIO_PB5_M0PWM3         0x00011404
#define GPIO_PE4_M0PWM4         0x00041004
#define GPIO_PE5_M0PWM5         0x00041404
#define GPIO_PF1_M1PWM5         0x00050405
#define GPIO_PF2_M1PWM6         0x00050805
#define GPIO_PF3_M1PWM7         0x00050C05

Share this post


Link to post
Share on other sites

 

Solving undefined identifiers error:

#define GPIO_PB6_M0PWM0         0x00011804
#define GPIO_PB7_M0PWM1         0x00011C04
#define GPIO_PB4_M0PWM2         0x00011004
#define GPIO_PB5_M0PWM3         0x00011404
#define GPIO_PE4_M0PWM4         0x00041004
#define GPIO_PE5_M0PWM5         0x00041404
#define GPIO_PF1_M1PWM5         0x00050405
#define GPIO_PF2_M1PWM6         0x00050805
#define GPIO_PF3_M1PWM7         0x00050C05

Did you include the gpio.h file and driverlib?

Share this post


Link to post
Share on other sites

Yes. gpio.h uses pin_map.h, which has no declaration of these pins for StellarisPad (at least in energia). I took those #defines directly from TivaWare C Series 1.1 pin_map.h. It seems to work for Tiva pads.

Share this post


Link to post
Share on other sites

Hi,

 

I tried porting it to Energia  TIVA board :

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/pwm.h"
#include "inc/tm4c123gh6pm.h" //added

void setup()
{   
     unsigned long ulPeriod;

    //Set the clock
   SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC |   SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

   //Configure PWM Clock to match system
   SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

   // Enable the peripherals used by this program.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);  //The Tiva Launchpad has two modules (0 and 1). Module 1 covers the LED pins
    ulPeriod = SysCtlClockGet() / 200; //PWM frequency 200HZ

    //Configure PF1,PF2,PF3 Pins as PWM
    GPIOPinConfigure(GPIO_PF1_M1PWM5);
    GPIOPinConfigure(GPIO_PF2_M1PWM6);
    GPIOPinConfigure(GPIO_PF3_M1PWM7);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    //Configure PWM Options
    //PWM_GEN_2 Covers M1PWM4 and M1PWM5
    //PWM_GEN_3 Covers M1PWM6 and M1PWM7 See page 207 4/11/13 DriverLib doc
    PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC); 
    PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC); 

    //Set the Period (expressed in clock ticks)
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, ulPeriod);
    PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, ulPeriod);

    //Set PWM duty-50% (Period /2)
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,ulPeriod/2);
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,ulPeriod/2);
    PWMPulseWidthSet(PWM1_BASE, PWM_OUT_7,ulPeriod/2);

    // Enable the PWM generator
    PWMGenEnable(PWM1_BASE, PWM_GEN_2);
    PWMGenEnable(PWM1_BASE, PWM_GEN_3);

    // Turn on the Output pins
    PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT |PWM_OUT_6_BIT|PWM_OUT_7_BIT, true);
}
   
    void loop()
    {

    }


I get errors:

pwmtiva.ino:28:22: error: 'GPIO_PF1_M1PWM5' was not declared in this scope
apwmtiva.ino:29:22: error: 'GPIO_PF2_M1PWM6' was not declared in this scope
apwmtiva.ino:30:22: error: 'GPIO_PF3_M1PWM7' was not declared in this scope

I don't understand because GPIO_PF1_M1PWM5, GPIO_PF1_M1PWM6, GPIO_PF1_M1PWM7 are defined in driverlib/pin_map.h.

Thanks for help.

Salutations.

Bernard

Share this post


Link to post
Share on other sites

Hi @@brownfox

 

 I think you have to include PART_TM4C123GH6PM here, in the project properties, under predefined symbols:

 

5YnrB.PNG

 

In your case use PART_TM4C123GH6PM instead of the LM4F120.

 

Happy Christmas

Share this post


Link to post
Share on other sites

hi,

 

Thanks gonya707 but I don't use CCS.

 

Just trying to port your example to Energia.

 

happy Christmas

 

Bernard.

Share this post


Link to post
Share on other sites

@@brownfox Using PMW on Energia should be easier.

 

Just try something like this as an example:



#define FREQ 50000 //Hz
#define PIN PD_0 //pin D0

void setup(){
  analogFrequency(FREQ);

}

void loop(){
  
  int i=0;
  
  analogWrite(PIN, i);
  i = (i + 1) % 256;
  delay(30);

}

Share this post


Link to post
Share on other sites

Hello,

 

Thank you  Gonya707

 

I know this way of getting pwm on energia but I wanted to use pwm capability of TM4C123GH6PM.

 

I am sure it is possible but I am not skilled enough to deal with,  although I  learn every day .

 

so far I get a white LED ( mix of rgb )

 

May be the clock speed ... I wonder if clock speed (80 Mhz)  can be changed on Energia .

 

Salutations.

Share this post


Link to post
Share on other sites

HI,

To have alternate pins functions available, you must take two actions:

1) insert this: #include "driverlib/pin_map.h" at the beginning of your file;

2) check to have defined both PART_LM4Cxxxxx (write here the exact type of your micro) and TARGET_IS_BLIZZARD_RA1. The last one is useful in calling ROM_ prefixed functions.

 

But above all, first you need to check if your micro has the PWM module, since it is not present on all devices, even these has the same number of pins.

 

L

Share this post


Link to post
Share on other sites

@@Lyon Thanks, but I'm still missing something with this;

I put 1) at the very top of the project instead of later, to try that

2)are both included in my Makefile, PART=TM4C123GH6PM, as copied from my Tiva board's examples.

built and flashed again, no change in LEDs from earlier. Ran make clean before make...

Share this post


Link to post
Share on other sites

Hi,

I checked the posted code and compile correctly, with shown settings. I have slightly modified it, to allow ROM functions calls. The tested version is this:

 

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/pwm.h"
#include "driverlib/rom.h"

int
main(void)
{ unsigned long ulPeriod;

    ROM_FPUEnable();
ROM_FPUStackingEnable();

//Set the clock
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL |SYSCTL_OSC_MAIN |
         SYSCTL_XTAL_16MHZ);

//Configure PWM Clock to match system
ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_1);

// Enable the peripherals used by this program.
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); //The Tiva Launchpad has two modules (0 and 1). Module 1 covers the LED pins
ulPeriod = ROM_SysCtlClockGet() / 200; //PWM frequency 200HZ

//Configure PF1,PF2,PF3 Pins as PWM
ROM_GPIOPinConfigure(GPIO_PF1_M1PWM5);
ROM_GPIOPinConfigure(GPIO_PF2_M1PWM6);
ROM_GPIOPinConfigure(GPIO_PF3_M1PWM7);
ROM_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

//Configure PWM Options
//PWM_GEN_2 Covers M1PWM4 and M1PWM5
//PWM_GEN_3 Covers M1PWM6 and M1PWM7 See page 207 4/11/13 DriverLib doc
ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);

//Set the Period (expressed in clock ticks)
ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, ulPeriod);
ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, ulPeriod);

//Set PWM duty-50% (Period /2)
ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,ulPeriod/2);
ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,ulPeriod/2);
ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_7,ulPeriod/2);

// Enable the PWM generator
ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_2);
ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_3);

// Turn on the Output pins
ROM_PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT |PWM_OUT_6_BIT|PWM_OUT_7_BIT, true);

//Do nothing
while(1)
{

}

}
 

For the next several days I do not have an board available to test it...

The settings are here:

 

// tried to post a picture, but seems to not work… 

DEBUG
PART_TM4C123GH6PM
TARGET_IS_BLIZZARD_RA1
gcc

 

Check again - or at least post the errors or some settings.

L

larryfraz likes this

Share this post


Link to post
Share on other sites

Hi,

Please review your defines, hope this one: PART=TM4C123GH6PM is only a typing mistake. It should be PART_TM4C123GH6PM.

L

larryfraz likes this

Share this post


Link to post
Share on other sites

Same light, no change. This is the output I'm getting, and the makefile ("non-restricted" not a copy of TI's; that may be where I'm over my head here).

zadok@new-host-3 tiva_pwm]$ make

Compiling tiva_pwm.c...
arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -O0 -ffunction-sections -fdata-sections -MD -std=c99 -Wall -pedantic -c -g -I ../../../../ -DPART_TM4C123GH6PM -c -DTARGET_IS_BLIZZARD_RA1 tiva_pwm.c -o tiva_pwm.o

Compiling startup_gcc.c...
arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -O0 -ffunction-sections -fdata-sections -MD -std=c99 -Wall -pedantic -c -g -I ../../../../ -DPART_TM4C123GH6PM -c -DTARGET_IS_BLIZZARD_RA1 startup_gcc.c -o startup_gcc.o

Compiling LM4F_startup.c...
arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -O0 -ffunction-sections -fdata-sections -MD -std=c99 -Wall -pedantic -c -g -I ../../../../ -DPART_TM4C123GH6PM -c -DTARGET_IS_BLIZZARD_RA1 LM4F_startup.c -o LM4F_startup.o
LM4F_startup.c:72:5: warning: ISO C forbids initialization between function pointer and 'void *' [-pedantic]
LM4F_startup.c:72:5: warning: (near initialization for 'myvectors[0]') [-pedantic]

Making driverlib
make -C ../../../../driverlib/
make[1]: Entering directory `/home/zadok/tools/driverlib'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/zadok/tools/driverlib'

Linking...
arm-none-eabi-ld -T LM4F.ld --gc-sections -o main.axf tiva_pwm.o startup_gcc.o LM4F_startup.o ../../../../driverlib/gcc-cm4f/libdriver-cm4f.a /home/zadok/tools/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/softfp/libm.a /home/zadok/tools/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/softfp/libc.a /home/zadok/tools/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/armv7e-m/softfp/libgcc.a

Copying...
arm-none-eabi-objcopy -Obinary main.axf main.bin

Creating list file...
arm-none-eabi-objdump -S main.axf > main.lst
[zadok@new-host-3 tiva_pwm]$ sudo lm4flash main.bin
[sudo] password for zadok:
Found ICDI device with serial: 0E20092F
ICDI version: 9270
 

Makefile.txt

Share this post


Link to post
Share on other sites

Going back to using TI's startup_gcc and Makefile, I get

make: *** No rule to make target `tiva_pwm.ld', needed by `gcc/tiva_pwm.axf'.  Stop.

Share this post


Link to post
Share on other sites

Hi,

There some problems with your project:
1) You do not need two initializations files, namely startup_gcc.c and LM4F_startup.c. Remove the last one from your project and keep only that from TI (although small changes are needed, later…). As you note, you get some warnings, while the first one compiles OK.
2) Do not know what is LM4F.ld - if from the same author like Makefile, then could be buggy, and bugs shows up when used on little bit more bigger/complex projects than blinky one.
3) The linker must be called from gcc, not directly - this is the recommendation and the good practice. Good to pass the switch -nostartfiles, since you provide your own in startup_gcc.c
4) The Makefile uses some settings from TI for working with floating point (uses softfp libraries) - for this project may not be important, but if really using fp, the hardfp library could be an advantage (is smaller than softfp).
5) The paths: I do not know where this project is created - TI recommendation is to be done inside StellarisWare/TivaWare folder - so if yours is not there, again, the paths shown in Makefile could cause problems. I do not use TI recommendation, made the project elsewhere and add the right path. Correct yours, add them to Makefile (where points this: STELLARISWARE_PATH=../../../../  ??).
6) If you prefix your calls with ROM_ as I have done, then you do not need to compile/link the driverlib, since it is included on-chip.
7) A much more easier approach is to use Eclipse+GCC - together with GNU ARM Eclipse  plug-in (from here: http://sourceforge.net/projects/gnuarmeclipse/)- you do not need to write Makefiles, all this process is managed by the plug-in (it is called "managed make"). 
8) If you will get warnings from compiling startup_gcc.c, I will tell you how to avoid them.
 
L
larryfraz likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0