AVR简单好用的4x4矩阵键盘

合集下载

AVR单片机扫描4X4矩阵键盘并数码管显示程序

AVR单片机扫描4X4矩阵键盘并数码管显示程序

AVR单片机扫描4X4矩阵键盘并数码管显示程序/*programname : keyboard ; 功能描述: 扫描16 个按键(4X4),并把键值显示在数码管上(两位); 要点: 在扫描按键时运用了比较复杂的两个for()循环嵌套式扫描方案,大大减少了程序量,循环嵌套方案让我纠结了好久,键值有0~9,上,下,左,右,确认,清零; 体会: 又一个里程碑,泪奔啊...我似乎成了代码男神啊...;实验用时: 约等于14 小时(每天2 小时X7 天);完成时间: 2013-11-19 23:58:22*/#include #include#define uint8 unsigned char //宏定义8 位数据类型;#define uint16 unsigned int // 宏定义16 位数据类型;// 0 , 1 , 2 , 3 , 4 , 5 , 6 ,uint8 ak[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, // 7 , 8 , 9 , 上, 下左, 右; 0x07,0x7f,0x6f,0x62 ,0x54,0x21,0x0c};uint8 ge=8,shi=8 ,si=0;void bit(uint8 h) //数码管位选使能函数;{ PORTB|=0X02; //数码管位选置1(透明状态); if(h==0) {PORTB&=0XFD; //清零(锁存状态);}}void dat(uint8 u) //数码管数据使能函数;{ PORTB|=0X01; if(u==0) { PORTB&=0XFE; }}void buzz(uint8 k) //蜂鸣器函数;{ if(k==0) {PORTC&=~(0X80);} else PORTC|=0X80;}void delay(uint8 j) //1=1000 个计数周期;{ uint16 h=0; while(j--) {for(h=0;hvoid mega16() //初始化各个IO 口;{DDRA=0XFF; //PA 输出; DDRB=0XFF; //PB 输出; PORTA=0X00; //PA 输出全0; delay(1); //延时一下,1000 个计数周期; bit(0); //数码管共阴极全零;。

4X4矩阵式键盘输入程序

4X4矩阵式键盘输入程序

4*4键盘程序readkeyboard:begin: acall key_onjnz delayajmp readkeyboarddelay:acall delay10msacall key_onjnz key_numajmp beginkey_num:acall key_panl a,#0FFhjz beginacall key_ccodepush akey_off:acall key_onjnz key_offpop aretkey_on: mov a,#00horl a,#0fhmov p1,amov a,p1orl a,#0f0hcpl aretkey_p: mov r7,#0efhl_loop:mov a,r7mov p1,amov a,p1orl a,#0f0hmov r6,acpl ajz nextajmp key_cnext: mov a,r7jnb acc.7,errorrl amov r7,aajmp l_looperror:mov a,#00hretkey_c:mov r2,#00hmov r3,#00hmov a,r6mov r5,#04hagain1:jnb acc.0,out1rr ainc r2djnz r5, again1out1: inc r2mov a,r7mov r5,#04hagain2:jnb acc.4,out2rr ainc r3djnz r5,again2out2: inc r3mov a, r2swap aadd a,r3retkey_ccode:push aswap aanl a,#0fhdec arl a ;行号乘4rl amov r7,apop aanl a,#0fhdec aadd a,r7retdelay10ms:anl tmod,#0f0horl tmod,#01hmov th0,#0d8hmov tl0,#0f0hsetb tr0wait:jbc tf0,overajmp waitclr tr0over:ret单片机键盘设计(二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。

AVR学习笔记十九、4X4矩阵键盘实验

AVR学习笔记十九、4X4矩阵键盘实验

A VR学习笔记十九、4X4矩阵键盘实验19.1 实例功能在前面的实例中我们已经学习了在单片机系统中检测独立式按键的接口电路和程序设计,独立式按键的每个按键占用1位I/O口线,其状态是独立的,相互之间没有影响,只要单独测试链接案件的I/O口线电平的高低就能判断键的状态。

独立式按键电路简单、配置灵活,软件结构也相对简单。

此种接口方式适用于系统需要按键数目较少的场合。

在按键数量较多的情况下,如系统需要8个以上按键的键盘时,采用独立式接口方式就会占用太多的I/O口,这对于I/O口资源不太丰富的单片机系统来说显得相当浪费,那么当按键数目相对较多的时候,为了减少I/O口资源的占用,应该采取什么样的方式才能够既满足多按键识别,又减少I/O口的占用呢?当然我们可以采用端口扩展器件比如串并转换芯片实现单片机I/O口的扩展,但是这种方式既增加了电路的复杂性,又增加了系统的成本开销。

有没有比较经济实惠的方法呢?事实上,在实际引用中我们经常采用矩阵式键盘的方式来节约I/O口资源和系统成本。

在这个实验中,我们采用4X4矩阵键盘来实现使用8个I/O口识别16个按键的实验,本实例分为三个功能模块,分别描述如下:●单片机系统:利用A Tmega16单片机与矩阵键盘电路实现多按键识别。

●外围电路:4X4矩阵键盘电路、LED数码管显示电路。

●软件程序:编写软件,实现4X4矩阵键盘识别16个按键的程序。

通过本实例的学习,掌握以下内容:●4X4矩阵键盘的电路设计和程序实现。

19.2 器件和原理19.2.1 矩阵键盘的工作原理和扫描确认方式当键盘中按键数量较多时,为了减少对I/O口的占用,通常将按键排列成矩阵形式,也称为行列键盘,这是一种常见的连接方式。

矩阵式键盘接口见图1所示,它由行线和列线组成,按键位于行、列的交叉点上。

当键被按下时,其交点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU通过检测行或列线上的电平变化可以确定哪个按键被按下。

avr单片机基于ATmega16的4乘4矩阵按键驱动程序

avr单片机基于ATmega16的4乘4矩阵按键驱动程序

4*4矩阵按键---控制数码管//ICC-AVR application builder : 2010-10-05 19:19:34 // Target : M16#include <iom16v.h>#include <macros.h>#define hang1 (PINA&BIT(PA0))#define hang2 (PINA&BIT(PA1))#define hang3 (PINA&BIT(PA2))#define hang4 (PINA&BIT(PA3))unsigned char key=16; //16 表示无效键值unsigned char xianshishuju[8];/*************CPU器件初始化***********************/ void port_init(void){PORTA = 0xFF;DDRA = 0xF0;PORTB = 0x00;DDRB = 0xFF;PORTC = 0x00; //m103 output onlyDDRC = 0xFF;PORTD = 0xFF;DDRD = 0xFF;}//call this routine to initialize all peripherals void init_devices(void){//stop errant interrupts until set upCLI(); //disable all interruptsport_init();MCUCR = 0x00;GICR = 0x00;TIMSK = 0x00; //timer interrupt sourcesSEI(); //re-enable interrupts//all peripherals are now initialized}/****************************************//***********延时模块******************/void delay(unsigned int m){unsigned int i,j;for(i=0;i<m;i++)for(j=0;j<570;j++);}/************************************//***********显示模块*****************/unsigned char const duanma[]={0x3F,/*0*/0x06,/*1*/0x5B,/*2*/0x4F,/*3*/0x66,/*4*/0x6D,/*5*/0x7D,/*6*/0x07,/*7*/0x7F,/*8*/0x6F,/*9*/};void baweixianshi(void){unsigned char i;for(i=0;i<8;i++){PORTD=~(BIT(i));PORTC=duanma[xianshishuju[i]];delay(1);PORTC=0X00;}}/************************************//******键盘扫描模块****************************/void keyscan(void){PORTA=0XEF;//高四位1110 令第一列按键处于判断状态低四位1111 保持内部上拉电阻if(!hang1)key=0;if(!hang2)key=1;if(!hang3)key=2;if(!hang4)key=3;PORTB=~key;PORTA=0XDF;//高四位1101 令第二列按键处于判断状态低四位1111 保持内部上拉电阻if(!hang1)key=4;if(!hang2)key=5;if(!hang3)key=6;if(!hang4)key=7;PORTB=~key;PORTA=0XBF;//高四位1011 令第三列按键处于判断状态低四位1111 保持内部上拉电阻if(!hang1)key=8;if(!hang2)key=9;if(!hang3)key=10;if(!hang4)key=11;PORTB=~key;PORTA=0X7F;//高四位0111 令第四列按键处于判断状态低四位1111 保持内部上拉电阻if(!hang1)key=12;if(!hang2)key=13;if(!hang3)key=14;if(!hang4)key=15;}/**************************************************/void main(void){init_devices();//insert your functional code here...while(1){keyscan();if(key<10){xianshishuju[7]=key;}baweixianshi();}}。

单片机实现4X4矩阵键盘控制项目PPT课件

单片机实现4X4矩阵键盘控制项目PPT课件

