switch from UART to USART

This commit is contained in:
King Kévin 2016-01-18 16:04:31 +01:00
parent f42fcc3b8f
commit 44c609699d
3 changed files with 20 additions and 125 deletions

View File

@ -1,62 +0,0 @@
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* This library handles the USART configuration */
#include <stdint.h> // Standard Integer Types
#include <stdio.h> // Standard IO facilities
#include <stdlib.h> // General utilities
#include <avr/io.h> // AVR device-specific IO definitions
#include "uart.h" // UART header
#include <util/setbaud.h> // Helper macros for baud rate calculations
/* assign input and output streams */
FILE uart_output = FDEV_SETUP_STREAM((int (*)(char, struct __file *)) uart_putchar, NULL, _FDEV_SETUP_WRITE);
FILE uart_input = FDEV_SETUP_STREAM(NULL, (int (*)(struct __file *)) uart_getchar, _FDEV_SETUP_READ);
FILE uart_io = FDEV_SETUP_STREAM((int (*)(char, struct __file *)) uart_putchar, (int (*)(struct __file *)) uart_getchar, _FDEV_SETUP_RW);
/* configure serial port */
void uart_init(void)
{
UBRR0H = UBRRH_VALUE; // set baurate (calculated from BAUD)
UBRR0L = UBRRL_VALUE; // set baurate (calculated from BAUD)
#if USE_2X
UCSR0A |= (1<<U2X0); // use double speed (set depending on BAUD)
#else
UCSR0A &= ~(1<<U2X0); // do not use double speed (set depending on BAUD)
#endif
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); // 8N1 bit data
UCSR0B = (1<<RXEN0)|(1<<TXEN0); // enable RX and TX
UCSR0B |= (1<<RXCIE0); // enable RX complete interrupt
}
/* put character on UART stream */
void uart_putchar(char c, FILE *stream)
{
if (c == '\n') { // add carrier return before line feed. this is recommended for most UART terminals
uart_putchar('\r', stream);
}
while (!(UCSR0A&(1<<UDRE0))); // wait for transmit register to empty
UDR0 = c; // put data in transmit register
while (!(UCSR0A&(1<<TXC0))); // wait for transmission to complete (else sleep mode can break it)
UCSR0A |= (1<<TXC0); // clear transmit flag
}
/* get character from UART stream (blocking) */
char uart_getchar(FILE *stream)
{
while (!(UCSR0A&(1<<RXC0))); // wait until data exists
return UDR0;
}

View File

@ -1,33 +0,0 @@
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* This library handles the USART configuration */
/* set tolerance to 3% to allow 115200 baudrate with 16 MHz clock, else use 9600 for default <2% */
#define BAUD_TOL 3
/* serial baudrate, in bits per second (with 8N1 8 bits, no parity bit, 1 stop bit settings) */
#define BAUD 115200
/* input & output streams */
FILE uart_output;
FILE uart_input;
FILE uart_io;
/* configure serial port */
void uart_init(void);
/* put character on UART stream (blocking) */
void uart_putchar(char c, FILE *stream);
/* get character from UART stream (blocking) */
char uart_getchar(FILE *stream);

50
main.c
View File

@ -26,7 +26,7 @@
#include <avr/pgmspace.h> // Program Space Utilities
#include <avr/sleep.h> // Power Management and Sleep Modes
#include "uart.h" // basic UART functions
#include "usart.h" // basic USART functions
#include "main.h" // main definitions
/* help strings */
@ -46,11 +46,11 @@ PGM_P const help_table[] PROGMEM = {
};
/* global variables */
char uart_in[32] = {0}; // user input from USART
volatile uint8_t uart_in_i = 0; // how many UART characters have been input
char usart_in[32] = {0}; // user input from USART
volatile uint8_t usart_in_i = 0; // how many USART characters have been input
/* flags, set in the interrupts and handled in the main program */
volatile bool uart_flag = false; // UART input data is available
volatile bool usart_flag = false; // USART input data is available
/* switch off LED */
void led_off(void)
@ -162,16 +162,6 @@ void help(void)
}
}
/* save the UART input into a string */
ISR(USART_RX_vect) { /* UART receive interrupt */
uart_in[uart_in_i] = getchar(); // save input
if (uart_in_i<sizeof(uart_in)-1) { // go to next if there is space left (else overwrite last)
uart_in_i++; // prepare for next character
uart_in[uart_in_i] = 0; // always end the string
}
uart_flag = true; // notify new character is there
}
/* disable watchdog when booting */
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
void wdt_init(void)
@ -185,10 +175,10 @@ void wdt_init(void)
/* initialize GPIO */
void io_init(void)
{
/* use UART as terminal */
uart_init();
stdout = &uart_output;
stdin = &uart_input;
/* use USART as terminal */
usart_init();
stdout = &usart_output;
stdin = &usart_input;
/* gpio */
/* LED */
@ -203,7 +193,7 @@ void command_action()
{
/* split command */
const char* delimiter = " ";
char* word = strtok(uart_in,delimiter);
char* word = strtok(usart_in,delimiter);
if (!word) {
goto error;
}
@ -280,27 +270,27 @@ error:
int main(void)
{
uint8_t uart_out_i = 0; // how many UART input characters have been processed
uint8_t usart_out_i = 0; // how many UART input characters have been processed
io_init(); // initialize IOs
printf(PSTR("welcome to the demo code\n"));
while (true) { // endless loop for micro-controller
while (uart_flag) { // new UART input
uart_flag = false;
while (uart_out_i<uart_in_i) {
putchar(uart_in[uart_out_i++]); // print current character
while (usart_flag) { // new UART input
usart_flag = false;
while (usart_out_i<usart_in_i) {
putchar(usart_in[usart_out_i++]); // print current character
}
if ('\n'==uart_in[uart_in_i-1] || '\r'==uart_in[uart_in_i-1]) { // end of line detected
if ('\r'==uart_in[uart_in_i-1]) { // be sure to print a newline (for windows and mac EOL)
if ('\n'==usart_in[usart_in_i-1] || '\r'==usart_in[usart_in_i-1]) { // end of line detected
if ('\r'==usart_in[usart_in_i-1]) { // be sure to print a newline (for windows and mac EOL)
putchar('\n');
}
uart_in[uart_in_i-1] = 0; // remove end of line
if (uart_in_i>1) { // ignore empty lines
usart_in[usart_in_i-1] = 0; // remove end of line
if (usart_in_i>1) { // ignore empty lines
command_action(); // process command
}
uart_out_i = 0; // reset output
uart_in_i = 0; // reset input
usart_out_i = 0; // reset output
usart_in_i = 0; // reset input
}
}
/* go to sleep and wait for next interrupt */