/* Tarjeta Nucleo L031K6
= Practica 11 - 1 Conmutación de LEDs con potenciómetro =
Primer bloque LEDs, umbral 1.5V:
- D3 (PB0), D6 (PB1), LD3 (PB3)
Segundo bloque LEDs, umbral 3.0V:
- D12 (PB4), D11 (PB5), D5 (PB6), D4 (PB7)
Pulsador PA0
*/
// Umbrales de tensión
const float UMB_TENS_1 = 1.5;
const float UMB_TENS_2 = 3.0;
// Todos apagados (reset) PB0,1,3,4,5,6,7
const uint32_t ALL_RESET = 0b00000000111110110000000000000000;
// Encendidos: D3 (PB0), D6 (PB1), LD3 (PB3)
// Apagados (reset): D12 (PB4), D11 (PB5), D5 (PB6), D4 (PB7)
const uint32_t ON1_RESET2 = 0b00000000111100000000000000001011;
// Todos encendidos: PB0,1,3,4,5,6,7
const uint32_t ALL_ON = 0b00000000000000000000000011111011;
//----- Función que genera un retardo en milisegundos
void delay_ms(uint32_t milliseconds) {
uint32_t cycles = milliseconds * (SystemCoreClock / 2000);
for (uint32_t i = 0; i < cycles; i++) {
__NOP();
}
}
//----- Configuración de conversor A/D
void setup_ADC(void){
// Habilita reloj del ADC
RCC->APB2ENR |= 0b1000000000;
// PA0 como entrada analógica (modo por defecto)
// GPIOA->MODER |= 0b00000000000000000000000000000011;
// Selecciona canal 0 para conversión A/D
ADC1->CHSELR |= 0b1;
// Habilita el ADC
ADC1->CR |= 0b1;
}
void setup_LED() {
// Habilita reloj del puerto GPIOB
RCC->IOPENR |= 0b10;
// Configura pines PB0,1,3,4,5,6,7 como salida digital (01)
GPIOB->MODER &= 0b11111111111111110101010101110101;
}
//----- Efectúa una conversión A/D
// TODO: revisar a PA0 en vez de PA1
uint16_t lectura_ADC(void) {
// Inicia conversión A/D
ADC1->CR |= 0b1 << 2;
// Espera a completar conversión A/D
while ((ADC1->ISR & 0b1<<1) == 0){};
// Lee el valor convertido
return ADC1->DR;
}
int main(void) {
setup_ADC();
setup_LED();
uint32_t state;
while(1) {
// Tensión en V (parece que PA0 está con resolución de 12 bit=> max 4095)
uint16_t valor_ADC = lectura_ADC();
float tension = valor_ADC * (3.3 / 4095.0);
// Compara la tensión obtenida con el umbral de 3V
if (tension < UMB_TENS_1) {
state = ALL_RESET;
} else if ((tension >= UMB_TENS_1) && (tension < UMB_TENS_2)) {
state = ON1_RESET2;
} else {
state = ALL_ON;
};
GPIOB->BSRR |= state;
delay_ms(20);
}
}