-
5
• 在矩阵按键处理过程中,一旦检测到有按 键闭合与确认按键已经稳定闭合期间,通 过调用10-20ms延时子程序避开按键抖动问 题。由于按键是机械器件,按下或者松开 时有固定的机械抖动,抖动图如图所示。
-
6
• 按键去抖分为硬件去抖和软件去抖,硬件去抖最简单的是 按键两端并联电容,容量根据实验而定。软件去抖使用方 便不增加硬件成本,容易调试,所以现在处理按键抖动问 题大部分选择软件去抖。软件去抖操作步骤如下:
-
10
13.4 项目软件程序设计
• 矩阵键盘行线P20~P23为输出线,列线 P24~P27为输入线。单片机将行线(P20~P23) 全部输出低电平,此时读入列线数据,若列线 全为高电平则没有键按下,当列线有出现低电 平时调用延时程序以此来去除按键抖动。延时 完成后再判断是否有低电平,如果此时读入列 线数据还是有低电平,则说明确实有键按下, 再来进一步确定键值。
51单片机
VC C P0. 0 P0. 1 P0. 2 P0. 3 P0. 4 P0. 5 P0. 6 P0. 7 EA/VPP PROG/ ALE PSEN A15/P2. 7 A14/P2. 6 A13/P2. 5 A12/P2. 4 A11/P2. 3 A10/P2. 2 A9/P2. 1 A8/P2. 0

case 0xdd:P0=table[5];break; //显示按键码“5”

case 0xbd:P0=table[6];break; //显示按键码“6”

case 0x7d:P0=table[7];break; //显示按键码“7”

case 0xeb:P0=table[8];break; //显示按键码“8”

4X4矩阵式键盘输入程序

4X4矩阵式键盘输入程序

4*4键盘程序readkeyboard:begin: acall key_onjnz delayajmp readkeyboard delay:acall delay10msacall key_onjnz key_numajmp beginkey_num:acall key_panl a,#0FFhjz beginacall key_ccodepush akey_off:acall key_onjnz key_offpop aretkey_on: mov a,#00horl a,#0fhmov p1,amov a,p1orl a,#0f0hcpl aretkey_p: mov r7,#0efhl_loop:mov a,r7mov p1,amov a,p1orl a,#0f0hmov r6,acpl ajz nextajmp key_cnext: mov a,r7jnb acc.7,errorrl amov r7,aajmp l_looperror:mov a,#00hretkey_c:mov r2,#00hmov r3,#00hmov a,r6mov r5,#04hagain1:jnb acc.0,out1rr ainc r2djnz r5, again1out1: inc r2mov a,r7mov r5,#04hagain2:jnb acc.4,out2rr ainc r3djnz r5,again2out2: inc r3mov a, r2swap aadd a,r3retkey_ccode:push aswap aanl a,#0fhdec arl a ;行号乘4rl amov r7,apop aanl a,#0fhdec aadd a,r7retdelay10ms:anl tmod,#0f0horl tmod,#01hmov th0,#0d8hmov tl0,#0f0hsetb tr0wait:jbc tf0,overajmp waitclr tr0over:ret单片机键盘设计(二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。

单片机4×4矩阵键盘设计方案

单片机4×4矩阵键盘设计方案

1、设计原理(1)如图14.2所示,用单片机的并行口P3连接4×4矩阵键盘,并以单片机的P3.0-P3.3各管脚作输入线,以单片机的P3.4-P3.7各管脚作输出线,在数码管上显示每个按键“0-F”的序号。

(2)键盘中对应按键的序号排列如图14.1所示。

2、参考电路图14.2 4×4矩阵式键盘识别电路原理图3、电路硬件说明(1)在“单片机系统”区域中,把单片机的P3.0-P3.7端口通过8联拨动拨码开关JP3连接到“4×4行列式键盘”区域中的M1-M4,N1-N4端口上。

(2)在“单片机系统”区域中,把单片机的P0.0-P0.7端口连接到“静态数码显示模块”区域中的任何一个a-h端口上;要求:P0.0对应着a,P0.1对应着b,……,P0.7对应着h。

4、程序设计内容(1)4×4矩阵键盘识别处理。

(2)每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。

矩阵的行线和列线分别通过两并行接口和CPU通信。

键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。

键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。

两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。

