#include <Arduino.h>
// Definição dos pinos utilizados pelo DIP Switch como entradas digitais
#define CHAVE_0 0 // Entrada do bit 0 do DIP (PA0)
#define CHAVE_1 1 // Entrada do bit 1 do DIP (PA1)
#define CHAVE_2 3 // Entrada do bit 2 do DIP (PA3)
#define CHAVE_3 4 // Entrada do bit 3 do DIP (PA4)
// Definição dos pinos utilizados para acionamento dos LEDs
#define LED_0 12 // LED correspondente ao bit 0 (PA12 - D2)
#define LED_1 0 // LED correspondente ao bit 1 (PB0 - D3)
#define LED_2 7 // LED correspondente ao bit 2 (PB7 - D4)
#define LED_3 6 // LED correspondente ao bit 3 (PB6 - D5)
#define LED_PAR 1 // LED indicador de paridade (PB1 - D6)
void setup() {
// Ativação do clock dos blocos GPIO utilizados no circuito
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
RCC->IOPENR |= RCC_IOPENR_GPIOBEN;
// Configuração dos pinos conectados ao DIP Switch
// Os pinos são configurados como entrada digital
GPIOA->MODER &= ~(3UL << (CHAVE_0 * 2));
GPIOA->MODER &= ~(3UL << (CHAVE_1 * 2));
GPIOA->MODER &= ~(3UL << (CHAVE_2 * 2));
GPIOA->MODER &= ~(3UL << (CHAVE_3 * 2));
// Ativação dos resistores internos de pull-up
// Mantém os pinos em nível lógico alto quando a chave está aberta
GPIOA->PUPDR &= ~(3UL << (CHAVE_0 * 2));
GPIOA->PUPDR &= ~(3UL << (CHAVE_1 * 2));
GPIOA->PUPDR &= ~(3UL << (CHAVE_2 * 2));
GPIOA->PUPDR &= ~(3UL << (CHAVE_3 * 2));
GPIOA->PUPDR |= (1UL << (CHAVE_0 * 2));
GPIOA->PUPDR |= (1UL << (CHAVE_1 * 2));
GPIOA->PUPDR |= (1UL << (CHAVE_2 * 2));
GPIOA->PUPDR |= (1UL << (CHAVE_3 * 2));
// Configuração do pino do LED conectado ao GPIOA como saída digital
GPIOA->MODER &= ~(3UL << (LED_0 * 2));
GPIOA->MODER |= (1UL << (LED_0 * 2));
// Configuração dos LEDs conectados ao GPIOB como saída digital
GPIOB->MODER &= ~(3UL << (LED_1 * 2));
GPIOB->MODER &= ~(3UL << (LED_2 * 2));
GPIOB->MODER &= ~(3UL << (LED_3 * 2));
GPIOB->MODER &= ~(3UL << (LED_PAR * 2));
GPIOB->MODER |= (1UL << (LED_1 * 2));
GPIOB->MODER |= (1UL << (LED_2 * 2));
GPIOB->MODER |= (1UL << (LED_3 * 2));
GPIOB->MODER |= (1UL << (LED_PAR * 2));
// Inicialização do sistema mantendo todos os LEDs desligados
GPIOA->BSRR = (1UL << (LED_0 + 16));
GPIOB->BSRR = (1UL << (LED_1 + 16)) |
(1UL << (LED_2 + 16)) |
(1UL << (LED_3 + 16)) |
(1UL << (LED_PAR + 16));
}
void loop() {
// Leitura do estado atual das entradas conectadas ao DIP Switch
uint32_t estado = GPIOA->IDR;
// Conversão dos níveis lógicos das entradas em bits individuais
// Como o circuito utiliza pull-up, a lógica é invertida:
// chave acionada = nível baixo = bit ativo
uint8_t b0 = !(estado & (1UL << CHAVE_0));
uint8_t b1 = !(estado & (1UL << CHAVE_1));
uint8_t b2 = !(estado & (1UL << CHAVE_2));
uint8_t b3 = !(estado & (1UL << CHAVE_3));
// Atualização do LED correspondente ao primeiro bit recebido
if (b0) {
GPIOA->BSRR = (1UL << LED_0);
} else {
GPIOA->BSRR = (1UL << (LED_0 + 16));
}
// Atualização do LED correspondente ao segundo bit recebido
if (b1) {
GPIOB->BSRR = (1UL << LED_1);
} else {
GPIOB->BSRR = (1UL << (LED_1 + 16));
}
// Atualização do LED correspondente ao terceiro bit recebido
if (b2) {
GPIOB->BSRR = (1UL << LED_2);
} else {
GPIOB->BSRR = (1UL << (LED_2 + 16));
}
// Atualização do LED correspondente ao quarto bit recebido
if (b3) {
GPIOB->BSRR = (1UL << LED_3);
} else {
GPIOB->BSRR = (1UL << (LED_3 + 16));
}
// Cálculo da paridade utilizando operação XOR entre os quatro bits
// Resultado 0 indica quantidade par de bits em nível alto
// Resultado 1 indica quantidade ímpar de bits em nível alto
uint8_t impar = b0 ^ b1 ^ b2 ^ b3;
// Controle do LED azul indicador de paridade
// LED ligado quando a quantidade de bits ativos for par
if (impar == 0) {
GPIOB->BSRR = (1UL << LED_PAR);
} else {
GPIOB->BSRR = (1UL << (LED_PAR + 16));
}
}