diff --git a/src/adc.cpp b/src/adc.cpp new file mode 100644 index 0000000..41c0e78 --- /dev/null +++ b/src/adc.cpp @@ -0,0 +1,43 @@ +/* + * adc.cpp + * + * Created on: 03.10.2014 + * Author: wn + */ + +#include +#include +#include + +#include "adc.h" + + + +void adcInit() { + ADC10CTL0 = ADC10SHT_1 | ADC10ON | SREF_0; + ADC10CTL1 = INCH_5; + ADC10AE0 = BIT5; +} + +uint16_t adcGet() { + uint16_t res = 0xffff; + + ADC10CTL0 |= ENC | ADC10SC; + + uint32_t timeOut = ADC_TIME_OUT; + + while (1) { + timeOut--; + if (timeOut == 0) + break; + + if ((ADC10CTL0 & ADC10IFG) != 0) { + res = ADC10MEM; + ADC10CTL0 &= ~(ADC10IFG | ENC); + break; + } + } + + return res; +} + diff --git a/src/adc.h b/src/adc.h new file mode 100644 index 0000000..1613fd8 --- /dev/null +++ b/src/adc.h @@ -0,0 +1,22 @@ +/* + * adc.h + * + * Created on: 03.10.2014 + * Author: wn + */ + +#ifndef ADC_H_ +#define ADC_H_ + +#include + + +const uint32_t ADC_TIME_OUT = 100000; +const uint16_t ADC_MAX = 1023; + +void adcInit(); +uint16_t adcGet(); + + + +#endif /* ADC_H_ */ diff --git a/src/control.cpp b/src/control.cpp new file mode 100644 index 0000000..3e7814f --- /dev/null +++ b/src/control.cpp @@ -0,0 +1,38 @@ +/* + * control.c + * + * Created on: 24.09.2012 + * Author: wn + */ + + +#include "control.h" +#include "utils.h" + + + + +Control::Control(float p_rMin, float p_rMax, float p_kP, float p_kI, float p_kD) : + m_rOld(0), m_eOld(0), m_eOld2(0), + m_rMin(p_rMin), m_rMax(p_rMax), m_kP(p_kP), m_kI(p_kI), m_kD(p_kD) +{ +} + + +float Control::cycle(float vDes, float vCur) volatile { + float e = vDes - vCur; + + float rMot = m_rOld + + m_kP * (e - m_eOld) + + m_kI * (e + m_eOld) / 2 + + m_kD * (e - 2 * m_eOld + m_eOld2); + + float r = minmax(m_rMin, rMot, m_rMax); + + m_rOld = r; + m_eOld2 = m_eOld; + m_eOld = e; + return r; +} + + diff --git a/src/control.h b/src/control.h new file mode 100644 index 0000000..721cb5d --- /dev/null +++ b/src/control.h @@ -0,0 +1,37 @@ +/* + * control.h + * + * Created on: 24.09.2012 + * Author: wn + */ + +#ifndef CONTROL_H_ +#define CONTROL_H_ + +#include + + + +class Control { +public: + Control(float p_rMin, float p_rMax, float p_kP, float p_kI, float p_kD); + float cycle(float vDes, float vCur) volatile; + float getP() volatile { return m_kP; }; + void setP(float p) volatile { m_kP = p; }; + float getI() volatile { return m_kI; }; + void setI(float i) volatile { m_kI = i; }; + float getD() volatile { return m_kD; }; + void setD(float d) volatile { m_kD = d; }; +private: + float m_rOld; + float m_eOld; + float m_eOld2; + float m_rMin; + float m_rMax; + float m_kP; + float m_kI; + float m_kD; +}; + + +#endif /* CONTROL_H_ */ diff --git a/src/main.cpp b/src/main.cpp index 3e63aef..b0f3d9a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,12 +10,14 @@ #include #include -#include "time.h" +#include "pwm.h" +#include "adc.h" -int main() { +void init() { + // disable watchdog WDTCTL = WDTPW | WDTHOLD; // highest possible system clock @@ -23,13 +25,15 @@ int main() { BCSCTL1 = XT2OFF | RSEL0 | RSEL1 | RSEL2 | RSEL3; BCSCTL2 = 0; BCSCTL3 = 0; +} - timeInit(); +int main() { + init(); + adcInit(); + pwmInit(); __enable_interrupt(); - - while (1) { } } diff --git a/src/params.h b/src/params.h new file mode 100644 index 0000000..7d26602 --- /dev/null +++ b/src/params.h @@ -0,0 +1,17 @@ +#ifndef PARAMS_H_ +#define PARAMS_H_ + + + +const float Ctrl_P = 10.0; +const float Ctrl_I = 5.0; +const float Ctrl_D = 0.0; + +const float U_ref = 3.3; +const float R_top = 100000.0; +const float R_bottom = 6200.0; + +const float U_des = 5.0; + + +#endif /* PARAMS_H_ */ diff --git a/src/pwm.cpp b/src/pwm.cpp new file mode 100644 index 0000000..bfb8403 --- /dev/null +++ b/src/pwm.cpp @@ -0,0 +1,90 @@ +/* + * time.c + * + * Created on: 20.05.2014 + * Author: wn + */ +#include +#include +#include + +#include "pwm.h" +#include "control.h" +#include "params.h" +#include "adc.h" + + + +volatile Control ctrl((float)PWM_MIN, (float)PWM_MAX, Ctrl_P, Ctrl_I, Ctrl_D); + +volatile float u_des = 0; +volatile float u_curr = 0; +volatile uint16_t newPwm = 0; + + + + +ISR(TIMER0_A0, TA0_ISR) { + static uint8_t cycleCnt = 0; + cycleCnt++; + + if (cycleCnt >= CYCLE_DELAY) { + cycleCnt = 0; + + + uint16_t adcIn = adcGet(); + float u_adc = ((float)adcIn) * U_ref / ((float)ADC_MAX); + u_curr = u_adc * (R_top + R_bottom) / R_bottom; + + float newPwm_f = ctrl.cycle(u_des, u_curr); + newPwm = (uint16_t) newPwm_f; + + TACCR1 = newPwm; + } +} + +float getDutyCycle() { + __disable_interrupt(); + uint16_t my_newPwm = newPwm; + __enable_interrupt(); + float dutyCycle = ((float)my_newPwm) / ((float)PWM_MAX) * 100.0; + return dutyCycle; +} + +float getUCur() { + __disable_interrupt(); + float my_u_curr = u_curr; + __enable_interrupt(); + return my_u_curr; +} + +float getUDes() { + __disable_interrupt(); + float my_u_des = u_des; + __enable_interrupt(); + return my_u_des; +} + +void setUDes(float uDes) { + if (uDes < 0) { + uDes= 0; + } + __disable_interrupt(); + u_des = uDes; + __enable_interrupt(); +} + + + +void pwmInit() { + P1DIR |= BIT6; + P1SEL |= BIT6; + P1OUT = 0; + + TACCR0 = PWM_MAX; + TACCR1 = 8; + TACCTL0 = CCIE; + TACCTL1 = OUTMOD_7; + TACTL = MC_1 | ID_0 | TASSEL_2 | TACLR; +} + diff --git a/src/time.h b/src/pwm.h similarity index 54% rename from src/time.h rename to src/pwm.h index 3b745b1..39b52b4 100644 --- a/src/time.h +++ b/src/pwm.h @@ -10,8 +10,12 @@ -void timeInit(); -unsigned long millis(); +const uint16_t PWM_MIN = 0; +const uint16_t PWM_MAX = 511; +const uint16_t CYCLE_DELAY = 2; + + +void pwmInit(); diff --git a/src/time.cpp b/src/time.cpp deleted file mode 100644 index 8695540..0000000 --- a/src/time.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * time.c - * - * Created on: 20.05.2014 - * Author: wn - */ -#include -#include -#include - -#include "time.h" - - -volatile unsigned long timestamp; - -//ISR(TIMER0_A0, TA0_ISR) { -// static uint8_t state = 0; -// -// timestamp++; -// -// switch (state) { -// case 0: -// P1OUT = BIT0; -// state = 1; -// break; -// case 1: -// P1OUT = BIT6; -// state = 0; -// break; -// default: -// state = 0; -// } -//} - - -void timeInit() { - timestamp = 0; - - P1DIR |= BIT6; - P1SEL |= BIT6; - P1OUT = 0; - - TACCR0 = 511; - TACCR1 = 8; - TACCTL1 = OUTMOD_7; - TACTL = MC_1 | ID_0 | TASSEL_2 | TACLR; -} - - -unsigned long millis() { - return timestamp; -} - diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..6e8d073 --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,33 @@ +/* + * utils.cpp + * + * Created on: Feb 11, 2015 + * Author: wn + */ + + + + +#include "utils.h" + + +int32_t max(int32_t a, int32_t b){ + return (a >= b) ? a : b; +} + + +int32_t min(int32_t a, int32_t b) { + return (a <= b) ? a : b; +} + +int32_t minmax(int32_t lowerBound, int32_t value, int32_t upperBound){ + int32_t res = value; + if (value <= lowerBound) { + res = lowerBound; + } else if (value >= upperBound) { + res = upperBound; + } + return res; +} + + diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..2348019 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,20 @@ +/* + * utils.h + * + * Created on: Feb 11, 2015 + * Author: wn + */ + +#ifndef UTILS_H_ +#define UTILS_H_ + + +#include + +int32_t max(int32_t a, int32_t b); +int32_t min(int32_t a, int32_t b); +int32_t minmax(int32_t lowerBound, int32_t value, int32_t upperBound); + + + +#endif /* UTILS_H_ */