Librería Teclado 4x4
Dependents: teclado teclado discovery_17_keypad_buzzer kasim_rfid_kart_okuyucu
Revision 0:0012aa4908fa, committed 2015-06-07
- Comitter:
- jyrodriguezg
- Date:
- Sun Jun 07 04:34:47 2015 +0000
- Commit message:
- Librer?a keypad
Changed in this revision
diff -r 000000000000 -r 0012aa4908fa FPointer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FPointer.h Sun Jun 07 04:34:47 2015 +0000 @@ -0,0 +1,163 @@ +/* + Copyright (c) 2011 Andy Kirkham + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef AJK_FPOINTER_H +#define AJK_FPOINTER_H + +namespace AjK { + +class FPointerDummy; + +/** FPointer - Adds callbacks that take and return a 32bit uint32_t data type. + * + * The Mbed library supplies a callback using the FunctionPointer object as + * defined in FunctionPointer.h However, this callback system does not allow + * the caller to pass a value to the callback. Likewise, the callback itself + * cannot return a value. + * + * FPointer operates in the same way but allows the callback function to be + * passed one arg, a uint32_t value. Additionally, the callback can return + * a single uint32_t value. The reason for using uint32_t is that the Mbed + * and the microcontroller (LPC1768) have a natural data size of 32bits and + * this means we can use the uint32_t as a pointer. See example1.h for more + * information. This example passes an "int" by passing a pointer to that + * int as a 32bit value. Using this technique you can pass any value you like. + * All you have to do is pass a pointer to your value cast to (uint32_t). Your + * callback can the deference it to get the original value. + * + * example2.h shows how to do the same thing but demostrates how to specify + * the callback into a class object/method. + * + * Finally, example3.h shows how to pass multiple values. In this example we + * define a data structure and in the callback we pass a pointer to that + * data structure thus allowing the callback to again get the values. + * + * Note, when passing pointers to variables to the callback, if the callback + * function/method changes that variable's value then it will also change the + * value the caller sees. If C pointers are new to you, you are strongly + * advised to read up on the subject. It's pointers that often get beginners + * into trouble when mis-used. + * + * @see example1.h + * @see example2.h + * @see example3.h + * @see http://mbed.org/handbook/C-Data-Types + * @see http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h + */ +class FPointer { + +protected: + + //! C callback function pointer. + uint32_t (*c_callback)(uint32_t); + + //! C++ callback object/method pointer (the object part). + FPointerDummy *obj_callback; + + //! C++ callback object/method pointer (the method part). + uint32_t (FPointerDummy::*method_callback)(uint32_t); + +public: + + /** Constructor + */ + FPointer() { + c_callback = NULL; + obj_callback = NULL; + method_callback = NULL; + } + + /** attach - Overloaded attachment function. + * + * Attach a C type function pointer as the callback. + * + * Note, the callback function prototype must be:- + * @code + * uint32_t myCallbackFunction(uint32_t); + * @endcode + * @param A C function pointer to call. + */ + void attach(uint32_t (*function)(uint32_t) = 0) { c_callback = function; } + + /** attach - Overloaded attachment function. + * + * Attach a C++ type object/method pointer as the callback. + * + * Note, the callback method prototype must be:- + * @code + * public: + * uint32_t myCallbackFunction(uint32_t); + * @endcode + * @param A C++ object pointer. + * @param A C++ method within the object to call. + */ + template<class T> + void attach(T* item, uint32_t (T::*method)(uint32_t)) { + obj_callback = (FPointerDummy *)item; + method_callback = (uint32_t (FPointerDummy::*)(uint32_t))method; + } + + /** call - Overloaded callback initiator. + * + * call the callback function. + * + * @param uint32_t The value to pass to the callback. + * @return uint32_t The value the callback returns. + */ + uint32_t call(uint32_t arg) { + if (c_callback != NULL) { + return (*c_callback)(arg); + } + else { + if (obj_callback != NULL && method_callback != NULL) { + return (obj_callback->*method_callback)(arg); + } + } + return (uint32_t)NULL; + } + + /** call - Overloaded callback initiator. + * + * Call the callback function without passing an argument. + * The callback itself is passed NULL. Note, the callback + * prototype should still be <b>uint32_t callback(uint32_t)</b>. + * + * @return uint32_t The value the callback returns. + */ + uint32_t call(void) { + if (c_callback != NULL) { + return (*c_callback)((uint32_t)NULL); + } + else { + if (obj_callback != NULL && method_callback != NULL) { + return (obj_callback->*method_callback)((uint32_t)NULL); + } + } + return (uint32_t)NULL; + } +}; + +}; // namespace AjK ends + +using namespace AjK; + +#endif
diff -r 000000000000 -r 0012aa4908fa keypad.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/keypad.cpp Sun Jun 07 04:34:47 2015 +0000 @@ -0,0 +1,115 @@ +#include "keypad.h" + +Keypad::Keypad(PinName row3, PinName row2, PinName row1, PinName row0, + PinName col3, PinName col2, PinName col1, PinName col0, + int debounce_ms): + _row0(row0), _row1(row1), _row2(row2), _row3(row3), + _cols(col0, col1, col2, col3) +{ + _debounce = debounce_ms; + _rows[0] = &_row0; + _rows[1] = &_row1; + _rows[2] = &_row2; + _rows[3] = &_row3; + for (int r = 0; r < row_count; r++) + _rows[r]->mode(PullUp); + // _cols.mode(OpenDrain); + _cols.output(); +} + +void Keypad::_setupFallTrigger(void) +{ + for (int r = 0; r < row_count; r++) + _rows[r]->fall(this, &Keypad::_callback); +} + +void Keypad::Start(void) +{ + /* make the columns zero so they can pull rows down */ + _cols = 0x00; +} + +void Keypad::Stop(void) +{ + /* make the columns one so they cannot pull any rows down anymore */ + _cols = ~0x00; +} + +void Keypad::CallAfterInput(uint32_t (*fptr)(uint32_t index)) +{ + _input.attach(fptr); + _setupFallTrigger(); +} + +int Keypad::DebouncedScan() +{ + /* debounce */ + wait_ms(_debounce); + + return Scan(); +} + +int Keypad::Scan() +{ + /* lookup row */ + int r = -1; + for (r = 0; r < row_count; r++) { + if (*_rows[r] == 0) + break; + } + + /* if we didn't find a valid row, return */ + if (!(0 <= r && r < row_count)) + return -1; + + /* scan columns to find out which one pulls down the row */ + int c = -1; + for (c = 0; c < col_count; c++) { + _cols = ~(1 << c); + if (*_rows[r] == 0) + break; + } + + /* re-energize all columns */ + Start(); + + /* if we didn't find a valid column, return */ + if (!(0 <= c && c < col_count)) + return -1; + + return r * col_count + c; +} + +int Keypad::DebouncedScanMultiple() +{ + /* debounce */ + wait_ms(_debounce); + + return ScanMultiple(); +} + +int Keypad::ScanMultiple() +{ + int res = 0; + for (int c = 0; c < col_count; c++) { + _cols = ~(1 << c); + for (int r = 0; r < row_count; r++) { + if (*_rows[r] == 0) { + res |= 1 << (r * col_count + c); + } + } + } + + return res; +} + +void Keypad::_callback() +{ + /* lookup */ + int position = DebouncedScan(); + + /* call back a valid position */ + if (position >= 0) + _input.call(position); +} +
diff -r 000000000000 -r 0012aa4908fa keypad.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/keypad.h Sun Jun 07 04:34:47 2015 +0000 @@ -0,0 +1,127 @@ +/* mbed Keypad library, using user-defined interrupt callback + * Copyright (c) 2012 Yoong Hor Meng + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE + */ + +#ifndef KEYPAD_H +#define KEYPAD_H + +#include "mbed.h" +#include "FPointer.h" + +/** + * An interrupt-based interface to 4x4 keypad. + * + * On each key pressed on a keypad, the index of the key is passed to a + * user-defined function. User is free to define what to be done with the + * input. + * + * This library makes use of + * @see http://mbed.org/cookbook/FPointer by Andy Kirkham + * + * Example: + * @code + * #include "mbed.h" + * #include "keypad.h" + * + * // Define your own keypad values + * char Keytable[] = { '1', '2', '3', 'A', + * '4', '5', '6', 'B', + * '7', '8', '9', 'C', + * '*', '0', '#', 'D' + * }; + * + * uint32_t cbAfterInput(uint32_t index) { + * printf("Index:%d => Key:%c\n", key, Keytable[index]); + * return 0; + * } + * + * int main() { + * Keypad keypad(p25, p26, p27, p28, p21, p22, p23, p24); + * keypad.CallAfterInput(&cbAfterInput); + * keypad.Start(); + * + * while (1) { + * wait_ms(100); + * } + * } + * @endcode + */ +class Keypad +{ +public: + /** Create a Keypad interface + * + * @param row<3..0> Row data lines + * @param col<3..0> Column data lines + * @param debounce_ms Debounce in ms (Default to 20ms) + */ + Keypad(PinName row3, PinName row2, PinName row1, PinName row0, + PinName col3, PinName col2, PinName col1, PinName col0, + int debounce_ms = 20); + + /** Start the keypad interrupt routines + */ + void Start(void); + + /** Stop the keypad interrupt routines + */ + void Stop(void); + + /** Scan the keyboard for a debounced pressed key + */ + int DebouncedScan(void); + + /** Scan the keyboard for a pressed key + */ + int Scan(void); + + /** Scan the keyboard for multiple debounced pressed keys + */ + int DebouncedScanMultiple(void); + + /** Scan the keyboard for multiple pressed keys + */ + int ScanMultiple(void); + + /** User-defined function that to be called when a key is pressed + * @param fptr A function pointer takes a uint32_t and + * returns uint32_t + */ + void CallAfterInput(uint32_t (*fptr)(uint32_t)); + +protected: + static const int row_count = 4; + static const int col_count = 4; + + InterruptIn _row0; + InterruptIn _row1; + InterruptIn _row2; + InterruptIn _row3; + InterruptIn *_rows[row_count]; + BusInOut _cols; // BusOut doesn't support mode() yet; need open drain to prevent short circuits... + int _debounce; + FPointer _input; // Called after each input + + void _callback(); + void _setupFallTrigger(void); +}; + +#endif // KEYPAD_H