Disabled external gits
This commit is contained in:
BIN
cs473-es/lab1/Labo_MSP432_v1_2.pdf
Normal file
BIN
cs473-es/lab1/Labo_MSP432_v1_2.pdf
Normal file
Binary file not shown.
109
cs473-es/lab1/ch/main.c
Normal file
109
cs473-es/lab1/ch/main.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include"msp.h"
|
||||
|
||||
#define UNLOCK_CS CS->KEY = CS_KEY_VAL
|
||||
#define LOCK_CS CS->KEY = 0
|
||||
|
||||
#define DISABLE_WATCHDOG() WDT_A->CTL= WDT_A_CTL_PW | WDT_A_CTL_HOLD
|
||||
|
||||
#define TIMER_PERIOD 20 // ms
|
||||
#define TIMER_DIV (8)
|
||||
#define TIMER_FCLK 3000000
|
||||
#define TIMER_PERIOD_TICKS (((TIMER_FCLK / TIMER_DIV) * TIMER_PERIOD) / 1000)
|
||||
|
||||
//#define FULLRANGE
|
||||
|
||||
#ifdef FULLRANGE
|
||||
#define DC_MIN 0.75
|
||||
#define DC_MAX 2.25
|
||||
#else
|
||||
#define DC_MIN 1
|
||||
#define DC_MAX 2
|
||||
#endif
|
||||
|
||||
#define PERIOD TIMER_PERIOD_TICKS //20 ms
|
||||
#define DUTY_MAX ((unsigned int)(TIMER_PERIOD_TICKS/TIMER_PERIOD)*(DC_MAX)) //2 ms
|
||||
#define DUTY_MIN ((unsigned int)(TIMER_PERIOD_TICKS/TIMER_PERIOD)*(DC_MIN)) //1 ms
|
||||
#define DUTY_RANGE (DUTY_MAX - DUTY_MIN)
|
||||
|
||||
|
||||
#define ADC_MAX ((1 << 14) - 1)
|
||||
#define ADC_MIN 0
|
||||
#define ADC_RANGE ((ADC_MAX-ADC_MIN))
|
||||
|
||||
|
||||
#define ADC_TO_T(v) (DUTY_MIN + ((v - ADC_MIN)*DUTY_RANGE)/ADC_RANGE)
|
||||
|
||||
|
||||
void setup_pins(){
|
||||
// J4 - P2.4
|
||||
P2->DIR |= 0x10; //2.4
|
||||
P2->SEL0 |= 0x10; //2.4 SELECT TA0 MODULE
|
||||
P2->SEL1 &= ~0x10;//2.4 SELECT TA0 MODULE
|
||||
|
||||
// J3 - P4.0
|
||||
P4->SEL0 |= 0x01; //4.0 SELECT ADC MODULE
|
||||
P4->SEL1 |= 0x01; //4.0 SELECT ADC MODULE
|
||||
}
|
||||
|
||||
void setup_clock(){
|
||||
UNLOCK_CS;
|
||||
|
||||
CS->CTL0 |= CS_CTL0_DCORSEL_1; // 3 MHz
|
||||
CS->CTL1 |= CS_CTL1_DIVS__8 | CS_CTL1_SELS__DCOCLK ; // SMCLOCK = DCLOCK/8
|
||||
CS->CTL0 |= CS_CTL0_DCOEN; //Enable
|
||||
|
||||
LOCK_CS;
|
||||
}
|
||||
|
||||
void setup_timer_a0(){
|
||||
TIMER_A0->CCR[0] = PERIOD; //base period
|
||||
|
||||
TIMER_A0->CCR[1] = DUTY_MIN; //COMPARE to duty cycle
|
||||
TIMER_A0->CCTL[1] = OUTMOD_7; //RESET/SET
|
||||
|
||||
TIMER_A0->EX0 = TAIDEX__1; // divide by 1
|
||||
TIMER_A0->CTL = TASSEL__SMCLK | ID__1 | MC__UP;//DOWN; //SMCLK, /1, UP
|
||||
}
|
||||
|
||||
void setup_adc(){
|
||||
ADC14->CTL0 &= ~ADC14_CTL0_ENC; //ADC Disable
|
||||
|
||||
ADC14->CTL0 = ADC14_CTL0_ON; //ADC ON
|
||||
ADC14->CTL0 |= ADC14_CTL0_SSEL__SMCLK; //USE SMCLK
|
||||
|
||||
ADC14->CTL0 |= ADC14_CTL0_CONSEQ_2; //ADC14 Repeat Channel Sampling
|
||||
|
||||
ADC14->CTL0 |= ADC14_CTL0_SHS_1; //USE TA0.1
|
||||
|
||||
ADC14->CTL1 = ADC14_CTL1_RES__14BIT; //14 bit, 16 clk conversion
|
||||
|
||||
ADC14->MCTL[0] = ADC14_MCTLN_VRSEL_0 | ADC14_MCTLN_INCH_13; // A13 ADC & V(R+) = AVCC, V(R-) = AVSS
|
||||
ADC14->IER0 |= ADC14_IER0_IE0; //ADC Interrupt
|
||||
|
||||
ADC14->CTL0 |= ADC14_CTL0_ENC; //ADC Enable
|
||||
}
|
||||
|
||||
|
||||
|
||||
void main(void){
|
||||
DISABLE_WATCHDOG();
|
||||
|
||||
setup_pins();
|
||||
setup_clock();
|
||||
setup_timer_a0();
|
||||
setup_adc();
|
||||
|
||||
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; // Enable sleep on exit from ISR
|
||||
__DSB(); // Ensures SLEEPONEXIT takes effect immediately
|
||||
__enable_irq(); // Enable global interrupt
|
||||
|
||||
NVIC_EnableIRQ(ADC14_IRQn); //ENABLE IRQ ADC14
|
||||
|
||||
__sleep(); //Sleep
|
||||
}
|
||||
|
||||
|
||||
void ADC14_IRQHandler(void) {
|
||||
TIMER_A0->CCR[1] = ADC_TO_T(ADC14->MEM[0]);
|
||||
}
|
||||
|
||||
175
cs473-es/lab1/mbp/main.c
Normal file
175
cs473-es/lab1/mbp/main.c
Normal file
@@ -0,0 +1,175 @@
|
||||
#include "msp.h"
|
||||
#include "math.h"
|
||||
|
||||
// =========================== Convenience functions ===========================
|
||||
|
||||
inline void setmasked32(volatile uint32_t* ptr, uint32_t mask, uint32_t bits) {
|
||||
*ptr = (*ptr & ~mask) | bits;
|
||||
}
|
||||
|
||||
inline void setmasked16(volatile uint16_t* ptr, uint16_t mask, uint16_t bits) {
|
||||
*ptr = (*ptr & ~mask) | bits;
|
||||
}
|
||||
|
||||
inline void clearmasked16(volatile uint16_t* ptr, uint16_t mask) {
|
||||
*ptr &= ~(mask);
|
||||
}
|
||||
|
||||
inline void clearbit32(volatile uint32_t* ptr, unsigned idx) {
|
||||
*ptr &= ~(1 << idx);
|
||||
}
|
||||
|
||||
inline void clearbit16(volatile uint16_t* ptr, unsigned idx) {
|
||||
*ptr &= ~(1 << idx);
|
||||
}
|
||||
|
||||
inline void clearbit8(volatile uint8_t* ptr, unsigned idx) {
|
||||
*ptr &= ~(1 << idx);
|
||||
}
|
||||
|
||||
inline void setbit32(volatile uint32_t* ptr, unsigned idx) {
|
||||
*ptr |= 1 << idx;;
|
||||
}
|
||||
|
||||
inline void setbit16(volatile uint16_t* ptr, unsigned idx) {
|
||||
*ptr |= 1 << idx;;
|
||||
}
|
||||
|
||||
inline void setbit8(volatile uint8_t* ptr, unsigned idx) {
|
||||
*ptr |= 1 << idx;;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
||||
#define ADC_MAX ((1 << 14) - 1) // 14-bit ADC
|
||||
#define ADC_MCTL_IDX (0)
|
||||
#define TIMER_PERIOD 20 // ms
|
||||
#define TIMER_DIV (8)
|
||||
#define TIMER_FCLK 3000000
|
||||
#define TIMER_PERIOD_TICKS (((TIMER_FCLK / TIMER_DIV) * TIMER_PERIOD) / 1000)
|
||||
|
||||
|
||||
void startTimer(Timer_A_Type* timer) {
|
||||
// Select clock source = SMCLK
|
||||
setmasked16(&timer->CTL, TIMER_A_CTL_SSEL_MASK, TIMER_A_CTL_SSEL__SMCLK);
|
||||
|
||||
// Divide by 8*1 (SMCLK defaults to 3000000Hz, dont bother to change it).
|
||||
// Although one should probably use a lower-freq clock if we are in
|
||||
// the millisecond range for interrupts.
|
||||
setmasked16(&timer->EX0, TIMER_A_EX0_IDEX_MASK, TIMER_A_EX0_IDEX__8); // divide by 8
|
||||
|
||||
// CCR0 is set to the full period count.
|
||||
// When CCR0 is met, the timer should reset to 0 and repeat (in UP mode).
|
||||
timer->CCR[0] = TIMER_PERIOD_TICKS;
|
||||
|
||||
// Enable IRQ from timer (caller shall enable corresponding bit in NVIC)
|
||||
setmasked16(&timer->CCTL[0], 1 << TIMER_A_CCTLN_CCIE_OFS,TIMER_A_CCTLN_CCIE);
|
||||
|
||||
// Reset timer
|
||||
clearmasked16(&timer->CCTL[0], TIMER_A_CCTLN_CCIFG);
|
||||
TIMER_A0->R = 0;
|
||||
|
||||
// Start the timer - Count upwards
|
||||
setmasked16(&timer->CTL, TIMER_A_CTL_MC_MASK, TIMER_A_CTL_MC__UP);
|
||||
}
|
||||
|
||||
void enableADC() {
|
||||
// Configure pin 4.0 (A13) as an ADC input
|
||||
clearbit8(&P4->DIR, 0);
|
||||
clearbit8(&P4->SEL0, 1);
|
||||
clearbit8(&P4->SEL1, 1);
|
||||
|
||||
// Enable ADC finish conversion interrupt
|
||||
NVIC_EnableIRQ(ADC14_IRQn);
|
||||
|
||||
// Set voltage reference from rail to rail
|
||||
setmasked32(&ADC14->MCTL[ADC_MCTL_IDX], ADC14_MCTLN_VRSEL_MASK, ADC14_MCTLN_VRSEL_0);
|
||||
|
||||
// Non-difference mode
|
||||
clearbit32(&ADC14->MCTL[ADC_MCTL_IDX], ADC14_MCTLN_DIF_OFS);
|
||||
|
||||
// Input channel
|
||||
setmasked32(&ADC14->MCTL[ADC_MCTL_IDX], ADC14_MCTLN_INCH_MASK, ADC14_MCTLN_INCH_13);
|
||||
setmasked32(&ADC14->CTL1, ADC14_CTL1_CSTARTADD_MASK, ADC_MCTL_IDX << ADC14_CTL1_CSTARTADD_OFS);
|
||||
|
||||
// Enable the channel 0 interrupt
|
||||
setbit32(&ADC14->IER0, ADC14_IER0_IE0_OFS);
|
||||
|
||||
// This is a >software triggered< adc routine (convert when requested)
|
||||
setmasked32(&ADC14->CTL0, ADC14_CTL0_SHS_MASK, ADC14_CTL0_SHS_0);
|
||||
|
||||
// Mega-speed is not ultra important so set clock source to ACLK
|
||||
setmasked32(&ADC14->CTL0, ADC14_CTL0_SSEL_MASK, ADC14_CTL0_SSEL_2);
|
||||
|
||||
// Enable conversion
|
||||
setbit32(&ADC14->CTL0, ADC14_CTL0_ON_OFS);
|
||||
setbit32(&ADC14->CTL0, ADC14_CTL0_ENC_OFS);
|
||||
}
|
||||
|
||||
void setAngle(float ratio) {
|
||||
// We work in microseconds to have the appropriate precision.
|
||||
// This allows a range of 1000 different angles (1000us to 2000 us).
|
||||
const unsigned duty_period_us = (1000 /* 1ms = 0 degrees */ + 1000 * ratio);
|
||||
const unsigned duty_ticks = ((TIMER_FCLK / TIMER_DIV) * duty_period_us) / 1000000;
|
||||
|
||||
// Finally, write the new duty cycle tick count to TA0.CCR1
|
||||
TIMER_A0->CCR[1] = TIMER_PERIOD_TICKS - duty_ticks;
|
||||
}
|
||||
|
||||
|
||||
void ADC14_IRQHandler() {
|
||||
// Adjust duty cycle of PWM
|
||||
const float ratio = ((float)(ADC14->MEM[ADC_MCTL_IDX]) / ADC_MAX);
|
||||
setAngle(ratio);
|
||||
}
|
||||
|
||||
void TA1_0_IRQHandler() {
|
||||
// Initiate software-controlled ADC conversion
|
||||
setbit32(&ADC14->CTL0, ADC14_CTL0_SC_OFS);
|
||||
clearbit32(&ADC14->CTL0, ADC14_CTL0_SC_OFS);
|
||||
}
|
||||
|
||||
void motorController() {
|
||||
// Step 1: Enable ADC
|
||||
enableADC();
|
||||
startTimer(TIMER_A0); // PWM timer
|
||||
startTimer(TIMER_A1); // ADC sampling trigger timer (software triggered)
|
||||
|
||||
|
||||
// Enable PWM output of TA0.1
|
||||
// Compare mode is required to generate PWM signals.
|
||||
// Compare mode => capture mode is disables => CAP = 0
|
||||
clearbit16(&TIMER_A0->CCTL[1], TIMER_A_CCTLN_CAP_OFS);
|
||||
|
||||
|
||||
// Enable output for reg1 of timer 0 (P2.4)
|
||||
setbit8(&P2->DIR, 4);
|
||||
setbit8(&P2->SEL0, 4);
|
||||
clearbit8(&P2->SEL1, 4);
|
||||
|
||||
// Next, we need to configure the output unit of the capture/compare
|
||||
// block to generate the proper PWM signal. The PWM is defined by
|
||||
// using the set/reset output mode (note: we are creating a
|
||||
// sawtooth wave and NOT a triangle wave).
|
||||
setmasked16(&TIMER_A0->CCTL[1], TIMER_A_CCTLN_OUTMOD_MASK, TIMER_A_CCTLN_OUTMOD_3);
|
||||
|
||||
// Enable timer interrupts in NVIC
|
||||
NVIC_EnableIRQ(TA1_0_IRQn);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* main.c
|
||||
*/
|
||||
void main(void)
|
||||
{
|
||||
WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // stop watchdog timer
|
||||
|
||||
// Program clock system
|
||||
CS->KEY = CS_KEY_VAL;
|
||||
// ....
|
||||
CS->KEY = 0xdeadbeef;
|
||||
|
||||
motorController();
|
||||
}
|
||||
Reference in New Issue
Block a user