//Bibliotecas:
#define __ATmega2560__
#define __AVR_ATmega2560__
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <stdint.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdbool.h>
#include <stdint.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdlib.h>
#include <avr/interrupt.h>
/*Escreva um procedimento para receber pelo periférico USART0 os seguintes tipos de
dados:
a) Uma string.
b) Um número inteiro.
c) Um número em ponto flutuante
Os dígitos e outros símbolos dos números são recebidos como caracteres. Escreva um
programa para testar os procedimentos.
*/
//---------------------------------------------------------------------------------------------
/**
* @brief Este procedimento recebe uma string da USART0 até preenchermos um buffer.
A string é enviada pelo terminal quando pressionamos a tecla enter do
teclado, enviando o caractere nova linha, 0x0A.
*
* @param buffer Um ponteiro para um buffer. O buffer guarda os caracteres recebidos
* pela USART0 e o caractere nulo, '\0', marcando o final da string.
* @param tamanho Tamanho do buffer, em bytes.
*/
void USART0_recebe_string(uint8_t* buffer, uint8_t tamanho) {
char ch; // armazena o caractere lido da USART0
uint8_t* ptr_fim_buffer; // apontador para o final do buffer, antes do caractere nulo
ptr_fim_buffer = &buffer[tamanho - 1]; // apontamos para o último caratere do buffer antes do nulo
while (1) { // repita
ch = USART0_recebe(); // ch armazena um caractere lido da USART0
if (ch == 0x0A) { // se o caractere é um nova linha (tecla enter)
break; // termina o recebimento dos caracteres pela USART0
}
if (buffer < ptr_fim_buffer) { // enquando não chegamos no final do buffer
*buffer = ch; // adicione o caractere lido da USART0 no buffer
buffer++; // aponte para a próxima entrada do buffer
}
}
*buffer = '\0';
}
/**
* @brief Recebe pela USART0 uma string que é convertida em um inteiro tipo long.
*
* @return long Valor intiro longo recebido pela USART0
*/
long USART0_recebe_long() {
const uint8_t tamanho_buffer = 16; // tamanho do buffer
char buffer[tamanho_buffer]; // buffer para receber dados da USART0
USART0_recebe_string((uint8_t*)buffer, tamanho_buffer); // recebemos a string com o inteiro
return strtol(buffer, (char**)NULL, 10); // retornamos um inteiro
}
/**
* @brief Transmite pela USART0 um inteiro tipo long. O long é transmitido como
* uma string.
*
* @param data um inteiro tipo longo que é transmitido pela USART0.
*/
void USART0_transmite_long(long data) {
char buffer[16]; // um buffer para a string com o inteiro a ser tranmitido
ltoa(data, buffer, 10); // convertemos o inteiro em uma string
USART0_transmite_string_RAM((uint8_t*)buffer); // transmitimos a string com o inteiro pela USART0
}
/**
* @brief Recebe pela USART0 uma string contendo um número em ponto flutuante.
* A string é convertida em um número em ponto flutuante, tipo float
*
* @return float número em ponto flutuante recebido pela USART0 como uma string
*/
float USART0_recebe_float() {
const uint8_t tamanho_buffer = 16; // tamanho do buffer
char buffer[tamanho_buffer]; // buffer para receber dados da USART0
USART0_recebe_string((uint8_t*)buffer, tamanho_buffer); // recebemos pela USART0 a string com o float
return strtod(buffer, (char**)NULL); // convertemos a string em um número em ponto flutuante
}
/**
* @brief Transmite pela USART0 uma string de um número tipo float, no formato [-]d.dddE±dd
*
* @param dado valor (tipo float) que será trasmitido
*/
void USART0_transmite_float(float dado) {
char buffer[11]; // buffer para armazenar o número no formato [-]d.dddE±dd e o caractere nulo
dtostre(dado, buffer, 3, DTOSTR_UPPERCASE); // convertemos de float para uma string. Esta não é uma função ISO C
USART0_transmite_string_RAM(buffer); // transmite a string com o valor dp float
}
/**
* @brief
*
* @return int Este procedimento não retorna
*/
int main(void) {
const uint8_t tamanho_buffer = 16; // tamanho do buffer
uint8_t buffer[tamanho_buffer]; // buffer para receber dados da USART0
// configuramos a USART0 para transmitir a 57600 Baud, quadros 8N1, para um microcontrolador a 16 MHz
USART0_configura();
while (1) { // Realizamos alguns testes dos procedimentos
// teste do envio de uma string pelo terminal
USART0_transmite_string_FLASH(PSTR("Digite uma string: "));
USART0_recebe_string(buffer, tamanho_buffer);
USART0_transmite('|');
USART0_transmite_string_RAM(buffer);
USART0_transmite('|');
USART0_transmite('\n');
// teste do envio de um inteiro, tipo long
USART0_transmite_string_FLASH(PSTR("Digite um inteiro: "));
long l;
l = USART0_recebe_long();
USART0_transmite('\n');
USART0_transmite_string_FLASH(PSTR("inteiro recebido: "));
USART0_transmite_long(l);
USART0_transmite('\n');
// teste do envio de um número em ponto flutuante, tipo float
USART0_transmite_string_FLASH(PSTR("Digite um número em ponto flutuante: "));
float f;
f = USART0_recebe_float();
USART0_transmite('\n');
USART0_transmite_string_FLASH(PSTR("float recebido: "));
USART0_transmite_float(f);
USART0_transmite('\n');
}
return 0; // este procedimento não deve retornar
}