MEVIHUB

DC Motor Speed Control By Potentiometer using TMS320

Overview

This instructable will guide you on how to control the speed of a Dc motor with a potentiometer and a TMS320

Required Hardware Components

Software:

Gpio Connection

S.ṆOGPIO_PINLaunchpad pin numberName of the component
1ADCINA0Pin number 30Potentiometer
2GPIO0EPWM1A 40Oscilloscope
3Motor(GPIO_0)Connected to relay 

Connect the Potentiometer

  1. Connect the negative pin of the potentiometer to GNDPIN on the TMS320.
  2. Connect the signal pin of the potentiometer to ADCINA0on the TMS320.
  3. Connect the positive pin of the potentiometer to 5VPIN on the TMS320.

Connect the motor

Potentiometer

A potentiometer is a three-terminal electrical and electronic component that has the ability to change its resistance by rotating or statically moving. The potentiometer can be used in two configurations where you can change the voltage or change the resistance.

Your next project may require motor speed control.

Can you use a potentiometer to control engine speed? Yes, you can use a potentiometer to control the speed of the motor. When used to change the voltage, a potentiometer can be connected to a motor and change the voltage (and therefore power) delivered to a motor that controls its speed. I will discuss the circuit setup above and a couple of other settings you can use to control motor speed with a potentiometer.

How to control motor speed with potentiometer: using TMS320

The TMS320 is needed because it has a microcontroller that has the ability to produce pulse width modulation (PWM) on some of its dedicated pins. Note that you are not limited to using TMS320 only. As long as you have a microcontroller that can do PWM, you’ll be fine.

What is PWM?

PWM is a technology used to vary the average power supplied to electrical and electronic devices. It is a digital waveform signal that varies between two values; high and low.

The amount of time the TMS320 pin is HIGH versus LOW is known as the duty cycle, which ultimately determines the average power.

Below are a couple of different PWM waveforms with different duty cycles.

So if the duty cycle is 75% and the supply voltage is 5V, the total voltage at the output is now 3.75V (0.75 x 5). This is great since we can use PWM to control the speed of the motor.

But where does the potentiometer come from?

The potentiometer is used to change the duty cycle of the PWM through the TMS320 Analog to Digital Converter (ADC). Therefore, it directly controls the speed. Below is the circuit to use a potentiometer and TMS320 to control motor speed.

Step by step execution process

1st initialize the epwm gpio pins

///////////////////////////////////////////////////////////////

void PinMux_init()
{
    EALLOW;
    //EPWM1 -> myEPWM1 Pinmux

    GpioCtrlRegs.GPAMUX1.all=0;// gpio 15 to gpio 0 a;; general purpouse I/O
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=1;// epwm active
    EDIS;

}

2nd configure the epwm signal

/////////////////////////////////////////////////////////////////////// 

void initEPWM1()
{

        EPwm1Regs.TBPRD = 4000;       // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;
       // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = Adc_Result_1;    // Set compare A value
      // Setup counter mode
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

       EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM1A on event A, up
      // count
       EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;          // Clear PWM1A on event A,
                                                    // down count

}

Here  EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;

       EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;          // Clear PWM1A on event A,         // down count

                                          

Mean when your PWM pulses reach the setpoint(CMPA) then your pulse will be set to high and low

3rd configure the adc resolution

///////////////////////////////////////////////////////////////////////////

void ConfigADC(uint32_t ADC_BASE)
{
    EALLOW;
    AdcaRegs.ADCCTL2.bit.PRESCALE=4;  // 200/4 50 MHz
//    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);

#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setMode(ADC_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
    }
#elif(EX_ADC_RESOLUTION == 16)
    {
      ADC_setMode(ADCA_BASE, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL);
    }
#endif
    ADC_setInterruptPulseMode(ADC_BASE, ADC_PULSE_END_OF_CONV);
    ADC_enableConverter(ADC_BASE);
    DEVICE_DELAY_US(1000);
    EDIS;
}

4th initialize the adc_soc

//////////////////////////////////////////////////////////////


void initADC_SOC(void)
{
#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 15);


    }
#elif(EX_ADC_RESOLUTION == 16)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0,64);
    }
#endif
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);


    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);

    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);


}

// Convert, wait for completion, and store results

        ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);

   ////           // Store results

Adc_Result_1= ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);

Final Code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "F2837xD_device.h"
#include "F28x_Project.h"
#include "F2837xD_Examples.h"

#include "driverlib.h"
#include "device.h"

#define     EX_ADC_RESOLUTION       12

void gpio_init();
void ConfigADC(uint32_t ADC_BASE);
void initADC_SOC(void);

void PinMux_init();
void initEPWM1();

uint16_t Adc_Result_1,Adc_Result_2;
int ref_i,ref_h,ref_l;
void main(void)
{

    Adc_Result_1=0;
    Adc_Result_2 =0;

    Device_init();
    Device_initGPIO();
    PinMux_init();

    Interrupt_initModule();
    Interrupt_initVectorTable();
    IER = 0x0000;
          IFR = 0x0000;
          SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
          SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    ConfigADC(ADCA_BASE);
    initADC_SOC();

    EINT;
    ERTM;

    while(1)
       {

        // Convert, wait for completion, and store results
           ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);

            while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false)
                {

                }
            ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

            ////           // Store results
              Adc_Result_1= ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
              initEPWM1();
              DEVICE_DELAY_US(10000);
       }


}


void initEPWM1()
{

        EPwm1Regs.TBPRD = 4000;       // Set timer period 801 TBCLKs
        EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
        EPwm1Regs.TBCTR = 0x0000;
       // Set Compare values
        EPwm1Regs.CMPA.bit.CMPA = Adc_Result_1;    // Set compare A value
      // Setup counter mode
       EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
       EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable phase loading
       EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
       EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

       EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;            // Set PWM1A on event A, up
      // count
       EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;          // Clear PWM1A on event A,
                                                    // down count

}



void PinMux_init()
{
    EALLOW;
    //EPWM1 -> myEPWM1 Pinmux


    GpioCtrlRegs.GPAMUX1.all=0;// gpio 15 to gpio 0 a;; general purpouse I/O
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=1;// epwm active
    EDIS;

}


void ConfigADC(uint32_t ADC_BASE)
{
    EALLOW;
    AdcaRegs.ADCCTL2.bit.PRESCALE=4;  // 200/4 50 MHz
//    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);

#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setMode(ADC_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
    }
#elif(EX_ADC_RESOLUTION == 16)
    {
      ADC_setMode(ADCA_BASE, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL);
    }
#endif
    ADC_setInterruptPulseMode(ADC_BASE, ADC_PULSE_END_OF_CONV);
    ADC_enableConverter(ADC_BASE);
    DEVICE_DELAY_US(1000);
    EDIS;
}



void initADC_SOC(void)
{
#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 15);


    }
#elif(EX_ADC_RESOLUTION == 16)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0,64);
    }
#endif
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);


    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);

    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);


}


//
// End of File
//

Output Images

Exit mobile version