I've written a small program that uses a button on an STM32 Discovery board to act as a counter in either Binary/Decimal/Hexadecimal mode (screen cycles through the 3 options and once pressed, counts up to 16 for each press before resetting to cycling through options).
I'm encountering one small "bug" (read, not really) that has me a little confused. If I count up in Decimal/Hexadecimal, it returns to cycling through the options immediately but if I have counted up in Binary it takes ~1sec or so before doing so (a noticeable delay).
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;
}
I really have no idea why it is doing this and have played around with it now but still unable to figure it out. It's fine as is but I would like to know why it is doing this.