Commit ca14d409 authored by Pontus Giselsson's avatar Pontus Giselsson
Browse files

Current control with AD-conversion-complete-timer

parent cd4f3ada
......@@ -15,11 +15,25 @@
#include <avr/interrupt.h>
#include <inttypes.h>
volatile int16_t ref = 20;
// reference generation variables
volatile int16_t ref = 200;
volatile int16_t refCount = 0;
volatile int8_t refFlag = 0;
// control variables
volatile unsigned char lbyte,hbyte;
volatile int16_t result;
volatile int16_t ctrl;
volatile int16_t ctrl_out;
volatile int16_t temp;
volatile uint8_t alt = 1;
volatile uint8_t low, high;
/* Routine used to set the red LED */
void setLED(uint8_t on)
......@@ -46,7 +60,8 @@ static void putchar(unsigned char ch)
/* Interrupt service routine for handling incoming bytes on the serial port
might be needed to catch incoming bytes */
SIGNAL(SIG_UART_RECV){}
/* Read 10-bit input using the AD converter */
static inline int16_t readInput() {
uint8_t low, high;
ADCSRA |= 0x40;
......@@ -55,7 +70,7 @@ static inline int16_t readInput() {
high = ADCH;
return ((high<<8) | low) - 512;
}
/* Write 8-bit output using the PWM-generator */
static inline void writeOutput(int16_t val) {
......@@ -68,76 +83,48 @@ static inline void writeOutput(int16_t val) {
OCR1BH = 0; //(unsigned char) (val&0xff00);
OCR1BL = (unsigned char) (val&0x00ff);
}
//unsigned char lbyte,hbyte;
//hbyte = ((val & 0xff00)>>8); //Get ADC result high byte
//lbyte = ((val & 0x00ff)); //Get ADC result low byte
//putchar(hbyte);
//putchar(lbyte);
}
/* Periodic timer interrupt */
SIGNAL(SIG_OUTPUT_COMPARE2)
/* Interrupt when AD-conversion completes */
SIGNAL(SIG_ADC)
{
setPA4(1);
// PORTA &= 0xef;
unsigned char lbyte,hbyte;
int16_t result;
int16_t ctrl;
int16_t ctrl_out;
int16_t temp;
// Read input
low = inp(ADCL);
high = inp(ADCH);
result = ((high<<8) | low) - 512;
setPA4(alt);
result = readInput();
setPA4(0);
// Scale incoming current measurement
result = result*3; //!!!!!!!!!!!!!!!!!!!!!!!
// Compensate for offset in measurements
// Scale incoming current measurement
// result += 13;
//hbyte = (((ref-result) & 0xff00)>>8); //Get ADC result high byte
//lbyte = (((ref-result) & 0x00ff)); //Get ADC result low byte
// Transmit data
//putchar(hbyte); //high byte
//putchar(lbyte); //low byte
//hbyte = ((result & 0xff00)>>8); //Get ADC result high byte
//lbyte = ((result & 0x00ff)); //Get ADC result low byte
// Transmit data
//putchar(hbyte); //high byte
//putchar(lbyte); //low byte
// control
//control
ctrl = ref-result;
ctrl = ((ctrl + (1<< 2)) >> 3);
//saturation/rounding to 8 bit
if (ctrl > 127)
ctrl_out = 127;
else if (ctrl < -128)
ctrl_out = -128;
if (ctrl > 511)
ctrl_out = 511;
else if (ctrl < -511)
ctrl_out = -511;
else
ctrl_out = ctrl;
//writeOutput(ctrl_out);
writeOutput(ref);
temp = (int16_t) ctrl_out;
hbyte = ((temp & 0xff00)>>8); //Get ADC result high byte
lbyte = ((temp & 0x00ff)); //Get ADC result low byte
putchar(hbyte);
putchar(lbyte);
// write output
if (ctrl_out < 0) {
PORTC = 0x80+(PORTC & 0x7F);
OCR1BL = (unsigned char) (-ctrl_out);
} else {
PORTC = (PORTC & 0x7F);
OCR1BL = (unsigned char) (ctrl_out);
}
setPA4(0);
}
......@@ -186,8 +173,8 @@ int main()
outp(0x10,DDRA); // test pin output
/* Timer section */
// Enable TCNT2 (timer2) compare match interrupts, and timer0 overflow interrupts
outp(BV(OCIE2)|BV(TOIE0),TIMSK);
// Enable timer0 overflow interrupts
outp(BV(TOIE0),TIMSK);
/* Timer 1, 8 bit fast PWM no prescaling -> h_pwm=17.35 micros */
outp(BV(COM1A1)|BV(COM1B1)|BV(WGM10),TCCR1A);
......@@ -203,10 +190,10 @@ int main()
/* Timer 2 (control loop), prescaler 256, clear on compare match (28), -> h = 0.5 ms */
outp(BV(WGM21)|BV(CS22)|BV(CS21),TCCR2);
outp(28,OCR2);
// outp(BV(WGM21)|BV(CS22)|BV(CS21),TCCR2);
//outp(28,OCR2);
/* Reset timer 2 */
outp(0,TCNT2);
//outp(0,TCNT2);
/* Timer 0 for reference generation, prescaler = 1024 periodic h = ? */
outp(BV(CS02)|BV(CS00),TCCR0);
......@@ -222,13 +209,8 @@ int main()
/* AREF (AREF is 5V) pin external capacitor, MUX0 for current, MUX3?? for pendulum angle */
outp(BV(REFS0)|BV(MUX0),ADMUX);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 128
// outp(BV(ADEN)|BV(ADSC)|BV(ADPS2)|BV(ADPS1)|BV(ADPS0),ADCSRA);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 8
// outp(BV(ADEN)|BV(ADSC)|BV(ADPS1)|BV(ADPS0),ADCSRA);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 64
outp(BV(ADEN)|BV(ADSC)|BV(ADPS2)|BV(ADPS1),ADCSRA);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 32
outp(BV(ADEN)|BV(ADATE)|BV(ADSC)|BV(ADIE)|BV(ADPS2)|BV(ADPS0),ADCSRA);
// outp(BV(ADEN)|BV(ADSC),ADCSRA);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment