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.

PWM Motor Drive using Driverlib with MSP432P401r and SN754410

Other Parts Discussed in Thread: SN754410

Hello,

I am trying to drive left & right wheels attached to two motors using SN7554410 Quad bridge on MSP432 P401R. I am trying to drive forward with PWM signal sent to P2.4/P2.5/P2.6/P2.7 as peripheral. P1.6 & P1.7 are the enable pins. Switch P1.1 drives the motor forward and Switch P1.4 drives it backward using using PWM signal and TIMER_A0. The duty cycle is to be incremented by 33% each time it is pressed and then resets to 0, when it reaches maximum value (10000). The code is attached. I am not able to get any movement on the motor. Can some one please help? It has to be done using the driver library commands. Comments are added in the code and connections are all checked.

 Here is the code:

/*******************************************************************************
* MSP432_P401r Timer_A - PWM Two Motor Drive
*
* Description: The purpose of this code is to drive a robot using Left & Right motors using SN754410.
* Switch 1 (P1.1) drives motor forward on both sides & Switch 2 (P1.4) drives motor backward.
* Timer_A0 is used. Motor speed control is at 33.33%, 66.66%, & 100% of duty cycle 10000.
*
*
*******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>


/* Timer A PWM Configuration via "struct" populated at the beginning of the program */
/* Define macros and function prototypes if needed */

//extern Timer_A_PWMConfig pwmConfig =

Timer_A_PWMConfig pwmConfig=
{
TIMER_A_CLOCKSOURCE_SMCLK,
TIMER_A_CLOCKSOURCE_DIVIDER_1, // No divider we'll use DCOfreq 3.0MHz--> period=1/3.0MHz=0.33us
10000, //Our period=3.3ms; clock period ticks=3.3ms/0.33us=10000 clock ticks
//TIMER_A_CAPTURECOMPARE_REGISTER_4, //CCR4 location register of TA0.4,P2.7-->4A
//TIMER_A_CAPTURECOMPARE_REGISTER_3, //CCR3 location register of TA0.3,P2.6-->3A
//TIMER_A_CAPTURECOMPARE_REGISTER_2, //CCR2 location register of TA0.2,P2.5-->2A
TIMER_A_CAPTURECOMPARE_REGISTER_1, //CCR1 location register of TA0.1,P2.4-->1A
//TIMER_A_CAPTURECOMPARE_REGISTER_0, //CCR0
TIMER_A_OUTPUTMODE_RESET_SET, // Module 7 functionality (PWM signal)
3300 // Set duty cycle to 33%; 0.33*10000=3300
};

//![Simple Timer_A Config]

volatile uint32_t counter = 0;

/* GPIO & Port initialization function */
void init () {
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1|GPIO_PIN4);//Set S1 & S2 as input pull-up resistors
// For Lab4: it is easier to use Polling instead of interrupts to monitor S1 & S2 Buttons

/* Set GPIO Port 1.6: Enable 1,2EN of SN754410 Quadruple Half-H Driver:Right Motor as output pin */
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN6);

/* Set GPIO Port 1.6:Enable 1,2EN of SN754410:Right Motor as output LOW to be turned on by polling */
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN6);

/* Set GPIO Port 1.7: Enable 3,4EN of SN754410 Quadruple Half-H Driver:Left Motor as output pin */
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN7);

/* Set GPIO Port 1.7:Enable 3,4EN of SN754410:Left Motor as output LOW to be turned on by polling */
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7);


}


int main(void)
{
/* Halting the watchdog */
WDT_A_holdTimer();
//unsigned int dcoFrequency = 3.0E+6;

//mechrev_setup();
//setup clock signal
//MAP_CS_setDCOFrequency(dcoFrequency); //set DCO clock source frequency
MAP_CS_setDCOFrequency(3000000); //set DCO clock source frequency

MAP_CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1);
//MAP_CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); // tie SMCLK to DCO

init(); // Call function "init": GPIO & Port initialization

// as peripheral output for PWM

//MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN3,GPIO_PRIMARY_MODULE_FUNCTION); /* P7.3 is TA0.0 */
//Set output pins of Timer A0: pins 2.4,2.5,2.6&2.7 for TA0.1,TA0.2,TA0.3,TA0.4 --> 1A,2A,3A,4A (SN754410)
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4|GPIO_PIN5|GPIO_PIN6| GPIO_PIN7,
GPIO_PRIMARY_MODULE_FUNCTION);

