/******************************************************************************
* Nome do Arquivo : main.c
*
* Descricao : Implementa o programa principal
*
* Ambiente : VSCode e RP2040 C/C++ SDK
*
* Responsavel : Torres, Weslley
*
* Versao/Data : v00.01 - 23/05/2025 - versao inicial
*
*****************************************************************************/
/******************************************************************************
HEADER-FILES (Somente os arquivos necessários nesse arquivo)
******************************************************************************/
#include "main.h"
#include "ssd1306.h"
#include "hardware/adc.h"
#include <stdio.h>
#include "pico/stdlib.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include "hardware/gpio.h"
/*****************************************************************************/
/******************************************************************************
* Definicoes
******************************************************************************/
/*****************************************************************************/
// Buffer de tela global
uint8_t display_buffer[128 * SSD1306_HEIGHT / 8] = {0};
const uint8_t pinos[] = { LD_1, LD_2, LD_3, LD_4, LD_5, LD_6, LD_7 };
const uint8_t pinos_chaves[] = { CHAVE_1, CHAVE_2, CHAVE_3, CHAVE_4 };
uint16_t timer_execucao[NUMBER_OF_TASKS];
/*Ponteiro para funcoes das tarefas*/
void (*p_tarefas[NUMBER_OF_TASKS])(void);
/*Backup periodo de tempo de tarefas*/
uint16_t tempo_backup[NUMBER_OF_TASKS];
/*Periodo de tempo de tarefas */
uint16_t tempo_tarefa[NUMBER_OF_TASKS];
/*Sinaliza interrupcao tempo*/
uint8_t sinaliza_int_timer;
/* Indica tarefa em execucao */
volatile char tarefa_em_execucao;
/******************************************************************************
* Prototipos das funções
******************************************************************************/
void system_init(void);
void alarm_irq(void);
void init_timer_irq(void);
void button_callback(uint gpio);
void inicializa_tarefas(void);
void escalonador(void);
void task_lamp_bateria(void);
void task_lamp_temperatura(void);
void task_lamp_oleo(void);
void task_lamp_freio(void);
/*****************************************************************************/
/******************************************************************************
* Funcao: void inicializa_tarefas(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Inicializa o ponteiro de função e as temporizações de cada umas
das tarefas.
*****************************************************************************/
void inicializa_tarefas(void)
{
p_tarefas[0] = task_lamp_temperatura;
p_tarefas[1] = task_lamp_bateria;
p_tarefas[2] = task_lamp_oleo;
p_tarefas[3] = task_lamp_freio;
/*init temporization values of each task.
These values do no change during execution*/
tempo_backup[0] = TIMER_1000_MS;
tempo_backup[1] = TIMER_500_MS;
tempo_backup[2] = TIMER_1500_MS;
tempo_backup[3] = TIMER_750_MS;
/*init recent temporization values of each task.
They´re used to decide which task must be executed*/
tempo_tarefa[0] = TIMER_1000_MS;
tempo_tarefa[1] = TIMER_500_MS;
tempo_tarefa[2] = TIMER_1500_MS;
tempo_tarefa[3] = TIMER_750_MS;
//It indicates that there´s no task executing
tarefa_em_execucao = NO;
}
/******************************************************************************
* Funcao: void escalonador(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Executa as tarefas do sistema.
*****************************************************************************/
void escalonador(void)
{
uint8_t cont;
for (cont=0; cont<NUMBER_OF_TASKS; cont++)
{
//Check if it´s time to execute a task
if ((p_tarefas[cont] != 0) && (tempo_tarefa[cont] == 0))
{
tarefa_em_execucao = YES;
(*p_tarefas[cont])();
tarefa_em_execucao = NO;
tempo_tarefa[cont] = tempo_backup[cont]; //reagendamento da tarefa
}
}
}
void trocar_valores(uint16_t *a, uint16_t *b)
{
printf("Antes da troca: *a = %d, *b = %d\n", *a, *b);
int temp = *a;
*a = *b;
*b = temp;
printf("Após a troca: *a = %d, *b = %d\n", *a, *b);
}
/******************************************************************************
* Funcao: int main(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Funcao principal.
*****************************************************************************/
int main(void)
{
stdio_init_all();
system_init();
inicializa_tarefas();
sleep_ms(5000);
// Limpa o buffer do display
ssd1306_clear_buffer(display_buffer);
ssd1306_send_data(display_buffer, 128 * SSD1306_HEIGHT / 8);
sleep_ms(2000);
// Escreve texto no buffer
ssd1306_write_text(display_buffer, 32, 0, "FATEC ");
ssd1306_write_text(display_buffer, 10, 8, "SANTO ANDRE");
ssd1306_write_text(display_buffer, 0, 24, "TAPM - Aula 06");
ssd1306_send_data(display_buffer, 128 * SSD1306_HEIGHT / 8);
while (1)
{
//Verification: check if there´s a task to be executed
if ((sinaliza_int_timer == YES) && (NUMBER_OF_TASKS != 0))
{
sinaliza_int_timer = NO;
escalonador();
}
sleep_ms(10);
}
{
printf("=== EXERCÍCIO 2: TROCA DE VALORES ===\n");
uint16_t x = 10, y = 20;
printf("Valores originais na main: x = %d, y = %d\n", x, y);
printf("Endereços: &x = %p, &y = %p\n", &x, &y);
trocar_valores(&x, &y);
printf("Valores na main após troca: x = %d, y = %d\n", x, y);
printf("\n");
}
}
void system_init(void)
{
//Configura todos os pinos como saida
for (uint8_t cont = 0; cont < 7; cont++)
{
gpio_init(pinos[cont]);
gpio_set_dir(pinos[cont], GPIO_OUT);
}
gpio_init(CONFIG_74LS245);
gpio_set_dir(CONFIG_74LS245, GPIO_OUT);
gpio_put(CONFIG_74LS245, 0);
for (uint8_t cont = 0; cont < 4; cont++)
{
gpio_init(pinos_chaves[cont]);
gpio_set_dir(pinos_chaves[cont], GPIO_IN);
}
adc_init();
adc_gpio_init(GPIO_SENSOR_COMB);
// Select ADC input and read COMB voltage
adc_select_input(ADC_INPUT_COMB);
/* Inicializa display */
SSD1306_init();
init_timer_irq();
}
/******************************************************************************
Funcao: void alarm_irq(void)
Entrada: Nenhuma (void)
Saída: Nenhuma (void)
Descrição: Função tratamento interrupcao do TIMER_IRQ_0
*****************************************************************************/
void alarm_irq(void)
{
// Clear the alarm irq
hw_clear_bits(&timer_hw->intr, 1u << ALARM_NUM);
sinaliza_int_timer = YES;
for (uint8_t cont=0; cont<NUMBER_OF_TASKS; cont++)
{
if (tempo_tarefa[cont] > 0) tempo_tarefa[cont]--;
}
uint64_t target = timer_hw->timerawl + DELAY;
// Write the lower 32 bits of the target time to the alarm register, arming it.
timer_hw->alarm[ALARM_NUM] = (uint32_t) target;
}
/******************************************************************************
Funcao: void init_timer_irq(void)
Entrada: Nenhuma (void)
Saída: Nenhuma (void)
Descrição: Função para inicialização do TIMER_IRQ_0 (100ms)
*****************************************************************************/
void init_timer_irq(void)
{
// Enable the interrupt for the alarm (we're using Alarm 0)
hw_set_bits(&timer_hw->inte, 1u << ALARM_NUM) ;
// Associate an interrupt handler with the ALARM_IRQ
irq_set_exclusive_handler(ALARM_IRQ, alarm_irq) ;
// Enable the alarm interrupt
irq_set_enabled(ALARM_IRQ, true) ;
uint64_t target = timer_hw->timerawl + DELAY;
// Write the lower 32 bits of the target time to the alarm register, arming it.
timer_hw->alarm[ALARM_NUM] = (uint32_t) target;
}
/******************************************************************************
* Funcao: void task_lamp_temperatura(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Controla o funcionamento da lampada de temperatura
*****************************************************************************/
void task_lamp_temperatura(void)
{
static uint8_t estado_led_task_um = 0;
uint16_t adc_reading = 0;
estado_led_task_um = ~estado_led_task_um;
gpio_put(LD_1,estado_led_task_um);
//adc_read(); // throw away first reading after changing input
//adc_reading = adc_read();
//printf("\n Valor ADC = %d", adc_reading);
}
/******************************************************************************
* Funcao: void task_lamp_bateria(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Controla o funcionamento da lampada de bateria
*****************************************************************************/
void task_lamp_bateria(void)
{
static uint8_t estado_led_task_dois = 0;
estado_led_task_dois = ~estado_led_task_dois;
gpio_put(LD_2,estado_led_task_dois);
}
/******************************************************************************
* Funcao: void task_lamp_oleo(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Controla o funcionamento da lampada de oleo
*****************************************************************************/
void task_lamp_oleo(void)
{
static uint8_t estado_led_task_tres = 0;
estado_led_task_tres = ~estado_led_task_tres;
gpio_put(LD_3,estado_led_task_tres);
}
/******************************************************************************
* Funcao: void task_lamp_freio(void)
* Entrada: Nenhuma (void)
* Saida: Nenhuma (void)
* Descricao: Controla o funcionamento da lampada de freio
*****************************************************************************/
void task_lamp_freio(void)
{
static uint8_t estado_led_task_quatro = 0;
estado_led_task_quatro = ~estado_led_task_quatro;
gpio_put(LD_4,estado_led_task_quatro);
}
B1
OLED
RESET
GPIO14
GP14
GPIO13
GP13
GPIO12
GP12
GPIO11
GP11
GPIO10
GP10
GPIO9
GP9
GPIO8
GP8
3.3V
4.3V
COM
GND
3.3V
GND
GP2
GP3
GP4
ADC0
Gerador PWM
Pot1
Gerador PWM
CH3
Chave
CH4
CH1
BTN3
BTN2
GP2
GP3
GP4
GP5
GP6
GP7