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

Final version of currentControl, current_control_final, uploaded. Takes 8 bit...

Final version of currentControl, current_control_final, uploaded. Takes 8 bit signed reference over TWI
parent b1d01b07
avr-gcc -mmcu=atmega16 -g -Wall -o current_control current_control.c
\ No newline at end of file
avr-gcc -mmcu=atmega16 -g -Wall -o current_control_final current_control_final.c
\ No newline at end of file
avr-gcc -mmcu=atmega16 -g -Wall -o current_control current_control.c
avr-objcopy -Osrec current_control current_control.sr
uisp -dprog=stk200 --erase --upload if=current_control.sr
\ No newline at end of file
avr-gcc -mmcu=atmega16 -g -Wall -o current_control_final current_control_final.c
avr-objcopy -Osrec current_control_final current_control_final.sr
uisp -dprog=stk200 --erase --upload if=current_control_final.sr
\ No newline at end of file
......@@ -9,7 +9,6 @@
*********************************************/
//#include <math.h> //Only include if sin will be used, takes up memory!
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
......@@ -17,7 +16,7 @@
// reference generation variables
volatile int16_t ref = 200;
volatile int16_t ref = 100;
volatile int16_t refCount = 0;
volatile int8_t refFlag = 0;
......@@ -54,14 +53,6 @@ volatile int16_t temp;
volatile int8_t pwmCycles = 0;
/* Routine used to set the red LED */
void setLED(uint8_t on)
{
if (on) PORTB &= 0x7f; //Turn on
else PORTB |= 0x80; //Turn off
}
/* Routine used to transmit bytes on the serial port */
static void putchar(unsigned char ch)
{
......@@ -141,7 +132,6 @@ SIGNAL(SIG_OUTPUT_COMPARE2) {
//control, since negative measurements
e = ref+y; //e 9 frac bits
//v = (int16_t)((K*e+I+64)>>7);
v = (int16_t)(((K*e+64)>>7)+(temp>>4));
//saturation and update integral part of ctrl
......@@ -166,7 +156,6 @@ SIGNAL(SIG_OUTPUT_COMPARE2) {
// write output, inverting mode means set pwm to 127-ctrl_out
// Original styrning med 7 bitar + direction
u = (v+2)>>2; //7 frac bits to pwm
......@@ -210,28 +199,28 @@ SIGNAL(SIG_OUTPUT_COMPARE2) {
/* reference square- or triangle wave generator with timer 0 */
SIGNAL(SIG_OVERFLOW0) {
int8_t rectangle = 0;
int8_t rectangle = 1;
refCount++;
if (rectangle == 1) {
if (refFlag == 0) {
if (refCount == 10) {
if (refCount == 20) {
refFlag = 1;
ref = -ref;
refCount = 0;
}
} else {
if (refCount == 20) {
if (refCount == 40) {
ref = -ref;
refCount = 0;
}
}
} else {
if (refCount <= 40) { // ref
ref -= 10;
if (refCount <= 200) { // ref
ref -= 1;
} else {
ref += 10;
ref += 1;
}
if (refCount == 80) { // ref*2
if (refCount == 400) { // ref*2
refCount = 0;
}
}
......@@ -244,11 +233,8 @@ int main()
int i,j;
//Port directions
outp(0x80,PORTB); // LED off
outp(0x80,DDRB); // output on LED
outp(0x08,PORTC); // pull up on overtemp signals
outp(0xa0,DDRC); // output on dir and brake
outp(0x80,PORTD); // pull up on reset switch
outp(0x10,DDRD); // output on pwm for motor 1
outp(0x10,DDRA); // test pin output
......
#include <avr/twi.h>
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <inttypes.h>
// control variables
volatile int16_t ref=0;
volatile unsigned char lbyte,hbyte;
volatile int16_t y;
volatile uint8_t low, high;
volatile int16_t e = 0;
volatile int16_t v = 0;
volatile int16_t I = 0;
volatile int16_t u = 0;
volatile int16_t K = 74; // 7 frac bits
volatile int16_t Ke = 26; //7 frac bits, K*h/Ti
volatile int16_t Ksat = 44; // 7 frac bits, h/Tr
// logging variables
#define log_len 100
volatile int16_t ctrl_log[log_len];
volatile int16_t error_log[log_len];
volatile int32_t I_log[log_len];
volatile int16_t skipSamples = 1000;
volatile int16_t countSamples = 0;
volatile int16_t jj=0;
volatile int8_t stop = 0;
// twi variables
volatile int16_t status;
/* Interrupt service routine for handling incoming bytes on the serial port
might be needed to catch incoming bytes */
SIGNAL(SIG_UART_RECV){}
/* Timer 1 compare match, start AD-conversion
* Additional changes: Dont use free running AD-conversion
* Enable overflow interrupts timer1
*/
SIGNAL(SIG_OUTPUT_COMPARE2) {
// Start AD conversion
ADCSRA |= BV(ADSC);
PORTB |= 0x40; //Turn on calculation timer
// Read input
low = inp(ADCL);
high = inp(ADCH);
y = ((high<<8) | low) - 512; //y 9 frac bits
//control, since negative measurements
e = ref+y; //e 9 frac bits
//v = (int16_t)((K*e+I+64)>>7);
v = (int16_t)(((K*e+64)>>7)+(I>>4));
//saturation and update integral part of ctrl
if (v > 511) {
I = I + (((Ke*e) + (Ksat)*(511-v))>>3);
} else if (v < -512) {
I = I + (((Ke*e) + (Ksat)*(-512-v))>>3);
} else {
I = I + ((Ke*e)>>3);
}
// Original styrning med 7 bitar + direction
u = (v+2)>>2; //7 frac bits to pwm
if (u > 127) {
u = 127;
} else if (u < -128) {
u = -128;
}
//u = 0;
// set pwm switching time
if (u < 0) {
PORTC |= 0x80;
OCR1BL = (unsigned char) (128-(-u));
} else {
PORTC = (PORTC & 0x7F);
OCR1BL = (unsigned char) (127-u);
}
// TWI-communication (need status == 0x60?)
if ((BV(TWINT)&inp(TWCR))) {
status = (inp(TWSR)&0xf8);
if (status == 0x80) {
ref = (int16_t)((int8_t)(inp(TWDR))); // read reference
ref = ref << 2; // shifted 2 steps for 10 bits for reference
}
else {
}
outp(BV(TWINT)|BV(TWEN)|BV(TWEA),TWCR);
}
PORTB &= 0xbf; //Turn off calculation timer
}
int main()
{
cli();
//Port directions
outp(0x08,PORTC); // pull up on overtemp signals
outp(0xa0,DDRC); // output on dir and brake
outp(0x10,DDRD); // output on pwm for motor 1
outp(0x40,DDRB); // output on timer calculation pin
outp(0x10,DDRA); // test pin output
/* Timer section */
// Enable timer2 compare match interrupts
outp(BV(OCIE2),TIMSK);
// Timer 1, fast PWM no prescaling (inverting mode (start low, switch to high))
outp(BV(COM1A1)|BV(COM1B1)|BV(COM1A0)|BV(COM1B0)|BV(WGM11)|BV(WGM10),TCCR1A);
outp(BV(CS10)|BV(WGM13)|BV(WGM12),TCCR1B);
// Reset Timer1 and set TOP-value to 128 (means 7-bit pwm-signal-> h_pwm=8.61 micros)
outp(0x00,OCR1AH);
outp(0x7f,OCR1AL);
outp(0x00,TCNT1H);
outp(0x00,TCNT1L);
outp(0x00,OCR1BH);
outp(0x7f,OCR1BL); // to not start motor-rotation before control
/* Timer 2, 4 times pwm-period, for control sampling, prescaler 8 */
outp(BV(WGM21)|BV(CS21),TCCR2);
outp(0x3f,OCR2);
/* Reset timer 2 */
outp(0,TCNT2);
//Serial communication
outp(0x00, UCSRA); // USART:
outp(0x98, UCSRB); // USART: RxIntEnable|RxEnable|TxEnable
outp(0x86, UCSRC); // USART: 8bit, no parity
outp(0x00, UBRRH); // USART: 115200 @ 14.7456MHz
outp(7,UBRRL); // USART: 115200 @ 14.7456MHz
/* AREF (AREF is 5V) pin external capacitor, MUX0 for current */
outp(BV(REFS0)|BV(MUX0),ADMUX);
// Enable ADC, start first conversion, prescaler 32, not free running mode
outp(BV(ADEN)|BV(ADSC)|BV(ADPS2)|BV(ADPS0),ADCSRA);
// Initialize TWI
outp(0x02,TWBR); // set SCL-frequency CPU-freq/(16+2*2)
outp(0x02,TWAR); // slave address
outp(BV(TWEA)|BV(TWEN),TWCR); // enable TWI, enable ACK
//Enable interrupts
sei();
// loop
while (1) {}
}
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