2022年2022年矩阵键盘扫描的C语言实例 .pdf
《2022年2022年矩阵键盘扫描的C语言实例 .pdf》由会员分享,可在线阅读,更多相关《2022年2022年矩阵键盘扫描的C语言实例 .pdf(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、矩阵键盘扫描的C 语言实例1、按键扫描(线反转)/- - / 函数名称:program_SCANkey / 函数功能:程序扫描键盘,/ 有键按下完成按键处理,无键按下直接返回/- void program_SCANkey() unsigned char key_code; if(judge_hitkey() /判断是否有键按下 delay(1000); /延时 20ms左右,消除抖动干扰if(judge_hitkey() /判断是否有效按键 key_code=scan_key();/获取键值while(judge_hitkey(); /等待按键释放 key_manage(key_code);
2、/键盘扫描、键盘散转、按键处理 /- / 函数名称:judge_hitkey / 函数功能:/判断是否有键按下,有返回1,没有返回0 / 列判断,还可以用行判断。/- bit judge_hitkey() /判断是否有键按下,有返回1,没有返回0 unsigned char scancode,keycode; scancode=0 x0F; /开始设定P1.0P1.3 输出全 1(初值)即表明无键闭合KEY=scancode; keycode=KEY; /读取 P1.0P1.3 的真实状态,从而确定有没有键被按下if(keycode=0 x0F) return(0); /全 1 则无键闭合el
3、se return(1); /否则有键闭合 /- / 函数名称:scan_key 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 16 页 - - - - - - - - - / 函数功能:/扫描键盘,返回键值(高四位代表行,低四位代表列) / 说明: scancode 扫描码, keycode 键值 ,keycode_line 行, keycode_row 列/ 过程:先扫描行,确定那行的按键被按下。再扫描列,确定那列的按键被按下,从而确定那个按键被按下。/- unsi
4、gned char scan_key() /扫描键盘,返回键值(高四位代表行,低四位代表列 ) unsigned char scancode,keycode,keycode_line,keycode_row; scancode=0 xF0; /列置低,行置高KEY = scancode; /输入扫描码,扫描行keycode_line=KEY; /KEY 的值是与键盘相连的P 的状态值。若没有按键按下 KEY 的值为 0 xF0,若有按键按下则KEY 的值就不是0 xF0 scancode=0 x0F; /列置高,行置低KEY=scancode; /输入扫描码,扫描列keycode_row=KE
5、Y; /KEY 的值是与键盘相连的P 的状态值。若没有按键按下KEY 的值为 0 x0F,若有按键按下则KEY 的值就不是0 x0F keycode = (keycode_line&0 xF0)|(keycode_row&0 x0F); return(keycode); 2、按键扫描(逐行扫描)/- / 函数名称:kbscan 键盘扫描子程序/ 函数功能:判断是否有键按下,有返回键值,没有返回0 / p1 的高四位为列, 低四位为行P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 / 列 4 列3 列2 列 1 行 4 行 3 行 2 行 1 / 过程:先根据列判
6、断是否有键按下,没有返回0,有,则逐行扫描以确定按键所在的行,再确定按键所在列/ 从而最终确定该按键。/- uchar kbscan(void) uchar sccode,recode; P1=0 xf0; /置所有行为低电平,行扫描,列线输入(此时 ) if(P1&0 xf0)!=0 xf0) /判断是否有有键按下(读取列的真实状态,若第 4 列有键按下则 P1的值会变成0111 0000) ,有往下执行 delays(); /延时去抖动(10ms)if(P1&0 xf0)!=0 xf0) /再次判断列中是否是干扰信号,不是则向下执行名师资料总结 - - -精品资料欢迎下载 - - - -
7、- - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 16 页 - - - - - - - - - sccode=0 xFE; /逐行扫描初值(即先扫描第1 行)while(sccode&0 x10)!=0) /行扫描完成时(即4 行已经全部扫描完成)sccode为 1110 1111 停止 while 程序 P1=sccode; /输出行扫描码if (P1&0 xf0)!=0 xf0) /本行有键按下 (即 P1(真实的状态) 的高四位不全为 1) recode=(P1&0 xf0)|0 x0f; / 列return(sccode&
8、recode); / 返回行和列 else /所扫描的行没有键按下,则扫描下一行,直到4 行都扫描,此时 sccode值为 1110 1111 退出 while 程序 sccode=(sccode1)|0 x01;/ 行扫描码左移一位 else return 0; /无键按下,返回0 - /*Main.c*/ #include global.c void SystemInit(); void Timer1Init(); void KickDog(); void delay(); unsigned int judge_key(); unsigned int scan_key(); unsigne
9、d char numkey=0; unsigned char DATX,DATY; main() 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 16 页 - - - - - - - - - SystemInit(); /系统初始化MCRA=MCRA & 0 x80FF; /IOPB0-6 设为 IO 口模式PBDATDIR=0 xBFC2; /所有 LED=0, 并置 IOPB6 为输入口Timer1Init(); /定时器初始化asm( CLRC INTM ); wh
10、ile(1) / KeyLed(); if(judge_key()=1) numkey+; void SystemInit() asm( SETC INTM ); /* 关闭总中断*/ asm( CLRC SXM ); /* 禁止符号位扩展*/ asm( CLRC CNF ); /* B0 块映射为on-chip DARAM*/ asm( CLRC OVM ); /* 累加器结果正常溢出*/ SCSR1=0 x83FE; /* 系统时钟CLKOUT=20*2=40M */ WDCR=0 x006F; /* 禁止看门狗 ,看门狗时钟64 分频*/ KickDog(); /* 初始化看门狗*/ I
11、FR=0 xFFFF; /* 清除中断标志*/ IMR=0 x0002; /* 打开中断2*/ void Timer1Init() EVAIMRA=0 x0080; / 定时器 1 周期中断使能EVAIFRA=0 xFFFF; / 清除中断标志GPTCONA=0 x0000; T1PR=2500; / 定时器 1 初值 ,定时 0.4us*2500=1ms T1CNT=0; T1CON=0 x144E; /增模式 , TPS 系数 40M/16=2.5M,T1使能 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 -
12、 - - - - - - 第 4 页,共 16 页 - - - - - - - - - unsigned int judge_key() MCRC=MCRC&0 x81FF; / PFDATDIR=PFDA TDIR|0 x0070; PFDATDIR=PFDA TDIR&0 x8FFF; /设置 456 输入高PFDATDIR=PFDA TDIR&0 xFFF1; PFDATDIR=PFDA TDIR|0 x0E00; /设置 123 输出低if(PFDATDIR&0 x0070)=0 x0070) return(0); else return(1); unsigned int scan_k
13、ey() if(judge_key()=1) delay(); if(judge_key()=1) MCRC=MCRC&0 x81FF; / PFDATDIR=PFDA TDIR|0 x0070; PFDATDIR=PFDA TDIR&0 x8FFF; /设置 456 输入高PFDATDIR=PFDA TDIR&0 xFFF1; PFDATDIR=PFDA TDIR|0 x0E00; /设置 123 输出低delay(); numkey=(PFDATDIR&0 x0070)|(PFDATDIR&0 x000E); / delay(); /MCRC=MCRC&0 x81FF; / PFDATDI
14、R=PFDA TDIR&0 xFF8F; /设置 456 输出低PFDATDIR=PFDA TDIR|0 xE000; PFDATDIR=PFDA TDIR|0 x000E; /设置 123 输入高PFDATDIR=PFDA TDIR&0 xF1FF; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 16 页 - - - - - - - - - delay(); / numkey=(PFDATDIR&0 x0070)|(PFDATDIR&0 x000E); numkey=
15、numkey|(PFDATDIR&0 x000E); return(numkey); void c_int2() /*定时器 1 中断服务程序 */ if(PIVR!=0 x27) asm( CLRC INTM ); return; scan_key() ; EVAIFRA=EV AIFRA&0 x80; asm( CLRC INTM ); void delay() int i; for(i=0;i10000;i+); void KickDog() /* 踢除看门狗*/ WDKEY=0 x5555; WDKEY=0 xAAAA; 名师资料总结 - - -精品资料欢迎下载 - - - - - -
16、 - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 16 页 - - - - - - - - - 矩阵键盘扫描程序集锦2009-08-18 11:24 初学者写的最简单矩阵键盘扫描程序这是站长初学者写的最简单、 最详细、 效率最高的矩阵键盘扫描程序,只用了四条常用命令( MOV/ 送数、JB/高电平转移、 JMP/直接转移、 RET/子程序返回),保证初学者一看就懂! 本程序已经在本站电子实验板上验证通过,占用时间少,效率高,被选作单片机的测试程序!矩阵按键扫描程序是一种节省IO 口的方法 , 按键数目越多节省IO 口就越可观,本程序的思
17、路跟书上一样:先判断某一列(行)是否有按键按下,再判断该行(列)是那一只键按下。但是,在程序的写法上,站长采用了最简单的方法,使得程序效率最高。本程序中,如果检测到某键按下了, 就不再检测其它的按键, 这完全能满足绝大多数需要, 又能节省大量的CPU 时间。另外,本人认为键盘用延时程序来消除抖动,完全是浪费时间。试想,如果不用中断执行(用中断执行需要更多的硬件资源)的方法来扫描键盘, 每秒钟扫描次,每次都要延时的话,我们的单片机还有多少时间做正事呢?其实,延时的这段时间, CPU可以做其它的事呀。所以,本键盘扫描程序的前面后面都可以加入少少代码, 既可以达到完美的消抖动效果, 又可以扩展其它的
18、功能(例如按键封锁、按键长按等按键功能复用!)本键盘扫描子程序名叫key,每次要扫描时用call key调用即可。以下子程序内容:key:mov p0,#00001111b; 上四位和下四位分别为行和列, 所以送出高低电压检查有没有按键按下jmp k10; 跳到 K10处开始扫描, 这里可以改成其它条件转移指令来决定本次扫描是否要继续,例如减1 为 0 转移或者位为 1 或 0 才转移,这主要用来增加功能,确认上一按键功能是否完成?是否相当于经过了延时?是否要封锁键盘?goend:jmp kend; 如果上面判断本次不执行键盘扫描程序,则立即转到程序尾部,不要浪费 CPU 的时间k10:jb
19、p0.0,k20;扫描正式开始,先检查列1 四个键是否有键按下,如果没有,则跳到 K20检查列 2 k11:mov p0,#11101111b; 列 1 有键按下时 ,P0.0 变低, 到底是那一个键按下?现在分别输出各行低电平jb p0.0,k12;该行的键不按下时, p0.0 为高电平 , 跳到到 K12,检查其它的行mov r1,#1; 如果正好是这行的键按下,将寄存器R0写下 1,表示 1 号键按下了k12:mov p0,#11011111b jb p0.0,k13 mov r1,#2; 如果正好是这行的键按下,将寄存器R0写下 2,表示 2 号键按下了k13:mov p0,#1011
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年2022年矩阵键盘扫描的C语言实例 2022 矩阵 键盘 扫描 语言 实例
限制150内