|
发表于 2013-1-4 08:23:26
|
显示全部楼层
本帖最后由 hefq 于 2013-1-4 08:50 编辑
- #ifndef _MATRIX2_H_
- #define _MATRIX2_H_
- #include <stdint.h>
- /* see drawing in matrix2.c */
- /* bits set in return of matrix2_scan for the indicated buttons */
- #define MATRIX2_A 0x2000
- #define MATRIX2_B 0x4000
- #define MATRIX2_C 0x8000
- #define MATRIX2_D 0x0100
- #define MATRIX2_E 0x0400
- #define MATRIX2_F 0x0800
- #define MATRIX2_G 0x0010
- #define MATRIX2_H 0x0020
- #define MATRIX2_I 0x0080
- #define MATRIX2_J 0x0001
- #define MATRIX2_K 0x0002
- #define MATRIX2_L 0x0004
- uint16_t
- extern matrix2_scan(void);
- #endif
复制代码- #include "matrix2.h"
- #include <avr/io.h>
- #define KBD_PORT PORTC
- #define KBD_PIN PINC
- #define KBD_DDR DDRC
- #define KBD_P0 1
- #define KBD_MASK (_BV(KBD_P0)|_BV(KBD_P0+1)|_BV(KBD_P0+2)|_BV(KBD_P0+3))
- /* This function is scanning a key matrix connected to four IO ports
- * in the following way:
- *
- * +------------------------------------+
- * | +-------------------------+ |
- * | | +--------------+ | |
- * | | | +---+ | | |
- * | | | | | |a |b |c
- * (P0)----|-|-|-+---|--------X--------X--------X
- * | | | |d | |e |f
- * (P1)----|-|-+-----X--------|--------X--------X
- * | | |g |h | |i
- * (P2)----|-+-------X--------X--------|--------X
- * | |j |k |l
- * (P3)----+---------X--------X--------X
- *
- * The keys are marked by X, they consist of a push
- * button and a diode,e.g.:
- *
- * (b)
- * | _|_
- * (a)---X--- is equivalent to (a)---o o--|<|--(b)
- * |
- *
- * The port bits have to be consecutive, starting at
- * the bit number KBD_P0, the port has to be adjusted
- * in the defines above, e.g. for port C1..C4 define
- * KBD_PIN to be PINC, KBD_DDR to be DDRC, KBD_PORT to
- * be KBD_PORTC and KBD_P0 to be 1.
- *
- * The return value of this function will be a 16bit word
- * with 12 bits corresponding to the indicated key
- * locations, 4 bits are constantly 0:
- *
- *
- */
- uint16_t
- matrix2_scan(void){
- uint16_t ret=0;
- uint8_t bit=_BV(KBD_P0);
- uint8_t c;
- do {
- ret <<= 4;
- KBD_PORT = ((KBD_PORT | KBD_MASK ) & (~bit));
- KBD_DDR = ((KBD_DDR & (~KBD_MASK)) | bit );
- /* the internal pullups are too weak for my
- slow diodes, therefore I wait for an awfully
- long time! Check on the 'scope' for yourself. */
- c=0;
- while(--c)
- __asm__("nop;\n");
- c = KBD_PIN; /* get input bits, 0 means key pressed */
- c |= bit; /* mask out current column */
- c >>= KBD_P0; /* shift bits to 0..3 */
- c = ~c & 0x0f; /* pressed buttons are 1 */
- ret |= c;
- if( bit == _BV(KBD_P0+3) )
- break;
- bit <<= 1;
- } while(1);
- return ret;
- }
复制代码- #include <avr/io.h>
- #include <avr/pgmspace.h>
- #include "matrixtest.c"
- /* put one single byte out onto the serial port */
- static void
- putserial(unsigned char c){
- /* wait for Uart DataRegister to become Empty (UDRE) */
- while(!(UCSR0A & _BV(UDRE0)));
- UDR0 = c;
- }
- /* convert 0..9,10..15 to '0'..'9','A'..'F' */
- static unsigned char
- nibble_to_char(unsigned char c){
- c &= 0x0f;
- if(c>=10)
- c+= ('A'-'0'-10);
- return c+'0';
- }
- static void
- putnibble(unsigned char c){
- putserial(nibble_to_char(c));
- }
- static void
- puthexword(uint16_t v){
- putnibble((v>>12)&0x0f);
- putnibble((v>> 8)&0x0f);
- putnibble((v>> 4)&0x0f);
- putnibble( v &0x0f);
- }
- /* this wastes memory, but the M328 is completely empty anyway... */
- struct keynames {
- uint16_t v;
- char name;
- } keynames[]={
- { MATRIX2_A, 'A' },
- { MATRIX2_B, 'B' },
- { MATRIX2_C, 'C' },
- { MATRIX2_D, 'D' },
- { MATRIX2_E, 'E' },
- { MATRIX2_F, 'F' },
- { MATRIX2_G, 'G' },
- { MATRIX2_H, 'H' },
- { MATRIX2_I, 'I' },
- { MATRIX2_J, 'J' },
- { MATRIX2_K, 'K' },
- { MATRIX2_L, 'L' }
- };
- int
- main(void){
- uint16_t ctr;
- uint16_t oldkeys,newkeys;
- int i; UBRR0 = 103; /* 9k6 bps @ 16 MHz */
- UCSR0B = _BV(RXEN0)|_BV(TXEN0);
- UCSR0C = _BV(UCSZ01)|_BV(UCSZ00);
- for(;;){
- newkeys = matrix2_scan();
- if(newkeys != oldkeys){
- ctr=255;
- }
- oldkeys = newkeys;
- if(ctr)
- ctr--;
- if(ctr==1){
- putserial('\r');
- putserial('\n');
- puthexword(newkeys);
- putserial(' ');
- for(i=0;i<12;i++){
- if(newkeys & keynames[i].v)
- putserial(keynames[i].name);
- else
- putserial('-');
- putserial(' ');
- }
- }
- }
- }
复制代码- This is a small example to show how to decode a
- 12-button matrix using only 4 I/O pins of a microcontroller.
- One key consists of a switch and a diode.
- All combination of simultaneously pressed keys can be decoded.
- The example compiles for an Arduino duemilanove, as is it's using
- the signals marked as Analog 1..Analog 4 (PortC1..4).
- Simple test shows the following output on ttyUSB0@9600 bps:
- +------ output of the matrix_scan function
- |
- | +-- "Human readable" key numbers
- | |
- V V
- 2000 A - - - - - - - - - - -
- 0000 - - - - - - - - - - - -
- 4000 - B - - - - - - - - - -
- 0000 - - - - - - - - - - - -
- 8000 - - C - - - - - - - - -
- 0000 - - - - - - - - - - - -
- 0100 - - - D - - - - - - - -
- 0000 - - - - - - - - - - - -
- 0400 - - - - E - - - - - - -
- 0000 - - - - - - - - - - - -
- 0800 - - - - - F - - - - - -
- 0000 - - - - - - - - - - - -
- 0010 - - - - - - G - - - - -
- 0000 - - - - - - - - - - - -
- 0020 - - - - - - - H - - - -
- 0000 - - - - - - - - - - - -
- 0080 - - - - - - - - I - - -
- 0000 - - - - - - - - - - - -
- 0001 - - - - - - - - - J - -
- 0000 - - - - - - - - - - - -
- 0002 - - - - - - - - - - K -
- 0000 - - - - - - - - - - - -
- 0004 - - - - - - - - - - - L
- 0000 - - - - - - - - - - - -
- 0000 - - - - - - - - - - - -
- 0010 - - - - - - G - - - - - <-- two buttons
- 0012 - - - - - - G - - - K - <-- simultaneously
复制代码 帮你转载过来 |
|