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.

TM4C123GH6PM: PWM to drive servo motor in TM4C123GH6PM

Part Number: TM4C123GH6PM

Hello everyone,

I am using Tiva TM4C123GH6PM  workshop workbook which I have attached below.Currently I am doing PWM Module experiment  to drive Servo motor which is on page no. 321 of the workshop workbook.

In this program  as it is mentioned in the manual, 83 is the center position to create a 1.5mS pulse from the PWM.Here’s how we came up with 83 … In the servo control code (covered shortly) we’re going to divide the PWM period by 1000. Since the programmed frequency is 55HZ and the period is 18.2mS, dividing that by 1000 gives us a pulse resolution of 1.82μS. Multiplying that by 83 gives us a pulse-width of 1.51mS. Other selections for the resolution, etc.would be just as valid as long as they produced a 1.5mS pulse-width. Take care though to be sure that your numbers will fit within the 16-bit registers.

Question 1.Why in the formula PWM Period is divided by 1000?

Question 2.Can we take any other Center frequency?

Question 3.What is meant by pulse resolution in this case?

Question 4.In the program ui8Adjust variable is taken which is in between 56 and 111.Is that mean motor will rotate in between 56 and 111 degrees or something else?

4762.TM4C123G_LaunchPad_Workshop_Workbook.pdf

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/debug.h"
#include "driverlib/pwm.h"
#include "driverlib/pin_map.h"
#include "inc/hw_gpio.h"
#include "driverlib/rom.h"
#define PWM_FREQUENCY 55
int main(void)
{
volatile uint32_t ui32Load;
volatile uint32_t ui32PWMClock;
volatile uint8_t ui8Adjust;
ui8Adjust = 83;
ROM_SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_64);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
ROM_GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0);
ROM_GPIOPinConfigure(GPIO_PD0_M1PWM0);
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;

HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
ROM_GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_DIR_MODE_IN);
ROM_GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4|GPIO_PIN_0, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
ui32PWMClock = SysCtlClockGet() / 64;
ui32Load = (ui32PWMClock / PWM_FREQUENCY) - 1;
PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN);
PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, ui32Load);
ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);
ROM_PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT, true);
ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_0);
while(1)
{
if(ROM_GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4)==0x00)
{
ui8Adjust--;
if (ui8Adjust < 56)
{
ui8Adjust = 56;
}
ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);
}
if(ROM_GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_0)==0x00)
{
ui8Adjust++;
if (ui8Adjust > 111)
{
ui8Adjust = 111;
}
ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);
}
ROM_SysCtlDelay(100000);
}
}

  • Abhishek Dutta said:
    Question 1.Why in the formula PWM Period is divided by 1000?

    The value 1000 is somewhat arbitrary. It causes the PWM period to be divided into 1000 steps. For this servo example that does not matter, but for other PWM examples each step would be 0.1%.

    Abhishek Dutta said:
    Question 2.Can we take any other Center frequency?

    I am not sure what you mean be center frequency. The pulse width of 1.5ms is the center position of the servo. That is a function of the servo. The frequency must be form 50Hz to 60Hz. That is also a requirement of the servo. In this example we used 55Hz.

    Abhishek Dutta said:
    Question 3.What is meant by pulse resolution in this case?

    The pulse resolution is the size the pulse will change for each increment of the value "ui8Adjust".

    Abhishek Dutta said:
    Question 4.In the program ui8Adjust variable is taken which is in between 56 and 111.Is that mean motor will rotate in between 56 and 111 degrees or something else?

    No, ui8Adjust = 56 gives a 1mS pulse, and ui8Adjust = 111 gives a 2mS pulse. These values represent the range of the servo,

  • Sir but I want to rotate the servo motor from 0 degree to 180 degree and vice-versa.

    So, what should be the logic behind the above mentioned question?

  • I am really not sure which question you are referring to. If you want a function that sets the servo based on a value of 0 to 180 degrees, and 56 equals 0 degrees, and 111 equals 180 degrees, then you simply scale and offset your value in degrees to create the appropriate adjust number. The function might look like this:

    void position_servo(uint8_t ui8Degrees, uint32_t ui32Load) // Servo position from 0 to 180 degrees
    {
        uint8_t ui8Adjust;
    
        if (ui8Degrees > 180)
        {
           ui8Adjust = 111;
        }
        else
        {
            ui8Adjust = 56.0 + ((float)ui8Degrees * (111.0 - 56.0)) / 180.0;
        }
        ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0, ui8Adjust * ui32Load / 1000);
    }
    

  • Abhishek Dutta said:

    Sir but I want to rotate the servo motor from 0 degree to 180 degree and vice-versa.   So, what should be the logic behind the above mentioned question?  

    Is it fair to note that,  "No such,  "0 degree to 180 degree" question - appeared - either (above) nor elsewhere in your opening post!      So - what was the logic in, "Failing to ask (so vital) a question?"

    Vendor has provided solid guidance - the responsibility  to list clear (and all) questions - rests w/you... 

  • Thank you sir for your reply.I will definitely try this logic now.
  • Dear sir,
    I referred to this statement "Sir but I want to rotate the servo motor from 0 degree to 180 degree and vice-versa."Any ways I got my answer I will try the above mentioned logic now.