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);
}