5、程序流程图(如图14.3所示)6、汇编源程序;;;;;;;;;;定义单元;;;;;;;;;;COUNT EQU 30H;;;;;;;;;;入口地址;;;;;;;;;;ORG 0000HLJMP STARTORG 0003HRETIORG 000BHRETIORG 0013HRETIORG 001BHRETIORG 0023HRETIORG 002BHRETI;;;;;;;;;;主程序入口;;;;;;;;;;ORG 0100HSTART: LCALL CHUSHIHUALCALL PANDUANLCALL XIANSHILJMP START;;;;;;;;;;初始化程序;;;;;;;;;;CHUSHIHUA: MOV COUNT,#00HRET;;;;;;;;;;判断哪个按键按下程序;;;;;;;;;;PANDUAN: MOV P3,#0FFHCLR P3.4MOV A,P3ANL A,#0FHJZ SW1LCALL DELAY10MS JZ SW1MOV A,P3ANL A,#0FHCJNE A,#0EH,K1 MOV COUNT,#0 LJMP DKK1: CJNE A,#0DH,K2 MOV COUNT,#4 LJMP DKK2: CJNE A,#0BH,K3 MOV COUNT,#8 LJMP DKK3: CJNE A,#07H,K4 MOV COUNT,#12K4: NOPLJMP DKSW1: MOV P3,#0FFH CLR P3.5MOV A,P3ANL A,#0FHJZ SW2LCALL DELAY10MS JZ SW2MOV A,P3ANL A,#0FHCJNE A,#0EH,K5 MOV COUNT,#1 LJMP DKK5: CJNE A,#0DH,K6 MOV COUNT,#5 LJMP DKK6: CJNE A,#0BH,K7 MOV COUNT,#9 LJMP DKK7: CJNE A,#07H,K8 MOV COUNT,#13K8: NOPLJMP DKSW2: MOV P3,#0FFH CLR P3.6MOV A,P3ANL A,#0FHJZ SW3LCALL DELAY10MS JZ SW3MOV A,P3ANL A,#0FHCJNE A,#0EH,K9 MOV COUNT,#2 LJMP DKK9: CJNE A,#0DH,KA MOV COUNT,#6 LJMP DKKA: CJNE A,#0BH,KB MOV COUNT,#10 LJMP DKKB: CJNE A,#07H,KC MOV COUNT,#14 KC: NOPLJMP DKSW3: MOV P3,#0FFH CLR P3.7MOV A,P3ANL A,#0FHJZ SW4LCALL DELAY10MSJZ SW4MOV A,P3ANL A,#0FHCJNE A,#0EH,KDMOV COUNT,#3LJMP DKKD: CJNE A,#0DH,KE MOV COUNT,#7LJMP DKKE: CJNE A,#0BH,KF MOV COUNT,#11 LJMP DKKF: CJNE A,#07H,KG MOV COUNT,#15KG: NOPLJMP DKSW4: LJMP PANDUAN DK: RET ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A,COUNTMOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ALCALL DELAYSK: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ SKRET;;;;;;;;;;10ms延时程序;;;;;;;;;;DELAY10MS: MOV R6,#20D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RET;;;;;;;;;;200ms延时程序;;;;;;;;;;DELAY: MOV R5,#20LOOP: LCALL DELAY10MSDJNZ R5,LOOPRET;;;;;;;;;;共阴码表;;;;;;;;;;TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H;;;;;;;;;;结束标志;;;;;;;;;;END7、C语言源程序#includeunsigned char code table[]={0x3f,0x66,0x7f,0x39,0x06,0x6d,0x6f,0x5e,0x5b,0x7d,0x77,0x79,0x4f,0x07,0x7c,0x71};void main(void){ unsigned char i,j,k,key;while(1){ P3=0xff; //给P3口置1//P3_4=0; //给P3.4这条线送入0//i=P3;i=i&0x0f; //屏蔽低四位//if(i!=0x0f) //看是否有按键按下//{ for(j=50;j>0;j--) //延时//for(k=200;k>0;k--);if(i!=0x0f) //再次判断按键是否按下//{ switch(i) //看是和P3.4相连的四个按键中的哪个// { case 0x0e:key=0;break;case 0x0d:key=1;break;case 0x0b:key=2;break;case 0x07:key=3;break;}P0=table[key]; //送数到P0口显示//}}P3=0xff;P3_5=0; //读P3.5这条线//i=P3;i=i&0x0f; //屏蔽P3口的低四位//if(i!=0x0f) //读P3.5这条线上看是否有按键按下// { for(j=50;j>0;j--) //延时//for(k=200;k>0;k--);i=P3; //再看是否有按键真的按下//i=i&0x0f;if(i!=0x0f){ switch(i) //如果有,显示相应的按键//{ case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}P0=table[key]; //送入P0口显示//}}P3=0xff;P3_6=0; //读P3.6这条线上是否有按键按下// i=P3;i=i&0x0f;if(i!=0x0f){ for(j=50;j>0;j--)for(k=200;k>0;k--);i=P3;i=i&0x0f;if(i!=0x0f){ switch(i){ case 0x0e:key=8;break;case 0x0d:key=9;break;case 0x0b:key=10;break;case 0x07:key=11;break;}P0=table[key];}}P3=0xff;P3_7=0; //读P3.7这条线上是否有按键按下//i=P3;i=i&0x0f;if(i!=0x0f){ for(j=50;j>0;j--) for(k=200;k>0;k--); i=P3;i=i&0x0f;if(i!=0x0f){ switch(i){ case 0x0e:key=12;break;case 0x0d:key=13;break;case 0x0b:key=14;break;case 0x07:key=15;break;}P0=table[key];}}}}8、注意事项在硬件电路中,要把8联拨动拨码开关JP2拨下,把8联拨动拨码开关JP3拨上去。

