Estoy tratando de entender el temporizador de stm32f0 sin usar la biblioteca stm, en particular estoy usando el tablero de descubrimiento stmf051 .
Lo que estoy tratando de hacer es un programa simple que detecta cuando se presiona brevemente o se presiona un botón.
Por lo tanto, el programa sería simplemente iniciar un contador cuando el microcontrolador detecte un botón y si ARR (valor de recarga automática) alcance el límite, encienda el límite. verde en la pizarra, de lo contrario, encienda azul en la pizarra.
Lo que surgió hasta ahora al ver el ejemplo en la hoja de datos y en este sitio web, es este fragmento de código, funciona pero hay un problema de debouncing (He actualizado el código y ahora el problema de debouncing está resuelto), y no estoy satisfecho con él.
Así que, por favor, ¿puedes ayudarme a mejorar mi código, mostrarme una mejor manera de hacerlo o simplemente señalarme la dirección correcta?
Gracias por tu tiempo, y lo siento por mi mal inglés.
#include "stm32f0xx.h"
short buttonPressed(void);
void delay(int a);
int main(void)
{
/* Enable the GPIO A,C,B */
RCC->AHBENR |=
(RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN);
// Enable Timer TIM2
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->PSC = 23999; // Set prescaler to 24 000 (PSC + 1)
TIM2->ARR = 800; // Auto reload value 800, for activate the green
// led you need to push the botton for at least 800 ms
TIM2->CR1 = TIM_CR1_CEN; // Enable timer
/* Configure PC8 and PC9 in output mode (led green and blue) */
GPIOC->MODER |= (GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0);
/* Button Pin PA0 in alternate function (user button in the board)*/
GPIOC->OTYPER &= ~(GPIO_OTYPER_OT_8 | ~GPIO_OTYPER_OT_9);
//Ensure maximum speed setting (even though it is unnecessary)
GPIOC->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9);
//Ensure all pull up pull down resistors are disabled
GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9);
while (1)
{
short answer = buttonPressed();
if (answer == 1)
{
GPIOC->BSRR = (1 << 9); // Blink the led in PC9 if the button is
delay(300000); // long pressed
GPIOC->BRR = (1 << 9); //
}
if (answer == 2)
{
GPIOC->BSRR = (1 << 8); // Blink the led in PC9 if the button is
delay(300000); // short pressed
GPIOC->BRR = (1 << 8); //
}
}
return 0;
}
short buttonPressed()
{
short return_value = 0;
if (GPIOA->IDR & GPIO_IDR_0) // If the button is pressed
{
delay(80000);
if (GPIOA->IDR | GPIO_IDR_0)
{
TIM2->EGR |= TIM_EGR_UG; // For an update generation with UG=1
TIM2->SR &= ~TIM_SR_UIF; // Clear TIM_ENV update interrupt so the ARR start from 0
while (GPIOA->IDR & GPIO_IDR_0)
{
} // Don't do anything until the button is released
if (TIM2->SR & TIM_SR_UIF) // If ARR reached 800 it means that it the button was long pressed
{
return_value = 1;
TIM2->SR &= ~TIM_SR_UIF; // Clear the ENV register
}
else // otherwise the button was short pressed
{
return_value = 2;
TIM2->SR &= ~TIM_SR_UIF; // Clear the ENV register
}
}
}
return return_value;
}
void delay(int a)
{
volatile int i, j;
for (i = 0; i < a; i++)
{
j++;
}
return;
}