#include <avr/io.h>
#include <avr/interrupt.h>
//tamaño de los buffers
#define BUFFER_SIZE 64
//macros
#define MOD(n) ((n) & (BUFFER_SIZE-1))
#define INC(idx) idx = (MOD(idx+1))
#define IS_BUFFER_EMPTY(buf) (buf.in_idx == buf.out_idx)
#define IS_BUFFER_FULL(buf) (MOD(buf.in_idx-1) == buf.out_idx)
typedef struct {
char buffer[BUFFER_SIZE]; /* espacio reservado */
volatile unsigned char in_idx; /* indice entrada (Head) */
volatile unsigned char out_idx; /* indice entrada (tail) */
} ring_buffer_t;
ring_buffer_t tx_buffer;
ring_buffer_t rx_buffer;
void itoa(uint16_t number, char * str, uint8_t base){
uint8_t index = 0;
uint8_t index_aux=0;
char temp;
if (base == 16 ) {
while(number>0) {
str[index] = number%base;
if (str[index]>9) {
str[index] = str[index] + 'A'- 10;
}
else {
str[index] = str[index] + '0';
}
number=number/base;
index++;
}
}
else {
while (number>0) {
str[index] = number % base + '0';
number=number/base;
index++;
}
}
index--;
for (index_aux = 0; index_aux < index; index_aux++, index--) {
temp = str[index_aux];
str[index_aux] = str[index];
str[index] = temp;
}
}
uint16_t atoi (char * str) {
uint8_t index = 0;
uint16_t entero = 0;
while (str[index] != '\0') {
entero = entero * 10 + str[index] - '0';
index ++ ;
}
return entero;
}
char UART_getchar( void ){
UCSR0B |= (1 << RXCIE0);
while(IS_BUFFER_EMPTY(rx_buffer));
char data = rx_buffer.buffer[rx_buffer.out_idx];
INC(rx_buffer.out_idx);
return data;
}
void UART_putchar( char data ) {
while (IS_BUFFER_FULL(tx_buffer));
tx_buffer.buffer[tx_buffer.in_idx]=data;
INC(tx_buffer.in_idx);
UCSR0B |= (1 << UDRIE0);
}
void UART_gets (char * str ) {
uint8_t cnt_gets=0;
do {
str[cnt_gets]=UART_getchar();
UART_putchar(str[cnt_gets]);
cnt_gets++;
} while (str[cnt_gets-1] != 13);
str[cnt_gets-1]='\0';
}
void UART_puts( char *str) {
uint8_t puts_cnt=0;
while (str[puts_cnt] != '\0') {
UART_putchar( str[puts_cnt] );
puts_cnt++;
}
}
void UART_gotoxy( uint8_t x, uint8_t y) {
char xy[9]= {
'\033',
'[',
y/10 + '0',
y%10 + '0',
';',
x/10 + '0',
x%10 + '0',
'H',
'\0'
};
UART_puts( xy);
}
void UART_clrscr( void ) {
char cls[] = "\033[H\033[2J";
UART_puts(cls);
}
void UART_Ini(uint8_t com, uint32_t baudrate, uint8_t size, uint8_t parity, uint8_t stop) {
uint32_t X20, X21, error0, error1;
X20=(10000000/baudrate + 5 -10 ) / 10;
X21=(20000000/baudrate + 5 -10 ) / 10;
error0 = ( (100000000/ (X20+1) ) / baudrate - 100);
error1 = ( (200000000/ (X21+1) ) / baudrate - 100);
if (com<2) {
*(&UCSR0B + 8 * com ) = (1 << RXCIE0) | (1 << UDRIE0) | (1<< RXEN0) | (1 << TXEN0);
*(&UCSR0C + 8 * com ) = ((size-5) << UCSZ00) | (parity<<UPM00) | (stop<<USBS0);
if (error1>=error0) {
*(&UBRR0 + 8 * com ) = X20;
}
else {
*(&UBRR0 + 8 * com ) = X21;
*(&UCSR0A + 8 * com ) |= (1 << U2X0);
}
}
else {
UCSR3B = (1 << RXCIE0) | (1 << UDRIE0) | (1<< RXEN0) | (1 << TXEN0); ;
UCSR3C = ((size-5) << UCSZ00) | (parity<<UPM00) | (stop<<USBS0);
if ( error1 >= error0 ) {
UBRR3 = X20;
}
else {
UBRR3 = X21;
UCSR3A |= (1 << U2X0);
}
}
sei();
}
ISR ( USART0_UDRE_vect ) {
if (!(IS_BUFFER_EMPTY(tx_buffer))) {
UDR0=tx_buffer.buffer[tx_buffer.out_idx];
INC(tx_buffer.out_idx);
}
else {
UCSR0B &= ~ (1<<UDRIE0);
}
}
ISR ( USART0_RX_vect ) {
if (!(IS_BUFFER_FULL(rx_buffer))) {
rx_buffer.buffer[rx_buffer.in_idx] = UDR0;
INC(rx_buffer.in_idx);
}
else {
UCSR0B &= ~(1 << RXCIE0);;
}
}
int main (void) {
UART_Ini(0,9600,8,0,0);
char cad[20]="255";
uint16_t num;
rx_buffer.in_idx=0;
rx_buffer.out_idx=0;
tx_buffer.in_idx=0;
tx_buffer.out_idx=0;
while(1) {
itoa(num, cad , 16);
UART_puts(cad);
}
return 0;
}