Atraso ligeiro após retornar da interrupção
Eu escrevi um pequeno programa que usa um botão em uma placa STM32 Discovery para atuar como um contador no modo Binário / Decimal / Hexadecimal (a tela percorre as 3 opções e, uma vez pressionada, conta até 16 para cada pressão antes de redefinir para alternando entre as opções).
Estou encontrando um pequeno "bug" (lido, na verdade) que me deixa um pouco confuso. Se eu contar em Decimal / Hexadecimal, ele voltará a percorrer as opções imediatamente, mas se eu tiver contado em Binário, levará cerca de 1 segundo antes de fazê-lo (um atraso perceptível).
int main(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
lcd_init();
button_init();
while (1)
{
while (!counting) {
standard_output();
}
}
}
void standard_output(void) {
state = 0;
lcd_command(0x01);
delay_microsec(2000);
lcd_putstring("Binary");
for (i=0; i<40; i++) delay_microsec(50000); // keep display for 2 secs
if (counting) return; // if we have pressed the button, want to exit this loop
state = 1;
lcd_command(0x01);
delay_microsec(2000);
lcd_putstring("Decimal");
for (i=0; i<40; i++) delay_microsec(50000); // keep display for 2 secs
if (counting) return; // if we have pressed the button, want to exit this loop
state = 2;
lcd_command(0x01);
delay_microsec(2000);
lcd_putstring("Hexadecimal");
for (i=0; i<40; i++) delay_microsec(50000); // keep display for 2 secs
if (counting) return; // if we have pressed the button, want to exit this loop
}
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
if (!stillBouncing) { // a button press is only registered if stillBouncing == 0
if (!counting) { // if we weren't already counting, a valid button press means we are now
counting = 1;
count = 0; // starting count from 0
}
else {
count++;
}
if (count < 16) {
lcd_command(0x01);
delay_microsec(2000);
format_int(count);
}
else {
counting = 0; // we are no longer counting if count >= 16
}
}
stillBouncing = 10; // every time a button press is registered, we set this to 10
while (stillBouncing > 0) { // and check that it hasn't been pressed for 10 consecutive 1000microsec intervals
if (!delay_millisec_or_user_pushed(1000)) {
stillBouncing--;
}
}
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void format_int(unsigned int n) {
if (state == 0) { // if we selected binary
for (i=0;i<4;++i) {
num[i] = (n >> i) & 1; // generate array of bit values for the 4 least significant bits
}
i = 4;
while (i>0) {
i--;
lcd_putint(num[i]); // put ints from array to lcd in reverse order to display correctly
}
}
else if (state == 1) { // if we selected decimal
lcd_putint(n); // lcd_putint is enough for decimal
}
else { // if we selected hex
snprintf(hex, 4, "%x", n); // format string such that integer is represented as hex in string
lcd_putstring(hex); // put string to lcd
}
}
int delay_millisec_or_user_pushed(unsigned int n)
{
delay_microsec(n);
if (!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) {
return 0;
}
return 1;
}
Eu realmente não tenho idéia do por que está fazendo isso e já brinquei com ele agora, mas ainda não consegui descobrir. Está tudo bem, mas gostaria de saberporque está fazendo isso.