Monitorização de grandeza física e atuação - STM32F4-Discovery
-
Upload
fabiooliveira -
Category
Documents
-
view
106 -
download
0
description
Transcript of Monitorização de grandeza física e atuação - STM32F4-Discovery
// Ficheiro main.c
/* O presente programa controlo 4 LEDs do I/O Expander MCP23017 através de comunicação I2C e * efetua a leitura continuamente de um valor analógico (potenciómetro) através do A/D Converter * MCP3202. Consoante a tensão lida, é alterada a configuração dos LEDs e de 1 em 1 segundo é enviado* o valor da tensão lido pela porta USART. Quando a tensão ultrapassa os 2.5 V, os LEDs são * desativados e é enviada uma mensagem de erro ao utilizador. O sistema volta a funcionar normalmente* quando a tensão for inferior a 2.5 V e o utilizador enviar um "ok" pela porta série.* Adicionalmente, são enviados pela porta série o n.º de leituras por segundo e os segundos passados* desde o arranque do sistema para testar impacto nas leituras de diferentes velocidades do I2C, USART E SPI.*/
#include <stm32f4xx.h>#include <stdlib.h>#include <string.h>
// Declaração de variáveis globaisfloat ultima_leitura = 0, nova_leitura = 0; // Guarda a última leitura efetuadaint sistema_on = 1; // Indica se o sistema está ativo - 1 ON, 0 - OFFchar txt_in[255]; // Buffer de entrada para guardar os caracteres recebidos pela porta sériechar txt_out[255]; // Buffer de saída para envio de caracetres pela porta sérieint pos_in = 0; // Guarda ultima posição ocupada no buffer de entradaint pos_out = 0; // Guarda ultima posiçao ocupada no buffer de saidalong leituras = 0; // Conta quantas leituras são realizadas num segundolong t_ativo = 0; // Conta segundos ativos
//----------------------------------------------------------------------------------------------------------------------
//Configuração do periférico USART3void USART3_config (void){
GPIO_InitTypeDef GPIO_InitStruct; //Declaração de uma estrutura do tipo GPIO para configuração dos pinos associados à USARTUSART_InitTypeDef USART_InitStruct; //Declaração de uma estrutura do tipo USART para configuração do periférico USARTNVIC_InitTypeDef NVIC_InitStruct; //Declaração de uma estrutura do tipo NVIC para configuração das interrupções associadas ao módulo USART
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //Ativa relógio do periférico GPIOC - USART3 (PC10 TX / PC11 RX) RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //Ativa relógio do periférico USART3
//Configuração dos pinos do GPIO associados ao periférico USART3GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // Pin 10 TX e Pin 11 RXGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // Configuração como Alternate Function uma vez que funcionarão associados à USART3GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // Frequência do relógioGPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Definir os pinos como push / pullGPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // Ativar resistência Pull-Up
GPIO_Init(GPIOC, &GPIO_InitStruct); // Passar os parâmetros anteriores para o periférico GPIOC
//Associação dos pinos GPIO ao periférico USART3GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);
//Configuração do periférico USART3USART_InitStruct.USART_BaudRate = 9600; // Para comunicações mais rápidas colocar 921600 - baudrate maximo permitido pela interface SÉRIE/USBUSART_InitStruct.USART_WordLength = USART_WordLength_8b; // Envio de 8 bits por
trama (standard)USART_InitStruct.USART_StopBits = USART_StopBits_1; // 1 bit de paragem (standard)USART_InitStruct.USART_Parity = USART_Parity_No; // Sem bit de paridade (standard)USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // Sem controlo do fluxo de dados (standard)USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // Ativar transmissão e receção
USART_Init(USART3, &USART_InitStruct); // Passar os parâmetros anteriores para o periférico USART3
///Configuração da estrutura NVIC - interrupçõesNVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn; // Interrupção associado ao módulo USART3NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; // Associação ao NVIC_PriorityGroup_0NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; // Será a interrupção com maior prioridadeNVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // Ativar
NVIC_Init(&NVIC_InitStruct); // Regista as informações pretendidas
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // Sempre que o buffer de receção do módulo USART3 não estiver vazio, ocorrerá uma interrupção
USART_Cmd(USART3, ENABLE); // Ativa o módulo USART3}
//----------------------------------------------------------------------------------------------------------------------// Função para envio de texto pela porta sérievoid enviar_texto( char *txt){
strcpy(txt_out, txt); // Copia o texto a enviar para o 'buffer' de saída
pos_out = 0; // Reinicia a posição a enviar
USART_ITConfig(USART3, USART_IT_TXE, ENABLE); // Ativa interrupção quando se poder enviar novo caracter (Buffer de saída da USART livre)
}
//----------------------------------------------------------------------------------------------------------------------//Configuração do periférico I2C2void I2C2_config (void){
GPIO_InitTypeDef GPIO_InitStruct; // Declaração de uma estrutura do tipo GPIO para configuração dos pinos associados ao I2C2I2C_InitTypeDef I2C_InitStruct; // Declaração de uma estrutura do tipo I2C para configuração do periférico I2C2RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // Ativa relógio do periférico GPIOB (I2C2: PB10 SCL, PB11 SDA)RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); // Ativa relógio do periférico I2C2
//Configuração dos pinos do GPIO associados ao periférico I2C2: PB10 SCL, PB11 SDAGPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // PB10 SCL, PB11 SDAGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // Define os pinos como Alternate function porque serão utilizados com I2C2GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // Frequência do relógioGPIO_InitStruct.GPIO_OType = GPIO_OType_OD; // Open drain porque o pull-up vai ser realizado por hardwareGPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // Sem resistências ativas (explicado em cima)
GPIO_Init(GPIOB, &GPIO_InitStruct); // Passar os parâmetros anteriores para o periférico GPIOB
//Associação dos pinos GPIO ao periférico I2C2GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2); // SCLGPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2); // SDA
//Configuração do periférico I2C2I2C_InitStruct.I2C_ClockSpeed = 100000; // Para comunicações mais rápidas colocar frequência 400kHz - Table 54 datasheet da placa
STMI2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // Modo I2C I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle --> standardI2C_InitStruct.I2C_OwnAddress1 = 0x00; // Endereço próprio, irrelevante no modo masterI2C_InitStruct.I2C_Ack = I2C_Ack_Enable; // Ativar acknowledgeI2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // Endereços de 7 bits
I2C_Init(I2C2, &I2C_InitStruct); // Passar os parâmetros anteriores para o periférico I2C2
I2C_Cmd(I2C2, ENABLE); // Ativação do periférico I2C2while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); // Aguardar estabilização da BUS
/* Configuração inicial do I/O Expander* Neste caso pretende-se que as portas sejam configuradas como saídas e que iniciem desativadas.* Pela TABLE 1-4 do datasheet, o CI inicia com as portas do GPIOA configuradas como entrada,
* pelo que no início tem de se configurá-las como saídas. Pela mesma tabela, vê-se que iniciam desativadas,* pelo que não será necessário enviar um byte para desativá-las inicialmente.* O registo IOCON.BANK está configurado por defeito a 0 (TABLE 1-5)*/
I2C_GenerateSTART(I2C2, ENABLE); // Enviar condição de START
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); // Aguardar transmissão condição START// Enviar Byte de controlo, Página 8 do datasheetI2C_Send7bitAddress(I2C2, 0x42 , I2C_Direction_Transmitter); // Byte de controlo: 0100 + A2 A1 A0 R/W - W 0 R 1while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // Aguardar por transmissão do byte
I2C_SendData(I2C2, 0x0); // Envia byte com o registo a aceder do CI - IODIRA - Página 12 do datasheet
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Aguardar por transmissão do byteI2C_SendData(I2C2, 0x0);
// Envia byte com o valor a colocar no registowhile(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Aguardar por transmissão do byteI2C_GenerateSTOP(I2C2, ENABLE); // Termina a transmissãowhile(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Aguardar por transmissão do byte
}
//----------------------------------------------------------------------------------------------------------------------// Alterar estado dos LEDs do I/O Expandervoid alterar_LEDs ( int novo_valor ){
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); // Aguardar estabilização da BUS
I2C_GenerateSTART(I2C2, ENABLE); // Enviar condição de START
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT)); // Aguardar transmissão condição START// Enviar Byte de controlo, Página 8 do datasheetI2C_Send7bitAddress(I2C2, 0x42 , I2C_Direction_Transmitter); // Byte de controlo: 0100 + A2 A1 A0 R/Wwhile(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // Aguardar por transmissão do byteI2C_SendData(I2C2, 0x12);
// Envia byte com o registo a aceder do CI - GPIOA - Página 5 do datasheetwhile(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Aguardar por transmissão do byteI2C_SendData(I2C2, novo_valor & 0xFF);
// Envia byte com o valor a colocar no registo (considera apenas primeiros 8 bits)while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Aguardar por transmissão do byteI2C_GenerateSTOP(I2C2, ENABLE); // Termina a transmissãowhile(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // Aguardar por transmissão do byte
}//----------------------------------------------------------------------------------------------------------------------
//Configuração do periférico SPI1void SPI1_config (void){
GPIO_InitTypeDef GPIO_InitStruct; // Declaração de uma estrutura do tipo GPIO para configuração dos pinos associados ao SPI1 SPI_InitTypeDef SPI_InitStruct; // Declaração de uma estrutura do tipo SPI para configuração do periférico SPI1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // Ativa relógio do periférico GPIOA (SPI1: PA5(SCK) and PA6(MISO) E PA7(MOSI)) RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // Ativa relógio do periférico SPI1
//Configuração dos pinos do GPIO associados ao periférico SPI1GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7; // PA5(SCK), PA6(MISO), PA7(MOSI)GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // Define os pinos como
Alternate Function porque serão utilizados com SPI1GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // Frequência do relógioGPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Definir os pinos como push / pullGPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // Sem resistências ativas
GPIO_Init(GPIOA, &GPIO_InitStruct); // Passar os parâmetros anteriores para o periférico GPIOA
//Associação dos pinos GPIO ao periférico SPI1GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); //SCKGPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); //MISOGPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); //MOSI
//Configuração do pino do GPIO associado ao periférico SPI1 para o pino Chip_Select (LOW ativa a comunicação)GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; // Pino 4 do GPIOAGPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // Configurado como saídaGPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // Frequência do relógioGPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Definir os pinos como push / pullGPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // Resistência Pull Up ativa
GPIO_Init(GPIOA, &GPIO_InitStruct); // Passar os parâmetros anteriores para o periférico GPIOA
GPIO_SetBits(GPIOA, GPIO_Pin_4); // Desativa comunicação colocando CS non nível alto
//Configuração do periférico SPI1SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Modo full duplex, linhas MOSI e MISO funcionam separadamenteSPI_InitStruct.SPI_Mode = SPI_Mode_Master; // Transmissão como master, pino NSS tem de estar no nível HIGHSPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // Configuração de tramas com 8 bits (aplicação do exemplo da figura 6-1, página 15 do datasheet do
componente)SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // Relógio LOW quando idle - Modo SPI 0 (CPOL 0 CPHA 0) - ver página 15 datasheetSPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // Dados capaturados no rising edgeSPI_InitStruct.SPI_NSS = SPI_NSS_Soft; // Gestão do NSS por softwareSPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; // Para comunicações mais rápidas - frequência SPI = (APB2_frequency/64) -> Pag. 3 datasheet
CI, 1.8 MHz max -> 64 é o mais próximoSPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; // MSB transmitido primeiro
SPI_Init(SPI1, &SPI_InitStruct); // Passar os parâmetros anteriores para o periférico SPI1
SPI_Cmd(SPI1, ENABLE); // Ativa o periférico SPI1
while(SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)); // Aguardar estabilização da BUS}
//----------------------------------------------------------------------------------------------------------------------//Leitura do valor da tensãovoid ler_tensao( void ){
int aux1 = 0, aux2 = 0; // Variáveis para cálculo do valor lido
while(SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)); // Aguardar estabilização da BUS GPIO_ResetBits(GPIOA, GPIO_Pin_4); // Ativar slaveSPI_I2S_SendData(SPI1, 0x1); // Envia 1.º byte para o slave, ver figura 6-1,
página 15 do datasheetwhile(!SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); // Aguarda que o byte tenha sido enviadowhile(SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)); // Aguardar estabilização da BUS
SPI_I2S_ReceiveData(SPI1); // Lê 1.º byte recebido do I/O e ignora-o, visto que não tem significado (ver figura 6-1, página 15 do datasheet)
SPI_I2S_SendData(SPI1, 0xA0); // Envia 2.º byte para o slave, ver figura 6-1, página 15 do datasheet (consultar também tabela 5-1, página 13, de forma a definir as opções de leitura)
while(!SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); // Aguarda que o byte tenha sido enviadowhile(SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)); // Aguardar estabilização da BUS
aux1 = SPI_I2S_ReceiveData(SPI1)&0xF; // Lê 2.º byte recebido que contém os 4 MBS e ignora os restantes
SPI_I2S_SendData(SPI1, 0x0); // Envia 3.º byte para o slave, ver figura 6-1, página 15 do datasheet
while(!SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); // Aguarda que o byte tenha sido enviadowhile(SPI_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY)); // Aguardar estabilização da BUS
aux2 = SPI_I2S_ReceiveData(SPI1); // Lê 3.º byte recebido que contém os retantes 8 MBS
GPIO_SetBits(GPIOA, GPIO_Pin_4); // Desativa o slave
aux1 = (aux1 << 8) + aux2; // Calcula valor final
nova_leitura = ( (float)aux1 * 4.77 / 4095 ); // Calcula valor em tensão 4.77V medido com multimetro
leituras++; // Incrementa o número de leituras
if (nova_leitura != ultima_leitura){ // Se ocorrer uma variação da tensão, executa o seguinte código // Isto serve para
evitar que se a tensão for igual à anterior se perca tempoultima_leitura = nova_leitura; // Guarda novo valor lido
if(ultima_leitura >= 2.5){ // Se tensão superior ao limite, desativa saídas alterar_LEDs(0); // Alteração das saídasif(sistema_on == 1) // Se é a primeira vez que a tensão é superior a 2,5V
enviar_texto( "\n\n DANGER! \n Tensao superior a 2.5V "); // Envia mensagem de alerta sistema_on = 0; // Desativa o sistema
}else{ // Se a tensão está normal
if(sistema_on == 1){ // E o sistema está ativo (para prevenir que se a tensão estiver normal mas o sistema ainda não tiver sido ativado pelo utilizador)
if(ultima_leitura >= 0.0 && ultima_leitura < 0.5) // Se a tensão estiver compreendida neste intervaloalterar_LEDs(0); // Alteração das saídas
elseif(ultima_leitura >= 0.5 && ultima_leitura < 1.0) // Se a tensão estiver compreendida neste intervalo
alterar_LEDs(1); // Alteração das saídaselse
if(ultima_leitura >= 1.0 && ultima_leitura < 1.5) // Se a tensão estiver compreendida neste intervaloalterar_LEDs(3); // Alteração das saídas
elseif(ultima_leitura >= 1.5 && ultima_leitura < 2.0) // Se a tensão estiver compreendida neste intervaloalterar_LEDs(7); // Alteração das saídaselse
if(ultima_leitura >= 2.0 && ultima_leitura < 2.5) // Se a tensão estiver compreendida neste intervalo
alterar_LEDs(15); // Alteração das saídas}
}}
}//----------------------------------------------------------------------------------------------------------------------// Configuração do TIMER 3 - 1 segundovoid TIM3CONFIG(){
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Variável para declarar propriedades do periférico TIMER NVIC_InitTypeDef NVIC_InitStruct; // Declaração de uma estrutura do tipo NVIC para configuração das interrupções associada ao TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // Ativação do relógio do periférico Timer 3
// Especificações das propriedades do TIM3// (F_clock_tim = F_clock_mcu/Prescaler = 84MHz/42kHz = 2kHz)TIM_TimeBaseStructure.TIM_Prescaler = 42000 - 1;// Timer_trigger = Period / F_clock_tim = 2000 cycles / 2 kHz = 1 segundoTIM_TimeBaseStructure.TIM_Period = 2000 - 1; // 2000 para ser 1 segundoTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // Dividir o clock por 1TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // Regista as informações pretendidas
// Configuração da interrupção associada ao TIMER 3NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01; // Menos prioritária que a da USART3NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStruct); // Regista as informações pretendidas
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // Ativação da interrupção associada ao TIM3
TIM_Cmd(TIM3, ENABLE); // Ativação do TIM3 }
//----------------------------------------------------------------------------------------------------------------------// Função principalint main(void){
USART3_config(); // Função para configuração da USARTI2C2_config(); // Função para configuração dO I2CSPI1_config(); // Função para configuração dO SPI//ler_tensao(); // Ativar para evitar que primeira leitura enviada seja '0V' TIM3CONFIG(); // // Função para configuração do Temporizador
while(1){ // To infinity, and beyond! ler_tensao(); // Monitoriza a tensão
}return 0;
}// Ficheiro stm32f4xx_it.c
extern float ultima_leitura, nova_leitura; extern int sistema_on; extern char txt_in[255]; extern char txt_out[255];extern int pos_in; extern int pos_out;extern long leituras;extern long t_ativo;
//----------------------------------------------------------------------------------------------------------------------// Tratamento da interrupção TIM 3void TIM3_IRQHandler(void){
char aux[100];if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET){ //Formalismo porque na verdade se o programa
// chegou aqui, é porque houve interrupçãoTIM_ClearITPendingBit(TIM3, TIM_IT_Update); // Desativar a FLAGt_ativo++;if(sistema_on == 1){ // Se o sistema estiver ativo
sprintf(aux, "\n\n Tensao %.1f V \n Leituras %lu \n Segundos %lu ", ultima_leitura, leituras, t_ativo); //Conversão da tensão, do número de leituras e do tempo ativo para string
//sprintf(aux, "\n Tensao %.1f V ", ultima_leitura); // Conversão só da tensão para textoenviar_texto(aux); // Solicitar o envio do textoleituras = 0; // Reset ao número de leituras
}}
}
//----------------------------------------------------------------------------------------------------------------------
// Tratamento das interrupções associadas à porta USARTvoid USART3_IRQHandler(void){
if (USART_GetITStatus(USART3, USART_IT_RXNE)){ // Se há dados para lertxt_in[pos_in] = USART_ReceiveData(USART3); // Lê o dado// Se o caracter não é CR nem o nova linha nem se atingiu o espaço máximo do 'buffer'if(txt_in[pos_in] != 13 && txt_in[pos_in] != '\n' && pos_in < 253){
pos_in++; // Passa-se para a seguitne posição do buffer}else{ // Caso se verifique qualquer das condições anteriores
txt_in[pos_in] = '\0'; // Assinala-se o fim do texto recebidopos_in = 0; // Reinicializa-se a posição para futura leitura// Se se recebeu um OKif( (txt_in[0] == 'o' && txt_in[1]=='k') || (txt_in[0] == 'O' && txt_in[1]=='K')){
// Se a tensão não estiver normaçif(ultima_leitura >= 2.5){
enviar_texto( "\n\n DANGER! \n Tensao superior a 2.5V "); // Envio de aviso pela porta série}// Se a tensão estiver normalelse{
enviar_texto("\n\n Sistema ativo "); // Envio de aviso pela porta sériesistema_on = 1; // Ativa o sistema
}}
}}if(USART_GetITStatus(USART3, USART_IT_TXE) ){ // Se há dados para enviar ocorrerá esta interrupção
if(txt_out[pos_out] != '\0'){ // Se há dados para enviarUSART_SendData(USART3, txt_out[pos_out]); // Envia caracterpos_out++; // Passa para
a posição seguinte }else{ // Se já enviou os dados todos
pos_out = 0; // Reinicializa a posição do 'buffer' de saída
USART_ITConfig(USART3, USART_IT_TXE, DISABLE); // Desativa interrupção de quando buffer de envio da USART está livre}
}}