usart/src/usart.cpp

128 lines
3.8 KiB
C++

#include <avr/io.h>
#include <avr/interrupt.h>
#include "usart.h"
namespace usart
{
void init( unsigned long baud) {
const unsigned int ubrr = F_CPU/8/baud-1;
/*Set baud rate */
#if defined __AVR_ATmega328P__
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
UCSR0A |= (1<<U2X0);
//Enable receiver and transmitter
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
//UCSRB |= (1<< RXCIE)|(1<<TXCIE);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
#elif defined __AVR_ATmega32__ || defined __AVR_ATmega16__
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;
UCSRA |= (1<<U2X);
//Enable receiver and transmitter
UCSRB = (1<<RXEN)|(1<<TXEN);
//UCSRB |= (1<< RXCIE)|(1<<TXCIE);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1 << URSEL)|(3<<UCSZ0);
#elif defined __AVR_ATtiny2313__
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;
UCSRA |= (1<<U2X);
//Enable receiver and transmitter
UCSRB = (1<<RXEN)|(1<<TXEN);
//UCSRB |= (1<< RXCIE)|(1<<TXCIE);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<USBS)|(3<<UCSZ0);
#endif
}
void put(char data) {
#if defined __AVR_ATmega328P__
while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = data;
#elif defined __AVR_ATmega32__ || defined __AVR_ATmega16__
while ( !( UCSRA & (1<<UDRE)) ); UDR = data;
#elif defined __AVR_ATtiny2313__
while ( !( UCSRA & (1<<UDRE)) ); UDR = data;
#endif
}
char get( void ) {
#if defined __AVR_ATmega328P__
while ( !(UCSR0A & (1<<RXC0)) ); return UDR0;
#elif defined __AVR_ATmega32__ || defined __AVR_ATmega16__ || defined __AVR_ATtiny2313__
while ( !(UCSRA & (1<<RXC)) ); return UDR;
#endif
}
void itoa(int n, char s[], int base) {
int i = 0;
int sign = n;
if (sign < 0) {
n = -n;
}
do {
s[i++] = n % base + '0';
} while ((n /= base) > 0);
if (sign < 0) {
s[i++] = '-';
}
s[i] = '\0';
// Reverse the string
for (int j = 0, k = i - 1; j < k; j++, k--) {
char temp = s[j];
s[j] = s[k];
s[k] = temp;
}
}
void printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
for (const char *p = fmt; *p != '\0'; p++) {
if (*p == '%') {
switch (*(++p)) {
case 's': {
const char *s = va_arg(args, const char *);
for (; *s; s++) put(*s);
break;
}
case 'd':
case 'i': {
char buf[10];
itoa(va_arg(args, int), buf, 10);
for (char *s = buf; *s; s++) put(*s);
break;
}
case 'c':
put(va_arg(args, int));
break;
case 'x': {
char buf[10];
itoa(va_arg(args, int), buf, 16);
for (char *s = buf; *s; s++) put(*s);
break;
}
}
} else {
put(*p);
}
}
va_end(args);
}
} // namespace usart