// Write PWM Configuration initial duty cycle 33% = 3300 with a period of 3.3ms
//MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);

//
//-------------------------

//Interrupt Configuration
Interrupt_disableMaster(); // Disable interrupts to enter critical section
GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1 |GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION);
GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1 |GPIO_PIN4);
GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1 |GPIO_PIN4);
Interrupt_enableInterrupt(INT_TA0_0);
Interrupt_enableMaster();

//MAP_Interrupt_enableInterrupt(Timer);
MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig);
MAP_Timer_A_clearInterruptFlag(TIMER_A0_BASE);
MAP_Timer_A_enableInterrupt(TIMER_A0_BASE);
MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);

/* Enabling MASTER interrupts */
MAP_Interrupt_enableMaster();

/* Sleeping when not in use */
/*
while (1)
{
MAP_PCM_gotoLPM0();
} */


}

/* Port1 ISR - This ISR will progressively step up the duty cycle of the PWM
* on a button press
*/

//void PORT1_IRQHandler(void)
void TA0_0_IRQHandler(void)
{
uint32_t status;
/*uint_fast16_t GPIO_getEnabledInterruptStatus ( uint_fast8_t selectedPort )
This function gets the interrupt status of the provided PIN and masks it with the interrupts that are
actually enabled. This is useful for inside ISRs where the status of only the enabled interrupts
needs to be checked.*/
status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
if (status & GPIO_PIN1){
//Right Motor Drive
// Enable (High) P1.6-->1,2EN; and P1.7-->3,4EN (HIGH)
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN6);
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN7);
//--------------
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2,GPIO_PIN4);
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2,GPIO_PIN5);
//---------------
//Increase duty cycle on P2.4 (TA0CCR1-->1A) Right Motor & P2.7 (TA0CCR4-->4A) Left Motor
TA0CCR2=0;
TA0CCR3=0;
TA0CCR1=+3300; //33% of 10000 (TA0CCR1-->1A) Right Motor
TA0CCR4=+3300; //33% of 10000 (TA0CCR1-->4A) Left Motor
if (TA0CCR1>10000 || TA0CCR4>10000){
TA0CCR1 = 0;
TA0CCR4 = 0;
}
int i;
for (i = 0; i < 5000; i++) {} //delay loop

counter++;
}
else if (status & GPIO_PIN4) {

// Enable (High) P1.7-->3,4EN
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN6);
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN7);
// Wait until pin is released (empty loop),
while(MAP_GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN4) == GPIO_INPUT_PIN_LOW){}
//Goes to infinite loop polling because it is receiving input 0 from button S2
//------------------------commented out----should be high
//MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7);
//MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN6); // when released input value becomes high & Output
// is set to LOW.
//-------------------------
//Increase duty cycle on P2.5 (TA0CCR2-->2A) Right Motor & P2.6 (TA0CCR3-->3A) Left Motor
TA0CCR1=0;
TA0CCR4=0;
TA0CCR2=+3300; //33% of 10000 (TA0CCR2-->2A) Right Motor
TA0CCR3=+3300; //33% of 10000 (TA0CCR3-->3A) Left Motor
if (TA0CCR2>10000 || TA0CCR3>10000){
TA0CCR2 = 0;
TA0CCR3 = 0;
}
int i;
for (i = 0; i < 5000; i++) {} //delay loop
counter++;
}

//MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);

/* Here to continue haile
MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_0);
*/
//h MAP_Timer_A_setCompareValue(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1, value);
/*
uint32_t status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

if (status & GPIO_PIN1)
{
if(pwmConfig.dutyCycle == 28800)
pwmConfig.dutyCycle = 3200;
else
pwmConfig.dutyCycle += 3200;

MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
}*/
//clear port1 interrupt

MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

}

  • Hello,

    Thank you for posting to the forum.

    Can you measure the voltage at the input signals? Let's first check if the input signals coming from the MCU to the driver are correct. If you have an oscilloscope, it would be good to view the voltage waveform of each of the control input signals.

  • Hi Pablo,

    Thank you for your reply. Unfortunately, I do not have an oscilloscope. But, the motors were running fine from the battery without PWM and timer. I know this doesn't help. But, I just want to see I am making in the code itself with the Module 7 RSET_SET functionality.

  • >MAP_Timer_A_enableInterrupt(TIMER_A0_BASE);

    This enables TAIE, but I don't see a TA0_N_IRQHandler for it, so the program will go to Default_Handler after the first 3.3ms. You don't seem to need this interrupt, so I recommend you just remove this line.

    ------------------------------

    //MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);

    You've commented this line in TA0_0_IRQHandler, but you need to do this or the interrupt will keep firing continuously. I recommend you un-comment this line.

  • Hi Haile,

    If the device is functioning properly, then it could mean there might be something wrong with the code. If you have a voltage meter and measure the voltage at the IN1 and IN2 signals, it will give a good indication if the MCU is outputting the proper PWM signals. If the voltages are 0-V, then that'll explain why the driver is not driving the load.

  • Hi Bruce,

    I did the changes but still not working. I hear some low noise high pitch sound and that's it. Is there any example code with driverlib that generates PWM with RESET_SET mode to Pin2.4, 2.5, 2.6, 2.7 to drive left and right motors by pressing Pin1.1 & Pin1.4?

    Many thanks for the help.

  • Hi Pablo,

    Thanks for the suggestion, I will try to do that. But, does the code look ok for the functionality point of view?

  • When I run this code and push the P1.1 button I see P2.4 generating PWM at about 300Hz (3.3ms period) with a duty of about 30% (1ms high period). If I then push the P1.4 button the activity stops. Pushing P1.1 (or P1.4) repeatedly has no additional effect. I see no activity on P2.5-7 (constant low). What behavior do you expect to see?

    It appears you only call MAP_Timer_A_generatePWM() using TIMER_A_CAPTURECOMPARE_REGISTER_1. If you want to generate PWM on P2.5-7 you should call it again using (each of) TIMER_A_CAPTURECOMPARE_REGISTER_2, _3, and _4. (Keep the period the same for all calls, though you can change the duty cycle for each call if you want.)

    [Edit: Also

    >TA0CCR1 = +3300; //33% of 10000 (TA0CCR1-->1A) Right Motor

    I suspect you meant:

    >TA0CCR1 += 3300; //33% of 10000 (TA0CCR1-->1A) Right Motor

    ]

  • Hi Bruce,

    You're the best! I was just experimenting before I read your message and found out exactly as you pointed out. According to my code, although slightly modified since, P2.7 (CCR4) &P2.4 (CCR1) are driving one motor in reverse and P2.6 (CCR3) & P2.5 (CCR2) are driving in opposite direction. I am going to modify it further per your suggestion regarding calling TIMER_A_CAPTURECOMPARE_REGISTER_2, _3, and _4 and will let you know. But, here is what I want to achieve:

    1. By Pressing switch/button P1.1, I want both motors to drive in one direction (dutycycle=3300); and it should stop when it is released. Press it 2nd time, the duty cycle should increase to 6600; stops when released. Press it 3rd time duty cycle/speed increases to 100% (100000) and stops on release. Press it fourth time duty cycle goes to zero and further pressing goes back to 33% (3300) duty cycle...

    2. By pressing Switch/Button P1.4, both motors should drive in the opposite direction in the same fashion.

    3. Pressing P1.1 or P1.4 should at any point should also continue from the duty cycle it left off. e.g. If P1.1 was released at the 66% (6600) duty cycle and come back to it after pressing P1.4 to drive backward, then upon pressing P1.1 again it should increment to 100% (10000) duty cycle and drive forward, and vice-versa.

    4. As it stands now, the connections are: On the SN754410: (i) P1.6 is connected to 1,2EN; P2.4 & P2.5 are PW inputs connected to the Right Motor (and changing One High & and the other low would change the direction) (ii) P1.7 is connected to 3,4EN; P2.6 & P2.7 are PWM inputs connected to the Left motor (and changing One High & and the other low would change the direction).

    5. I am trying to use PORT1_IRQHandler for ISR to detect the button pressing instead of polling.

    ====================Code========================

    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>

    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>

    /* Timer A PWM Configuration via "struct" populated at the beginning of the program */
    /* Define macros and function prototypes if needed */

    //extern Timer_A_PWMConfig pwmConfig =

    Timer_A_PWMConfig pwmConfig=
    {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1, // No divider we'll use DCOfreq 3.0MHz--> period=1/3.0MHz=0.33us
    10000, //Our period=3.3ms; clock period ticks=3.3ms/0.33us=10000 clock ticks
    //TIMER_A_CAPTURECOMPARE_REGISTER_4, //CCR4 location register of TA0.4,P2.7-->4A--->LM (stopped by P1.4) on by P1.1
    TIMER_A_CAPTURECOMPARE_REGISTER_3, //CCR3 location register of TA0.3,P2.6-->3A-----&RM (stopped by P1.1) on by 1.4
    //TIMER_A_CAPTURECOMPARE_REGISTER_2, //CCR2 location register of TA0.2,P2.5-->2A-----&RM
    //TIMER_A_CAPTURECOMPARE_REGISTER_1, //CCR1 location register of TA0.1,P2.4-->1A---->LM
    //TIMER_A_CAPTURECOMPARE_REGISTER_0, //CCR0 -- Should be removed?
    TIMER_A_OUTPUTMODE_RESET_SET, // Module 7 functionality (PWM signal)
    3300 // Set duty cycle to 33%; 0.33*10000=3300
    };

    //![Simple Timer_A Config]

    volatile uint32_t counter = 0;

    /* GPIO & Port initialization function */
    void init () {
    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1|GPIO_PIN4);//Set S1 & S2 as input pull-up resistors
    // For Lab4: it is easier to use Polling instead of interrupts to monitor S1 & S2 Buttons

    /* Set GPIO Port 1.6: Enable 1,2EN of SN754410 Quadruple Half-H Driver:Right Motor as output pin */
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN6);

    /* Set GPIO Port 1.6:Enable 1,2EN of SN754410:Right Motor as output LOW to be turned on by isr */
    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN6);

    /* Set GPIO Port 1.7: Enable 3,4EN of SN754410 Quadruple Half-H Driver:Left Motor as output pin */
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN7);

    /* Set GPIO Port 1.7:Enable 3,4EN of SN754410:Left Motor as output LOW to be turned on by isr */
    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7);


    }


    int main(void)
    {
    /* Halting the watchdog */
    MAP_WDT_A_holdTimer();
    //unsigned int dcoFrequency = 3.0E+6;


    //setup clock signal
    //MAP_CS_setDCOFrequency(dcoFrequency); //set DCO clock source frequency
    MAP_CS_setDCOFrequency(3000000); //set DCO clock source frequency
    MAP_CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1);
    //MAP_CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); // tie SMCLK to DCO

    init(); // Call function "init": GPIO & Port initialization
    // as peripheral output for PWM
    //MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN3,GPIO_PRIMARY_MODULE_FUNCTION); /* P7.3 is TA0.0 */
    //Set output pins of Timer A0: pins 2.4,2.5,2.6&2.7 for TA0.1,TA0.2,TA0.3,TA0.4 --> 1A,2A,3A,4A (SN754410)

    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4|GPIO_PIN5|GPIO_PIN6| GPIO_PIN7,
    GPIO_PRIMARY_MODULE_FUNCTION);

    // Write PWM Configuration initial duty cycle 33% = 3300 with a period of 3.3ms
    //MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);

    //
    //-------------------------
    TA0CCR1=0;
    TA0CCR2=0;
    TA0CCR3=0;
    TA0CCR4=0;

    //Interrupt Configuration
    //Interrupt_disableMaster(); // Disable interrupts to enter critical section
    //GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1 |GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1 |GPIO_PIN4);
    MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1 |GPIO_PIN4);
    MAP_Interrupt_enableInterrupt(INT_PORT1);
    //MAP_Interrupt_enableInterrupt(INT_TA0_0);
    MAP_Interrupt_enableMaster();
    /* Enabling SRAM Bank Retention */
    MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);

    //MAP_Interrupt_enableInterrupt(Timer);
    MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig);
    MAP_Timer_A_clearInterruptFlag(TIMER_A0_BASE);
    //MAP_Timer_A_enableInterrupt(TIMER_A0_BASE);
    MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);

    /* Enabling MASTER interrupts */
    //MAP_Interrupt_enableMaster();

    /* Sleeping when not in use */

    while (1)
    {
    MAP_PCM_gotoLPM0(); //MAP_PCM_gotoLPM3();
    }


    }

    /* Port1 ISR - This ISR will progressively step up the duty cycle of the PWM
    * on a button press
    */

    void PORT1_IRQHandler(void)
    //void TA0_0_IRQHandler(void)
    {
    uint32_t status;
    /*uint_fast16_t GPIO_getEnabledInterruptStatus ( uint_fast8_t selectedPort )
    This function gets the interrupt status of the provided PIN and masks it with the interrupts that are
    actually enabled. This is useful for inside ISRs where the status of only the enabled interrupts
    needs to be checked.*/
    status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    if (status & GPIO_PIN1){
    //Right Motor Drive
    // Enable (High) P1.6-->1,2EN; and P1.7-->3,4EN (HIGH)
    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN6);
    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN7);
    //--------------
    //MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2,GPIO_PIN4);
    //MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2,GPIO_PIN5);
    //---------------
    //Increase duty cycle on P2.4 (TA0CCR1-->1A) Right Motor & P2.7 (TA0CCR4-->4A) Left Motor
    TA0CCR2=0;
    TA0CCR3=0;
    TA0CCR1+=3300; //33% of 10000 (TA0CCR1-->1A) Right Motor
    TA0CCR4+=3300; //33% of 10000 (TA0CCR1-->4A) Left Motor
    if (TA0CCR1>10000 || TA0CCR4>10000){
    TA0CCR1 = 0;
    TA0CCR4 = 0;
    }
    int i;
    for (i = 0; i < 5000; i++) {} //delay loop

    counter++;
    }
    else if (status & GPIO_PIN4) {

    // Enable (High) P1.7-->3,4EN
    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN6);
    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN7);
    // Wait until pin is released (empty loop),
    //while(MAP_GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN4) == GPIO_INPUT_PIN_LOW){}
    //Goes to infinite loop polling because it is receiving input 0 from button S2
    //------------------------commented out----should be high
    //MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7);
    //MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN6); // when released input value becomes high & Output
    // is set to LOW.
    //-------------------------
    //Increase duty cycle on P2.5 (TA0CCR2-->2A) Right Motor & P2.6 (TA0CCR3-->3A) Left Motor
    TA0CCR1=0;
    TA0CCR4=0;
    TA0CCR2+=3300; //33% of 10000 (TA0CCR2-->2A) Right Motor
    TA0CCR3+=3300; //33% of 10000 (TA0CCR3-->3A) Left Motor
    if (TA0CCR2>10000 || TA0CCR3>10000){
    TA0CCR2 = 0;
    TA0CCR3 = 0;
    }
    int i;
    for (i = 0; i < 5000; i++) {} //delay loop
    counter++;
    }

    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);

    /* Here to continue haile
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,
    TIMER_A_CAPTURECOMPARE_REGISTER_0);
    */
    //h MAP_Timer_A_setCompareValue(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1, value);
    /*
    uint32_t status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

    if (status & GPIO_PIN1)
    {
    if(pwmConfig.dutyCycle == 28800)
    pwmConfig.dutyCycle = 3200;
    else
    pwmConfig.dutyCycle += 3200;

    MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
    }*/
    //clear port1 interrupt

    MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);

    }

  • So, what does it do now? Polling (using a timer) isn't necessarily a bad way of detecting a button push, since it provides a measure of debouncing.

    Unsolicited: If you want to post a large amount of code, please consider attaching it [Insert->File] rather than pasting it -- or at least use Code Tags [Insert->Code].

  • Hi Bruce,

    Now it is able to drive each wheel separately, but not together. It goes through three: Low, medium, high speeds. and it is controlled by the switches. This means it is rotating one wheel separately. I wanted both wheels to rotate in the same direction with one button and in opposite direction with the other one. Any suggestions? I really appreciate your help. I did not understand fully your feedback but I modified it as I tried to understand your comment. see added parts of code below.

    On your note: I tried to use insert file/code but it gives me an error, not sure why:

    Access Denied

    You don't have permission to access "">e2e.ti.com/.../configure on this server.

    Reference #18.846096b8.1618771216.f14f7c2

    ****Here is what I added to the code***

    //------------

    Timer_A_PWMConfig pwmConfig1 =
    {
    TIMER_A_CLOCKSOURCE_SMCLK, // tie Timer A to SMCLK
    TIMER_A_CLOCKSOURCE_DIVIDER_1, //No divider we'll use DCOfreq 3.0MHz--> period=1/3.0MHz=0.33us
    10000, //Our period=3.3ms; clock period ticks=3.3ms/0.33us=10000 clock ticks
    TIMER_A_CAPTURECOMPARE_REGISTER_1, //CCR1 location register of TA0.1,P2.4-->1A---->LM
    TIMER_A_OUTPUTMODE_RESET_SET, // Module 7 functionality (PWM signal)
    3300 // Set duty cycle to 33%; 0.33*10000=3300
    };

    Timer_A_PWMConfig pwmConfig2 =
    {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1,
    10000,
    TIMER_A_CAPTURECOMPARE_REGISTER_2, //CCR2 location register of TA0.2,P2.5-->2A-----&RM
    TIMER_A_OUTPUTMODE_RESET_SET,
    3300
    };
    Timer_A_PWMConfig pwmConfig3 =
    {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1,
    10000,
    TIMER_A_CAPTURECOMPARE_REGISTER_3, //CCR3 location register of TA0.3,P2.6-->3A-----&RM
    TIMER_A_OUTPUTMODE_RESET_SET,
    3300
    };
    Timer_A_PWMConfig pwmConfig4 =
    {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1,
    10000,
    TIMER_A_CAPTURECOMPARE_REGISTER_4, //CCR4 location register of TA0.4,P2.7-->4A--->LM
    TIMER_A_OUTPUTMODE_RESET_SET,
    3300
    };

    //------in the main code added following---

    //MAP_Interrupt_enableInterrupt(Timer);
    MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig1);
    MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig2);
    MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig3);
    MAP_Timer_A_generatePWM(TIMER_A0_BASE,&pwmConfig4);

    //----------------------
    MAP_Timer_A_clearInterruptFlag(TIMER_A0_BASE);
    //MAP_Timer_A_enableInterrupt(TIMER_A0_BASE);
    MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);
    MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1);
    MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
    MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_3);
    MAP_Timer_A_enableCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_4);

    //------in the end of isr added the following---

    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1);
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_3);
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_4);

  • Pushing the P1.1 button steps through the PWM levels on P2.4/7, with P2.5/6 constant low. Pushing the P1.4 button steps through the levels on P2.5/6 with P2.4/7 constant low.

    This behavior seems to match with the code. If this doesn't have the physical effect you want, you probably should check your wiring.

    Initially (before pushing any buttons) all 4 pins are running identical PWM waveforms at about 30%. I'm not sure what the motor thinks of that.

  • Hi Bruce,

    If the 4 pins are running identical PWM waveforms, the driver outputs will be the same value so no current will flow through the motor.

  • Hi Bruce,

    That's right. The motor doesn't run until I press the button. I can also set each of them to zero, and then increment is by 3300 as in the code: e.g. for one pwmconfig struct:

    Timer_A_PWMConfig pwmConfig2 =
    {
    TIMER_A_CLOCKSOURCE_SMCLK,
    TIMER_A_CLOCKSOURCE_DIVIDER_1,
    10000,
    TIMER_A_CAPTURECOMPARE_REGISTER_2, //CCR2 location register of TA0.2,P2.5-->2A-----&RM
    TIMER_A_OUTPUTMODE_RESET_SET,
    0
    };

    The issue is when I press P1.1 or 1.4, it only runs forward one motor at a time and not together and definitely not in reverse.

    I checked the wiring and it looks fine. I expected when P1.1 is pressed TA0CCR1 (P2,4) PWM with TA0CCR2=0 (P2.5) & P2.7 (TA0CCR4) PWM with P2.6 ((TA0CCR3=0, drive drive both motors forward and when P1.4 is pressed the reverse to happen.

  • If you're getting the PWM signal you expect, but it isn't having the (physical) effect you expect, that suggests something going on outside the MCU.

    I'm not a motor-drive wizard, but there are some lurking here. If you post a schematic, someone might have some suggestions.

  • Hi Bruce & Pablo:

    It is working! The code was fine after I put each config. The problem was I needed to bypass the motor drivers of the TI-RSLK chassis board due to the SN754410 motor driver on my breadboard circuit. Thanks for all the help. I just have to refine the code a bit more. In fact, I tried it both with polling & ISR and doing as what the code intended.

**Attention** This is a public forum