Monitorização de grandeza física e atuação - STM32F4-Discovery

17

description

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 lida 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 o impacto nas leituras de diferentes velocidades do I2C, USART E SPI.

Transcript of Monitorização de grandeza física e atuação - STM32F4-Discovery

Page 1: Monitorização de grandeza física e atuação - STM32F4-Discovery
Page 2: 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

Page 3: Monitorização de grandeza física e atuação - STM32F4-Discovery

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

Page 4: Monitorização de grandeza física e atuação - STM32F4-Discovery

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)

Page 5: Monitorização de grandeza física e atuação - STM32F4-Discovery

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

Page 6: Monitorização de grandeza física e atuação - STM32F4-Discovery

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

}//----------------------------------------------------------------------------------------------------------------------

Page 7: Monitorização de grandeza física e atuação - STM32F4-Discovery

//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

Page 8: Monitorização de grandeza física e atuação - STM32F4-Discovery

//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

Page 9: Monitorização de grandeza física e atuação - STM32F4-Discovery

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

Page 10: Monitorização de grandeza física e atuação - STM32F4-Discovery

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

Page 11: Monitorização de grandeza física e atuação - STM32F4-Discovery

// 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

Page 12: Monitorização de grandeza física e atuação - STM32F4-Discovery

}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

}}

}

//----------------------------------------------------------------------------------------------------------------------

Page 13: Monitorização de grandeza física e atuação - STM32F4-Discovery

// 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

Page 14: Monitorização de grandeza física e atuação - STM32F4-Discovery

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}

}}