A generic push button handler as practical demonstration of function pointers -- see Hackaday article Directly Executing Chunks of Memory: Function Pointers In C.
The example consists of two parts:
- the button handler itself
buttons.hheader filebuttons.csource file
- an example implementation for AVR ATmega328P
main.cmain file using the button handlerMakefileto easily build and flash
The push buttons are set up as a button_t struct defining the GPIO port and pin, and a handler function for each press and release event. The handlers are optional and can be NULL, in which case nothing will happen for that specific button at the event.
void some_press_handler(void)
{
...
}
button_t buttons[] = {
{
.port = &INPUT_PORT_REGISTER,
.pin = PIN_NUMBER,
.press = some_press_handler,
.release = NULL,
},
...
};
The buttons are initialized with the buttons_init() function, passing the array with the button setup data along with the amount of entries in that array
buttons_init(buttons, sizeof buttons / sizeof buttons[0]);
To keep things easy, the button states are meant to be polled periodically
while (1) {
buttons_poll();
...
}
That's it.
Whenever a push button is pressed or released, the defined handler functions will be called.
The example implementation is meant for an AVR ATmega328P running at 8MHz clock speed, using avr-gcc for compiling and avrdude for flashing with the USBasp programmer. Check the Makefile if you want to use a different AVR microcontroller or have a different programmer.
If you want to use the handler on a different platform (PIC, MSP430, ...), you should be able to use the button handler itself as-is (well, that's kinda the whole point of it), but you will have to adjust the main.c file accordingly, and handle your own Makefile somehow (or use an IDE).
- GPIO port name in
buttonsneeds to be changed to you your target controller's register names - GPIO pin number in
buttonsaccordingly - GPIO setup in the very beginning of
main()that defines the data direction and pull-up resistors.