查看: 6398|回复: 14
|
【教学】PIC 连接4x4 Keypad , 显示在 16x2 LCD
[复制链接]
|
|
本帖最后由 pic 于 9-3-2012 11:25 AM 编辑
过去有一些帖子, 示范了怎样用CCS C, 使用 PIC MCU 的ADC, 连接去LCD, USART 等等。。
矩阵键盘 (Keypad ) 倒是还没有说过。。 这里引用CCS C 的 示范程序, EX_LCDKB.C , LCD.C, KBD.C, 做部分修改后, 在proteus 运行示范。
供网友们参考。 有问题可以发问, 但是请不要离题。
电路图如下, LCD 是接去 16F887 的Port D, Keypad 是接去 Port B,相对的按键, 会显示在LCD 上, 按 [On/C] 键会清除 LCD。
矩阵键盘 的Row (行), 需要电位拉高 pull high,可以用4.7k~10K 的电阻。
CCS C 源码:下载
主程序
- // Demo: Keypad 4x4, display on LCD 16x2
- // Modified from CCS C Ex_LCDKB.C
- // Filename: Cari_LCDKB.C
- // Date: 6 Mar 2012
- // by: pic@cArI
- #include <16F887.h>
- #fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP
- #use delay(clock=8000000)
- #include <mylcd.c>
- #include <mykbd.c>
- void main() {
- char k;
- lcd_init();
- lcd_putc("\fReady...\n");
- while (TRUE)
- {
- k=kbd_getc();
- if(k!=0)
- if(k=='N')
- lcd_putc('\f');
- else
- lcd_putc(k);
- }
- }
复制代码 |
|
|
|
|
|
|
|
楼主 |
发表于 6-3-2012 09:00 PM
|
显示全部楼层
myKBD.C
本帖最后由 pic 于 6-3-2012 09:15 PM 编辑
Keypad 的bouncing , 可以设定, 在#define KBD_DEBOUNCE_FACTOR
我修改了 CCS C 原本的 Keypad Scan Driver , KBD.C (4x3)变成 myKBD.C (4x4)
- // Filename: myKBD.C
- #define use_portb_kbd TRUE // 使用 PortB
- #if defined(__PCH__)
- #if defined use_portb_kbd
- #byte kbd = 0xF81 // This puts the entire structure
- #else
- #byte kbd = 0xF83 // This puts the entire structure
- #endif
- #else
- #if defined use_portb_kbd
- #byte kbd = 6 // on to port B (at address 6)
- #else
- #byte kbd = 8 // on to port D (at address 8)
- #endif
- #endif
- #if defined use_portb_kbd
- #define set_tris_kbd(x) set_tris_b(x)
- #else
- #define set_tris_kbd(x) set_tris_d(x)
- #endif
- #define COL0 (1 << 4) // Col0 接去PortB.4
- #define COL1 (1 << 5) // Col1 接去PortB.5
- #define COL2 (1 << 6) // Col2 接去PortB.6
- #define COL3 (1 << 7) // Col3 接去PortB.7
- #define ROW0 (1 << 0) // ROW0 接去PortB.0
- #define ROW1 (1 << 1) // ROW1 接去PortB.1
- #define ROW2 (1 << 2) // ROW2 接去PortB.2
- #define ROW3 (1 << 3) // ROW3 接去PortB.3
- #define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
- #define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)
- // Keypad layout:
- char const KEYS[4][4] = {{'7','8','9','/'},
- {'4','5','6','x'},
- {'1','2','3','-'},
- {'N','0','=','+'}};
- #define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
- // n is the number of times you expect
- // to call kbd_getc each second
- void kbd_init()
- {
- port_b_pullups (true);
- }
- char kbd_getc( ) {
- static BYTE kbd_call_count;
- static int kbd_down;
- static char last_key;
- static BYTE col;
- BYTE kchar;
- BYTE row;
- kchar='\0';
- if(++kbd_call_count>KBD_DEBOUNCE_FACTOR)
- {
- switch (col)
- {
- case 0 : set_tris_kbd(ALL_PINS&~COL0);
- kbd=~COL0&ALL_PINS;
- break;
- case 1 : set_tris_kbd(ALL_PINS&~COL1);
- kbd=~COL1&ALL_PINS;
- break;
- case 2 : set_tris_kbd(ALL_PINS&~COL2);
- kbd=~COL2&ALL_PINS;
- break;
- case 3 : set_tris_kbd(ALL_PINS&~COL3);
- kbd=~COL3&ALL_PINS;
- break;
- }
- if(kbd_down)
- {
- if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
- kbd_down=FALSE;
- kchar=last_key;
- last_key='\0';
- }
- } else {
- if((kbd & (ALL_ROWS))!=(ALL_ROWS))
- {
- if((kbd & ROW0)==0)
- row=0;
- else if((kbd & ROW1)==0)
- row=1;
- else if((kbd & ROW2)==0)
- row=2;
- else if((kbd & ROW3)==0)
- row=3;
- last_key =KEYS[row][col];
- kbd_down = TRUE;
- }
- else
- {
- ++col;
- if(col==4)
- col=0;
- }
- }
- kbd_call_count=0;
- }
- set_tris_kbd(ALL_PINS);
- return(kchar);
- }
复制代码 |
|
|
|
|
|
|
|
楼主 |
发表于 6-3-2012 09:04 PM
|
显示全部楼层
myLCD.C
修改了 CCS C 原本的 LCD Driver, LCD.C 变成 myLCD.C , 改变了 RS, RW , Enable的接线。
- //// myLCD.C ////
- //// Driver for common LCD modules ////
- //// lcd_init() Must be called before any other function. ////
- //// lcd_putc(c) Will display c on the next position of the LCD. ////
- //// The following have special meaning: ////
- //// \f Clear display ////
- //// \n Go to start of second line ////
- //// \b Move back one position ////
- //// ////
- //// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
- //// lcd_getc(x,y) Returns character at position x,y on LCD ////
- // D0 rs
- // D1 rw
- // D2 enable
- // D4 D4
- // D5 D5
- // D6 D6
- // D7 D7
- struct lcd_pin_map { // This structure is overlayed
- BOOLEAN rs; // on to an I/O port to gain
- BOOLEAN rw; // access to the LCD pins.
- BOOLEAN enable; // The bits are allocated from
- BOOLEAN unused; // low order up. ENABLE will
- int data : 4; // be pin B0.
- } lcd;
- #if defined(__PCH__)
- #if defined use_portb_lcd
- #byte lcd = 0xF81 // This puts the entire structure
- #else
- #byte lcd = 0xF83 // This puts the entire structure
- #endif
- #else
- #if defined use_portb_lcd
- #byte lcd = 6 // on to port B (at address 6)
- #else
- #byte lcd = 8 // on to port D (at address 8)
- #endif
- #endif
- #if defined use_portb_lcd
- #define set_tris_lcd(x) set_tris_b(x)
- #else
- #define set_tris_lcd(x) set_tris_d(x)
- #endif
- #define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
- #define lcd_line_two 0x40 // LCD RAM address for the second line
- BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
- // These bytes need to be sent to the LCD
- // to start it up.
- // The following are used for setting
- // the I/O port direction register.
- struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
- struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
- BYTE lcd_read_byte() {
- BYTE low,high;
- set_tris_lcd(LCD_READ);
- lcd.rw = 1;
- delay_cycles(1);
- lcd.enable = 1;
- delay_cycles(1);
- high = lcd.data;
- lcd.enable = 0;
- delay_cycles(1);
- lcd.enable = 1;
- delay_us(1);
- low = lcd.data;
- lcd.enable = 0;
- set_tris_lcd(LCD_WRITE);
- return( (high<<4) | low);
- }
- void lcd_send_nibble( BYTE n ) {
- lcd.data = n;
- delay_cycles(1);
- lcd.enable = 1;
- delay_us(2);
- lcd.enable = 0;
- }
- void lcd_send_byte( BYTE address, BYTE n ) {
- lcd.rs = 0;
- while ( bit_test(lcd_read_byte(),7) ) ;
- lcd.rs = address;
- delay_cycles(1);
- lcd.rw = 0;
- delay_cycles(1);
- lcd.enable = 0;
- lcd_send_nibble(n >> 4);
- lcd_send_nibble(n & 0xf);
- }
- void lcd_init() {
- BYTE i;
- set_tris_lcd(LCD_WRITE);
- lcd.rs = 0;
- lcd.rw = 0;
- lcd.enable = 0;
- delay_ms(15);
- for(i=1;i<=3;++i) {
- lcd_send_nibble(3);
- delay_ms(5);
- }
- lcd_send_nibble(2);
- for(i=0;i<=3;++i)
- lcd_send_byte(0,LCD_INIT_STRING[i]);
- }
- void lcd_gotoxy( BYTE x, BYTE y) {
- BYTE address;
- if(y!=1)
- address=lcd_line_two;
- else
- address=0;
- address+=x-1;
- lcd_send_byte(0,0x80|address);
- }
- void lcd_putc( char c) {
- switch (c) {
- case '\f' : lcd_send_byte(0,1);
- delay_ms(2);
- break;
- case '\n' : lcd_gotoxy(1,2); break;
- case '\b' : lcd_send_byte(0,0x10); break;
- default : lcd_send_byte(1,c); break;
- }
- }
- char lcd_getc( BYTE x, BYTE y) {
- char value;
- lcd_gotoxy(x,y);
- while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
- lcd.rs=1;
- value = lcd_read_byte();
- lcd.rs=0;
- return(value);
- }
复制代码 |
|
|
|
|
|
|
|
发表于 7-3-2012 09:32 AM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 7-3-2012 07:18 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 9-3-2012 01:49 AM
|
显示全部楼层
回复 3# pic
那个myKBD.c 我copy到完,可是有error哦***Error128"myKBD.c"Line6(5,9):A #DEVICE required before this line
那个myLCD.c 我copy到完,也是有error哦***Error128"myKBD.c"Line21(1,8):A #DEVICE required before this line |
|
|
|
|
|
|
|
楼主 |
发表于 9-3-2012 11:19 AM
|
显示全部楼层
回复 pic
那个myKBD.c 我copy到完,可是有error哦***Error128"myKBD.c"Line6(5,9):A #DEVICE required ...
Harry88 发表于 9-3-2012 01:49 AM
那些file 要放在同一个folder。
直接给你源码吧
下载CCS C源码 |
|
|
|
|
|
|
|
发表于 12-3-2012 12:23 AM
|
显示全部楼层
好贴~谢谢楼主的分享 |
|
|
|
|
|
|
|
发表于 12-3-2012 12:31 AM
|
显示全部楼层
谢谢分享 |
|
|
|
|
|
|
|
发表于 12-3-2012 03:51 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 12-3-2012 06:12 PM
|
显示全部楼层
谢谢分享。。
我不是很会PIC。。慢慢学着。。
对了,我可以问看版主你会不会arduino? |
|
|
|
|
|
|
|
楼主 |
发表于 12-3-2012 06:39 PM
|
显示全部楼层
谢谢分享。。
我不是很会PIC。。慢慢学着。。
对了,我可以问看版主你会不会arduino?
希椏 发表于 12-3-2012 06:12 PM
没有接触过, 但是未来会买了玩玩体验。。。
Arduino 适合给不是很会电子的朋友, 比如读机械工程的, 业余爱好者,
他们想要控制一些东西, 但是又不要很深入, 不是做商业用途的,
就依赖模块, 要什么功能 , 就买特定的模块, 应用人家已经写好的程序,
做出一些控制。
好处是速成, 缺点是会依赖模块, 仰赖人家写的程序 library。
ok, 离题了。 |
|
|
|
|
|
|
|
发表于 12-3-2012 10:43 PM
|
显示全部楼层
没有接触过, 但是未来会买了玩玩体验。。。
Arduino 适合给不是很会电子的朋友, 比如读机械工程的, ...
pic 发表于 12-3-2012 06:39 PM
好的,谢谢你!
我也会试学PIC,因为现在假期当中。。
希望能把握时机。。 |
|
|
|
|
|
|
|
发表于 13-3-2012 08:40 PM
|
显示全部楼层
|
|
|
|
|
|
|
发表于 13-3-2012 11:46 PM
|
显示全部楼层
谢谢楼主分享~ |
|
|
|
|
|
|
| |
本周最热论坛帖子
|