lab5
This commit is contained in:
parent
71e58c6ea9
commit
609fb0bb76
|
@ -3,21 +3,72 @@
|
||||||
|
|
||||||
#include "inc/msp432p401r.h"
|
#include "inc/msp432p401r.h"
|
||||||
|
|
||||||
// Initialize GPIO pins for output, which will be
|
#undef BIT0
|
||||||
// used to control the direction of the motors and
|
#undef BIT1
|
||||||
// to enable or disable the drivers.
|
#undef BIT2
|
||||||
// The motors are initially stopped, the drivers
|
#undef BIT3
|
||||||
// are initially powered down, and the PWM speed
|
#undef BIT4
|
||||||
// control is uninitialized.
|
#undef BIT5
|
||||||
|
#undef BIT6
|
||||||
|
#undef BIT7
|
||||||
|
|
||||||
|
#define BIT0 (uint8_t)(0x01)
|
||||||
|
#define BIT1 (uint8_t)(0x02)
|
||||||
|
#define BIT2 (uint8_t)(0x04)
|
||||||
|
#define BIT3 (uint8_t)(0x08)
|
||||||
|
#define BIT4 (uint8_t)(0x10)
|
||||||
|
#define BIT5 (uint8_t)(0x20)
|
||||||
|
#define BIT6 (uint8_t)(0x40)
|
||||||
|
#define BIT7 (uint8_t)(0x80)
|
||||||
|
|
||||||
|
// duty := H/(H+L) = H/10000
|
||||||
|
// H+L is always 10 000 microsecond
|
||||||
|
|
||||||
|
// Left motor (PH) direction connected to P5.4 (J3.29)
|
||||||
|
#define LEFT_DIR_PIN BIT4 // P5.4
|
||||||
|
// Right motor (PH) direction connected to P5.5 (J3.30)
|
||||||
|
#define RIGHT_DIR_PIN BIT5 // P5.5
|
||||||
|
|
||||||
|
// Left motor (EN) PWM connected to P2.7/TA0CCP4 (J4.40)
|
||||||
|
#define LEFT_PWM_PIN BIT7 // P2.7
|
||||||
|
// Right motor (EN) PWM connected to P2.6/TA0CCP3 (J4.39)
|
||||||
|
#define RIGHT_PWM_PIN BIT6 // P2.6
|
||||||
|
|
||||||
|
// Left motor (nSLEEP) enable connected to P3.7 (J4.31)
|
||||||
|
#define LEFT_SLEEP_PIN BIT7 // P3.7
|
||||||
|
// Right motor (nSLEEP) enable connected to P3.6 (J2.11)
|
||||||
|
#define RIGHT_SLEEP_PIN BIT6 // P3.6
|
||||||
|
|
||||||
|
|
||||||
|
// Initializes the 6 GPIO output lines and puts driver to sleep
|
||||||
void MotorInit(void) {
|
void MotorInit(void) {
|
||||||
// write this code
|
// 1. Configure all motor control pins as outputs
|
||||||
|
// P5.4 (Left DIR), P5.5 (Right DIR)
|
||||||
|
P5->SEL0 &= ~(LEFT_DIR_PIN | RIGHT_DIR_PIN); // GPIO function
|
||||||
|
P5->SEL1 &= ~(LEFT_DIR_PIN | RIGHT_DIR_PIN);
|
||||||
|
P5->DIR |= (LEFT_DIR_PIN | RIGHT_DIR_PIN); // Output direction
|
||||||
|
|
||||||
|
// P3.6 (Right SLEEP), P3.7 (Left SLEEP)
|
||||||
|
P3->SEL0 &= ~(LEFT_SLEEP_PIN | RIGHT_SLEEP_PIN); // GPIO function
|
||||||
|
P3->SEL1 &= ~(LEFT_SLEEP_PIN | RIGHT_SLEEP_PIN);
|
||||||
|
P3->DIR |= (LEFT_SLEEP_PIN | RIGHT_SLEEP_PIN); // Output direction
|
||||||
|
|
||||||
|
// P2.6 (Right EN), P2.7 (Left EN)
|
||||||
|
P2->SEL0 &= ~(LEFT_PWM_PIN | RIGHT_PWM_PIN); // GPIO function
|
||||||
|
P2->SEL1 &= ~(LEFT_PWM_PIN | RIGHT_PWM_PIN);
|
||||||
|
P2->DIR |= (LEFT_PWM_PIN | RIGHT_PWM_PIN); // Output direction
|
||||||
|
|
||||||
|
// 2. Initial state: disable motors
|
||||||
|
P3->OUT &= ~(LEFT_SLEEP_PIN | RIGHT_SLEEP_PIN); // SLEEP pins low - DRV8838 disabled
|
||||||
|
P2->OUT &= ~(LEFT_PWM_PIN | RIGHT_PWM_PIN); // EN pins low
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the motors, power down the drivers, and
|
// Stop the motors, power down the drivers, and
|
||||||
// set the PWM speed control to 0% duty cycle.
|
// set the PWM speed control to 0% duty cycle.
|
||||||
void MotorStop(void) {
|
void MotorStop(void) {
|
||||||
P2->OUT &= ~0xC0; // off
|
P5->OUT &= ~(LEFT_DIR_PIN | RIGHT_DIR_PIN); // set direction - PH low
|
||||||
P3->OUT &= ~0xC0; // low current sleep mode
|
P3->OUT |= (LEFT_SLEEP_PIN | RIGHT_SLEEP_PIN); // wake up motors
|
||||||
|
|
||||||
SetPWMDutyLeftMotor(0);
|
SetPWMDutyLeftMotor(0);
|
||||||
SetPWMDutyRightMotor(0);
|
SetPWMDutyRightMotor(0);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +76,11 @@ void MotorStop(void) {
|
||||||
// Left and right wheels forward with the given duty cycles.
|
// Left and right wheels forward with the given duty cycles.
|
||||||
// Duty cycle is 0 to 14,998.
|
// Duty cycle is 0 to 14,998.
|
||||||
void MotorForward(uint16_t left_duty, uint16_t right_duty) {
|
void MotorForward(uint16_t left_duty, uint16_t right_duty) {
|
||||||
// write this code
|
P5->OUT &= ~(LEFT_DIR_PIN | RIGHT_DIR_PIN); // set direction - PH low
|
||||||
|
P3->OUT |= (LEFT_SLEEP_PIN | RIGHT_SLEEP_PIN); // wake up motors
|
||||||
|
|
||||||
|
SetPWMDutyRightMotor(right_duty);
|
||||||
|
SetPWMDutyLeftMotor(left_duty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left and right wheels backward with the given duty cycles.
|
// Left and right wheels backward with the given duty cycles.
|
||||||
|
|
27
common/pwm.c
27
common/pwm.c
|
@ -38,13 +38,32 @@ void SetPWMDutyP2_5(uint16_t duty) {
|
||||||
// P2.6/.7 = 1 when timer equals TA0CCR3/4 on way down,
|
// P2.6/.7 = 1 when timer equals TA0CCR3/4 on way down,
|
||||||
// P2.6/.7 = 0 when timer equals TA0CCR3/4 on way up
|
// P2.6/.7 = 0 when timer equals TA0CCR3/4 on way up
|
||||||
void PWMInitMotor(uint16_t period) {
|
void PWMInitMotor(uint16_t period) {
|
||||||
// write this code
|
P2->DIR |= BIT6 | BIT7;
|
||||||
|
P2->SEL0 |= BIT6 | BIT7;
|
||||||
|
P2->SEL1 &= ~(BIT6 | BIT7);
|
||||||
|
|
||||||
|
TIMER_A0->CCR[0] = period;
|
||||||
|
TIMER_A0->EX0 = 0x00;
|
||||||
|
|
||||||
|
TIMER_A0->CCTL[3] = 0x40;
|
||||||
|
TIMER_A0->CCTL[4] = 0x40;
|
||||||
|
|
||||||
|
TIMER_A0->CCR[3] = 0;
|
||||||
|
TIMER_A0->CCR[4] = 0;
|
||||||
|
|
||||||
|
TIMER_A0->CTL = 0x02F0;
|
||||||
|
|
||||||
|
// ZKURVENA MRDKA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// right motor on P2.6 -> CCR3
|
||||||
void SetPWMDutyRightMotor(uint16_t duty) {
|
void SetPWMDutyRightMotor(uint16_t duty) {
|
||||||
// write this code
|
if (duty >= TIMER_A0->CCR[0]) return;
|
||||||
|
TIMER_A0->CCR[3] = duty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// left motor on P2.7 -> CCR4
|
||||||
void SetPWMDutyLeftMotor(uint16_t duty) {
|
void SetPWMDutyLeftMotor(uint16_t duty) {
|
||||||
// write this code
|
if (duty >= TIMER_A0->CCR[0]) return;
|
||||||
}
|
TIMER_A0->CCR[4] = duty;
|
||||||
|
}
|
|
@ -7,9 +7,30 @@ void (*timer_a1_task)(void); // user function
|
||||||
// Activate Timer A1 interrupts to run user task periodically
|
// Activate Timer A1 interrupts to run user task periodically
|
||||||
// 16 bits period in units (24/SMCLK, with SMCLK 12 MHz -> 2us)
|
// 16 bits period in units (24/SMCLK, with SMCLK 12 MHz -> 2us)
|
||||||
void TimerA1Init(void (*task)(void), uint16_t period) {
|
void TimerA1Init(void (*task)(void), uint16_t period) {
|
||||||
// write this code
|
timer_a1_task = task;
|
||||||
|
|
||||||
|
// bits9-8=10, clock source to SMCLK
|
||||||
|
// bits7-6=10, input clock divider
|
||||||
|
// bits5-4=00, stop mode
|
||||||
|
// bit2=0, set this bit to clear
|
||||||
|
// bit1=0, no interrupt on
|
||||||
|
TIMER_A1->CTL = 0x0280;
|
||||||
|
|
||||||
|
// bits15-14=00, no capture mode
|
||||||
|
// bit8=0, compare mode
|
||||||
|
// bit4=1, enable capture/compare interrupt on CCIFG
|
||||||
|
// bit2=0, output this value in output mode 0
|
||||||
|
TIMER_A1->CCTL[0] &= ~0x0001;
|
||||||
|
|
||||||
|
TIMER_A1->CCR[0] = (period - 1);
|
||||||
|
TIMER_A1->EX0 = 0x0005;
|
||||||
|
NVIC->IP[3] = (NVIC->IP[3]&0xFFFFFF00)|0x00000040; // priority 2
|
||||||
|
NVIC->ISER[0] = 0x00001000; // enable interrupt 12 in NVIC
|
||||||
|
TIMER_A1->CTL |= 0x0014; // reset and start Timer A in up mode
|
||||||
|
TIMER_A1->CTL |= 0x0020; // Enable Timer A1 interrupts (TAIE)
|
||||||
}
|
}
|
||||||
|
|
||||||
void TA1_0_IRQHandler(void) {
|
void TA1_0_IRQHandler(void) {
|
||||||
// write this code
|
TIMER_A1->CCTL[0] &= ~0x0001;
|
||||||
|
timer_a1_task();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,8 @@ int main(void) {
|
||||||
BumpInit();
|
BumpInit();
|
||||||
MotorInit(); // your function
|
MotorInit(); // your function
|
||||||
|
|
||||||
MotorForward(1500, 100);
|
// MotorForward(1500, 100);
|
||||||
return 0;
|
// return 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
WaitTouchRelease();
|
WaitTouchRelease();
|
||||||
|
|
|
@ -44,7 +44,7 @@ void Task(void) {
|
||||||
REDLED ^= 1;
|
REDLED ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main_periodic_test(void) {
|
int main_f(void) {
|
||||||
ClockInit48MHz();
|
ClockInit48MHz();
|
||||||
RedLEDInit();
|
RedLEDInit();
|
||||||
TimerA1Init(&Task, 500); // 1000 Hz
|
TimerA1Init(&Task, 500); // 1000 Hz
|
||||||
|
@ -52,7 +52,7 @@ int main_periodic_test(void) {
|
||||||
while (true) {}
|
while (true) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main_motor_test(void) {
|
int main(void) {
|
||||||
ClockInit48MHz();
|
ClockInit48MHz();
|
||||||
SwitchInit();
|
SwitchInit();
|
||||||
PWMInitMotor(7502); // your function
|
PWMInitMotor(7502); // your function
|
||||||
|
@ -72,7 +72,7 @@ int main_motor_test(void) {
|
||||||
// Write a program that uses PWM to move the robot
|
// Write a program that uses PWM to move the robot
|
||||||
// but uses TimerA1 to periodically check the bump switches,
|
// but uses TimerA1 to periodically check the bump switches,
|
||||||
// stopping the robot on collision
|
// stopping the robot on collision
|
||||||
int main(void) {
|
int main_final(void) {
|
||||||
ClockInit48MHz();
|
ClockInit48MHz();
|
||||||
// write code here
|
// write code here
|
||||||
CPU_cpsie(); // Enable interrupts
|
CPU_cpsie(); // Enable interrupts
|
||||||
|
|
Loading…
Reference in New Issue