Files
HendiControlFirmware/Control/firmware/uart_echo/main.c
T
jens 189e3454d9 - update
git-svn-id: http://moon:8086/svn/projects/HendiControl@10 fda53097-d464-4ada-af97-ba876c37ca34
2019-02-14 20:27:43 +00:00

244 lines
3.9 KiB
C
Executable File

/*
* uart_echo.c
*
* Created: 16.08.2018 17:39:49
* Author : jens
*/
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define ARDUINO_NANO
#ifdef ARDUINO_NANO
#define F_CPU (16000000UL) // MHz
#else
#define F_CPU (18432000UL) // MHz
#endif
#define USART_BAUDRATE 9600UL
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define TIMER_RELOAD (0xFFFF-(F_CPU/1024/4-1))
static uint8_t rx_data;
static uint8_t count = 0;
volatile uint8_t msgCode = 0;
static uint8_t msgData = 0;
static uint8_t ledState = 0;
static int16_t adc_value[16];
static size_t adc_ch = 0;
enum MessageCode
{
NOP=0,
Command,
Timer,
AdcComplete,
Error = 0xFF
};
ISR(ADC_vect)
{
int16_t value_low = (int16_t)ADCL;
int16_t value_high = (int16_t)ADCH;
ADCSRA |= (1<<ADIF);
int16_t value = value_high << 8 | value_low;
if (((adc_value[adc_ch] - value) < -1) || ((adc_value[adc_ch] - value) > 1))
{
msgCode = AdcComplete;
msgData = adc_ch;
}
adc_value[adc_ch] = value;
adc_ch++;
if (adc_ch == 16)
{
adc_ch = 0;
}
adc_start_conversion(adc_ch);
}
ISR(USART_RX_vect)
{
rx_data = UDR0;
msgCode = NOP;
if (rx_data == ' ')
{
msgCode = Error;
}
else if (rx_data >= '0' && rx_data <= '9')
{
msgCode = Command;
msgData = rx_data;
}
count++;
}
ISR (TIMER1_OVF_vect) // Timer1 ISR
{
msgCode = Timer;
TCNT1 = TIMER_RELOAD;
ledState++;
if (ledState == 4)
{
ledState = 0;
}
}
void uart_init()
{
// Set baud rate
UBRR0L = (uint8_t)BAUD_PRESCALE;
UBRR0H = (uint8_t)(BAUD_PRESCALE >> 8);
// Enable receiver and transmitter
UCSR0B = (1<<TXEN0)|(1<<RXEN0);
// Enable RX interrupt
UCSR0B |= (1<<RXCIE0);
}
void timer_init()
{
TCNT1 = TIMER_RELOAD;
TCCR1A = 0x00;
TCCR1B = (1<<CS10) | (1<<CS12); // Timer mode with 1024 prescaler
TIMSK1 = (1 << TOIE1) ; // Enable timer1 overflow interrupt(TOIE1)
}
void adc_init()
{
PRR &= ~(1 << PRADC);
ADCSRA |= (1 << ADEN) | 7;
}
void adc_start_conversion(int ch)
{
ADMUX = (ADMUX & 0xF0) | (ch & 0x0F) | (1 << REFS0);
ADCSRA |= (1 << ADSC) | (1 << ADIE);
}
int adc_is_fininshed()
{
return (int)(0 == (ADCSRA & (1 << ADSC)));
}
int16_t adc_read()
{
return adc_value;
while(!adc_is_fininshed());
uint16_t value_low = (uint16_t)ADCL;
uint16_t value_high = (uint16_t)ADCH;
ADCSRA |= (1<<ADIF);
return value_high << 8 | value_low;
}
void uart_putc(char c)
{
while((UCSR0A & (1<<UDRE0)) == 0)
{
}
UDR0 = c;
}
int uart_putchar(char c, FILE *stream)
{
uart_putc(c);
if (c == 0x0A)
{
uart_putc(0x0D);
}
return 0;
}
void uart_puts(char const *str)
{
while(*str)
{
char c = *(str++);
uart_putc(c);
if (c == 0x0A)
{
uart_putc(0x0D);
}
}
}
void port_init()
{
PORTB = PORTB | 0x03;
DDRB = DDB1 | DDB2;
}
FILE uart_file = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
/* Replace with your application code */
uart_init();
timer_init();
adc_init();
stdout = &uart_file;
printf("UART test version 1.0\n\n");
sei();
adc_start_conversion(adc_ch);
while (1)
{
if (msgCode)
{
cli();
switch(msgCode)
{
case Command:
printf("Command : %c\n", msgData);
break;
case AdcComplete:
{
size_t ch = msgData;
if (ch == 6)
{
printf("ADC=%d\n", adc_value[ch]);
}
}
break;
case Timer:
switch(ledState)
{
case 0:
DDRB = (DDRB & 0xFC) | 0x00;
printf("----------- Timer -----------\n");
break;
case 1:
DDRB = (DDRB & 0xFC) | 0x01;
break;
case 2:
DDRB = (DDRB & 0xFC) | 0x03;
break;
case 3:
DDRB = (DDRB & 0xFC) | 0x02;
break;
}
break;
case Error:
printf("Error!!!\n");
break;
}
msgCode = NOP;
sei();
}
}
}