added UART functions for printing numbers

pull/1/head
Ondřej Hruška 9 years ago
parent 78f0398ef1
commit 877df1a3ed
  1. 150
      lib/uart.c
  2. 65
      lib/uart.h

@ -3,9 +3,11 @@
#include <util/delay.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "uart.h"
void _uart_init_do(uint16_t ubrr) {
/*Set baud rate */
UBRR0H = (uint8_t) (ubrr >> 8);
@ -29,6 +31,7 @@ void uart_isr_rx(bool yes)
}
}
/** Enable or disable TX ISR (1 byte is sent) */
void uart_isr_tx(bool yes)
{
@ -39,6 +42,7 @@ void uart_isr_tx(bool yes)
}
}
/** Enable or disable DRE ISR (all is sent) */
void uart_isr_dre(bool yes)
{
@ -50,8 +54,6 @@ void uart_isr_dre(bool yes)
}
/** Send byte over UART */
void uart_tx(uint8_t data)
{
@ -61,6 +63,17 @@ void uart_tx(uint8_t data)
UDR0 = data;
}
/** Receive one byte over UART */
uint8_t uart_rx()
{
// Wait for data to be received
while (!uart_rx_ready());
// Get and return received data from buffer
return UDR0;
}
/** Send string over UART */
void uart_puts(const char* str)
{
@ -69,6 +82,7 @@ void uart_puts(const char* str)
}
}
/** Send progmem string over UART */
void uart_puts_pgm(const char* str)
{
@ -78,14 +92,6 @@ void uart_puts_pgm(const char* str)
}
}
/** Receive one byte over UART */
uint8_t uart_rx()
{
// Wait for data to be received
while (!uart_rx_ready());
// Get and return received data from buffer
return UDR0;
}
/** Clear receive buffer */
void uart_flush()
@ -95,3 +101,127 @@ void uart_flush()
dummy = UDR0;
}
/** Send CRLF */
void uart_nl()
{
uart_tx(13);
uart_tx(10);
}
char tmpstr[12]; // buffer for number rendering
void _uart_putn(const uint8_t places);
/** Send unsigned int */
void uart_puti(const int16_t num)
{
ltoa(num, tmpstr, 10);
uart_puts(tmpstr);
}
/** Send signed int */
void uart_putu(const uint16_t num)
{
ltoa(num, tmpstr, 10);
uart_puts(tmpstr);
}
/** Send unsigned long */
void uart_putlu(const uint32_t num)
{
ltoa(num, tmpstr, 10);
uart_puts(tmpstr);
}
/** Send signed long */
void uart_putl(const int32_t num)
{
ltoa(num, tmpstr, 10);
uart_puts(tmpstr);
}
/** Send signed long as float */
void uart_putlf(const int32_t num, const uint8_t places)
{
if (num < 0) {
uart_tx('-');
ltoa(-num, tmpstr, 10);
} else {
ltoa(num, tmpstr, 10);
}
_uart_putn(places);
}
/** Send unsigned long as float */
void uart_putluf(const uint32_t num, const uint8_t places)
{
ltoa(num, tmpstr, 10);
_uart_putn(places);
}
/** Send signed int as float */
void uart_putif(const int16_t num, const uint8_t places)
{
if (num < 0) {
uart_tx('-');
itoa(-num, tmpstr, 10);
} else {
itoa(num, tmpstr, 10);
}
_uart_putn(places);
}
/** Send unsigned int as float */
void uart_putuf(const uint16_t num, const uint8_t places)
{
ltoa(num, tmpstr, 10);
_uart_putn(places);
}
/** Print number in tmp string as float with given decimal point position */
void _uart_putn(const uint8_t places)
{
// measure text length
uint8_t len = 0;
while(tmpstr[len] != 0) len++;
int8_t at = len - places;
// print virtual zeros
if (at <= 0) {
uart_tx('0');
uart_tx('.');
while(at <= -1) {
uart_tx('0');
at++;
}
at = -1;
}
// print the number
uint8_t i = 0;
while(i < len) {
if (at-- == 0) {
uart_tx('.');
}
uart_tx(tmpstr[i++]);
}
}

@ -1,5 +1,12 @@
#pragma once
/*
Utilities for UART communication.
First, init uart with desired baud rate using uart_init().
Then, enable interrupts you want, and that's it.
*/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
@ -7,16 +14,19 @@
#include <stdint.h>
/** Init UART for given baudrate */
void _uart_init_do(uint16_t ubrr); // internal, needed for the macro.
#define uart_init(baud) _uart_init_do(F_CPU / 16 / (baud) - 1)
void _uart_init_do(uint16_t ubrr);
/** Check if there's a byte in the RX register */
#define uart_rx_ready() (0 != (UCSR0A & (1 << RXC0)))
/** Check if transmission of everything is done */
#define uart_tx_ready() (0 != (UCSR0A & (1 << UDRE0)))
// Enable UART interrupts
/** Enable or disable RX ISR */
void uart_isr_rx(bool enable);
@ -26,18 +36,59 @@ void uart_isr_tx(bool enable);
/** Enable or disable DRE ISR (all is sent) */
void uart_isr_dre(bool enable);
// Basic IO
/** Receive one byte over UART */
uint8_t uart_rx();
/** Send byte over UART */
#define uart_putc(data) uart_tx(data)
#define uart_putc(data) uart_tx((data))
void uart_tx(uint8_t data);
/** Clear receive buffer */
void uart_flush();
// Strings
/** Send string over UART */
void uart_puts(const char* str);
/** Send progmem string over UART */
void uart_puts_pgm(const char* str);
/** Receive one byte over UART */
uint8_t uart_rx();
/** Clear receive buffer */
void uart_flush();
// Numbers
/** Send unsigned int */
void uart_puti(const int16_t num);
/** Send signed int */
void uart_putu(const uint16_t num);
/** Send unsigned long */
void uart_putlu(const uint32_t num);
/** Send signed long */
void uart_putl(const int32_t num);
/** Send signed long as float */
void uart_putlf(const int32_t num, const uint8_t places);
/** Send unsigned long as float */
void uart_putluf(const uint32_t num, const uint8_t places);
/** Send signed int as float */
void uart_putif(const int16_t num, const uint8_t places);
/** Send unsigned int as float */
void uart_putuf(const uint16_t num, const uint8_t places);
// Extras
/** Send CRLF */
void uart_nl();

Loading…
Cancel
Save