实验四4X4矩阵键盘实验

实验四4X4矩阵键盘实验


狀態S_2: 發出掃瞄column 1即col=4’b1101的狀態並讀回row值作比 較:
如果讀到row不等於f (4’b1111)就代表在column 1上的4個按鍵(3, 7, b, f)有其中一個被按下,於是跳至S_5做等待使用者放開按鍵的處 理。 如果讀到row等於f (4’b1111)就代表在column 1上的4個按鍵(3, 7, b, f)沒有被按下,於是跳至S_3做掃瞄column 2的按鍵。
按鍵掃瞄之狀態
狀態S_3: 發出掃瞄column 2即col=4’b1011的狀態並讀回
row值作比較:
如果讀到row不等於f (4’b1111)就代表在column 2上的4個按鍵(2, 6, a, e)有其中一個被按下,於是跳至S_5做等待使用者放開按 鍵的處理。 如果讀到row等於f (4’b1111)就代表在column 2上的4個按鍵(2, 6, a, e)沒有被按下,於是跳至S_4做掃瞄column 2的按鍵。 狀態S_4: 發出掃瞄column 3即col=4’b0111的狀態並讀回row值作比較: 如果讀到row不等於f (4’b1111)就代表在column 3上的4個按鍵(1, 5, g, d)有其中一個被按下,於是跳至S_5做等待使用者放開按 鍵的處理。 如果讀到row等於f (4’b1111)就代表在column 3上的4個按鍵(1, 5, g, d)沒有被按下,於是跳回至S_0,因此FSM跳回Idle state即掃 描完4個column 都沒有發現任何按鍵被按下。 狀態S_5: 等待使用者放開按鍵的狀態,如果使用者沒放開按鍵就一直停
實驗四 4X4矩陣鍵盤實驗
4X4矩陣鍵盤輸入並輸出至七段式顯示器
底板子4x4矩陣按鍵
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
unsignedchar keyboard_Scan(volude #include
#include“key.h”
constunsignedcharkey_table[16]={1,2,3,12,4,5,6,13,7,8,9,14,10,0,11,15,
};
voiddelay_1ms(void)//1ms延时函数{unsignedinti;for(i=0;i//4x4矩阵键盘
扫描函数
unsignedchar keyboard_Scan(void){ unsigned chartemp,key,row,Column;
key_port_ddr=0b00001111;//高四位输入行线/低四位输出列线key_port=
#include #include
#include“key.h”
voidmain(void){unsignedcharKey;while(1){Key=keyboard_Scan();//键盘扫
描switch(Key) { case 0: break;
...... default: break;} }}
AVR简单好用的4x4矩阵键盘
// Target: ATMEGA16// Crystal: 8.0000Mhz
//key.h
#ifndef _4X4_H_#define_4X4_H_
#define No_key 255
#define key_portPORTB#define key_port_ddr DDRB#define key_port_pin PINB
主函数中的延时个人觉得最好还是用定时器
电路接法不同可修改key_table数组
tips:感谢大家的阅读,本文由我司收集整编。仅供参阅!
0b11110000;//高四位打开上拉电阻/低四位输出低电平delay_nus(5);//延时5us
if((key_port_pin&0xF0)!=0xF0)//作初检查有否键按下,没有,就返回{//如果行
线不全为1,可能有键按下delay_nms(5);//延时去抖动
//设置列线初始值
3~0=1110for(Column=0,key_port=0b11111110;Column//main.c
相关文档
最新文档