147 lines
3.0 KiB
C
147 lines
3.0 KiB
C
#include <stdlib.h>
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/pgmspace.h>
|
|
#include <util/delay.h>
|
|
#include <string.h>
|
|
#include "utils.h"
|
|
#include "main.h"
|
|
#include "uart.h"
|
|
|
|
#define BUFSIZE 40
|
|
|
|
volatile uint16_t syscounter = 0;
|
|
|
|
// values send over uart from powerboard
|
|
uint16_t power_gen = 0;
|
|
|
|
unsigned char data_count = 0;
|
|
unsigned char data_in[BUFSIZE];
|
|
char command_in[BUFSIZE];
|
|
|
|
|
|
static void timer_init(void) {
|
|
// clock is 8MHz
|
|
TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10); // CTC Mode for Timer 1 (16Bit) with prescale of 64
|
|
OCR1A = 2312; // Neutralposition ((2500-2312)*0.008ms)=1,5ms)
|
|
TIMSK = _BV(OCIE1A);
|
|
TCCR1A = (1<<COM1A0); // Togglen bei Compare Match
|
|
|
|
sei(); // enable interrupts
|
|
}
|
|
|
|
static void ports_init(void) {
|
|
|
|
DDRB |= (1<<PB4)|(1<<PB3);
|
|
|
|
}
|
|
|
|
static void process_command() {
|
|
if(strstr(command_in,"A") != NULL) {
|
|
// we have an A and B (from check in work_uart()
|
|
// so our message should be complete and consist of:
|
|
// A$voltage,$current_in,$current_out,$power_in,$power_out,loadsw,dumpsw,gensw\n
|
|
|
|
//A12.5,65464,00000,00000,00000,1,0,1B
|
|
|
|
char *token;
|
|
uint8_t tokencounter = 0;
|
|
|
|
char *start = strrchr(command_in, 'A');
|
|
|
|
// remove first (B is ignored by atoi)
|
|
start++;
|
|
|
|
token = strtok(start, ",");
|
|
|
|
while( token ) {
|
|
if (tokencounter == 3) {
|
|
power_gen = atoi(token);
|
|
}
|
|
|
|
tokencounter++;
|
|
token = strtok(NULL, ",");
|
|
}
|
|
}
|
|
}
|
|
|
|
static void work_uart() {
|
|
|
|
uint8_t c = uart_getc();
|
|
|
|
if ( !(c & UART_NO_DATA) ) {
|
|
data_in[data_count] = c;
|
|
|
|
if (data_in[data_count] == 'B') {
|
|
data_count = 0;
|
|
|
|
memcpy(command_in, data_in, BUFSIZE);
|
|
memset(data_in, 0, BUFSIZE);
|
|
|
|
process_command();
|
|
} else {
|
|
data_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void set_servo(uint8_t power) {
|
|
|
|
uint8_t display = 0;
|
|
|
|
// display = power * 10; // shift, since we have to divide by 2,4 (24)
|
|
// display = display / 24; // instead of dividing by 2,4
|
|
// display = display + 125;
|
|
|
|
display = power;
|
|
|
|
OCR1A = 2500-display;
|
|
}
|
|
|
|
|
|
static void demo_display(void) {
|
|
for(uint8_t i = 0; i< 30;i = i+1) {
|
|
set_servo(i*10);
|
|
wait(100);
|
|
}
|
|
|
|
for(uint8_t i = 10; i>= 0;i = i-1) {
|
|
set_servo(i*5);
|
|
wait(100);
|
|
}
|
|
|
|
}
|
|
|
|
int main(void) {
|
|
|
|
ports_init();
|
|
timer_init();
|
|
uart_init(UART_BAUD_SELECT(19200,F_CPU));
|
|
memset(data_in, 0, BUFSIZE);
|
|
|
|
demo_display();
|
|
|
|
// while(1) {
|
|
// work_uart();
|
|
|
|
if(syscounter >= 10) {
|
|
uart_putc('a'); // send a to receive values
|
|
|
|
set_servo(power_gen);
|
|
syscounter = 0;
|
|
//}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
SIGNAL(TIMER1_COMPA_vect) {
|
|
syscounter++;
|
|
|
|
OCR1A = 2500-OCR1A; // Das Servosignal wird aus der Differenz von
|
|
// Periodenlänge (2500*0,008ms=20ms) und letztem
|
|
// Vergleichswert (OCR1A) gebildet
|
|
}
|
|
|
|
|