(代码未能实现,改进ing) (仅能检测到列,检测不到行,改进ing)【单片机】— {STC15}—{矩阵键盘&Proteus}
矩阵键盘
Proteus仿真
一、Proteus仿真STC15的问题
> 据说P0口存在BUG,不会被正常拉低,而是产生短路。
二、原理图
1、CPU
2、矩阵键盘
3、显示部分
程序
一、矩阵键盘_单行扫描_普通写法
#include<STC15.H> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define KeyBus P6 //定义矩阵键盘接口 uchar Key_res =0; uchar i=0; void GPIO(void); //IO口初始化函数 void Delay10ms(); //@12.000MHz void Delay5ms(); //@12.000MHz void Delay1ms(); //@12.000MHz uchar Key16_Scan(void);//矩阵键盘扫描函数子程序 void Key16_Function(void); //矩阵键盘服务(功能)子函数 void main(void) { GPIO(); while(1) { Key_res =0; i=Key16_Scan(); //矩阵键盘扫描函数子程序 Key16_Function(); //矩阵键盘服务(功能)子函数 } } //-----------------------------------IO口初始化函数-----------------------------// void GPIO(void) { P0M1=0; P0M0=0; P1M1=0; P1M0=0; P2M1=0; P2M0=0; P3M1=0; P3M0=0; P4M1=0; P4M0=0; P5M1=0; P5M0=0; } //------------------------------------软件延时---------------------------------------// void Delay10ms() //@12.000MHz { unsigned char i, j; i = 117; j = 184; do { while (--j); } while (--i); } void Delay5ms() //@12.000MHz { unsigned char i, j; i = 59; j = 90; do { while (--j); } while (--i); } void Delay1ms() //@12.000MHz { unsigned char i, j; i = 12; j = 169; do { while (--j); } while (--i); } //---------------------------------------矩阵键盘扫描函数子程序-------------------------// uchar Key16_Scan(void) { uchar temp = 0; uchar Key_res = 0; KeyBus = 0XFF; KeyBus = 0X7F; //0111 1111 扫描第一行 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); //按键消抖 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=16;break; case 0X0D: Key_res=15;break; case 0X0B: Key_res=14;break; case 0X07: Key_res=13;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } KeyBus = 0XFF; KeyBus = 0XBF; //1011 1111 扫描第二行 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=12;break; case 0X0D: Key_res=11;break; case 0X0B: Key_res=10;break; case 0X07: Key_res=9;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } KeyBus = 0XFF; KeyBus = 0XDF; //1101 1111 扫描第三行 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=8;break; case 0X0D: Key_res=7;break; case 0X0B: Key_res=6;break; case 0X07: Key_res=5;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } KeyBus = 0XFF; KeyBus = 0XEF; //1110 1111 扫描第四行 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=4;break; case 0X0D: Key_res=3;break; case 0X0B: Key_res=2;break; case 0X07: Key_res=1;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } return Key_res; } //-----------------------------------矩阵键盘服务(功能)子函数-------------------// void Key16_Function(void) { if(i != 0) { switch(i) { case 1: P1=0XFE;P2=0XFF;break; case 2: P1=0XFD;P2=0XFF;break; case 3: P1=0XFB;P2=0XFF;break; case 4: P1=0XF7;P2=0XFF;break; case 5: P1=0XEF;P2=0XFF;break; case 6: P1=0XDF;P2=0XFF;break; case 7: P1=0XBF;P2=0XFF;break; case 8: P1=0X7F;P2=0XFF;break; case 9: P1=0XFF;P2=0XFE;break; case 10: P1=0XFF;P2=0XFD;break; case 11: P1=0XFF;P2=0XFB;break; case 12: P1=0XFF;P2=0XF7;break; case 13: P1=0XFF;P2=0XEF;break; case 14: P1=0XFF;P2=0XDF;break; case 15: P1=0XFF;P2=0XBF;break; case 16: P1=0XFF;P2=0X7F;break; default:P1=0X00;P2=0X00;break; } } }
二、矩阵键盘_单行扫描_外部中断
#include<STC15.H> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define KeyBus P6 //定义矩阵键盘接口 uchar Key_res =0; uchar i=0; void GPIO(void); //IO口初始化函数 void Delay10ms(); //@12.000MHz void Delay5ms(); //@12.000MHz void Delay1ms(); //@12.000MHz void INT1_INIT(void); //外部中断1初始化函数 uchar Key16_Scan(void);//矩阵键盘扫描函数子程序 void Key16_Function(void); //矩阵键盘服务(功能)子函数 void main(void) { GPIO(); INT1_INIT(); while(1) { KeyBus=0X0F; Key16_Function(); //矩阵键盘服务(功能)子函数 } } //-----------------------------------IO口初始化函数-----------------------------// void GPIO(void) { P0M1=0; P0M0=0; P1M1=0; P1M0=0; P2M1=0; P2M0=0; P3M1=0; P3M0=0; P4M1=0; P4M0=0; P5M1=0; P5M0=0; } //------------------------------------软件延时---------------------------------------// void Delay10ms() //@12.000MHz { unsigned char i, j; i = 117; j = 184; do { while (--j); } while (--i); } void Delay5ms() //@12.000MHz { unsigned char i, j; i = 59; j = 90; do { while (--j); } while (--i); } void Delay1ms() //@12.000MHz { unsigned char i, j; i = 12; j = 169; do { while (--j); } while (--i); } //---------------------------------------外部中断1初始化函数-----------------------------// void INT1_INIT(void) { IT1=1; EX1=1; EA=1; } //---------------------------------------矩阵键盘扫描函数子程序-------------------------// uchar Key16_Scan(void) { uchar temp = 0; uchar Key_res = 0; KeyBus = 0XFF; KeyBus = 0X7F; //0111 1111 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=16;break; case 0X0D: Key_res=15;break; case 0X0B: Key_res=14;break; case 0X07: Key_res=13;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } KeyBus = 0XFF; KeyBus = 0XBF; //1011 1111 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=12;break; case 0X0D: Key_res=11;break; case 0X0B: Key_res=10;break; case 0X07: Key_res=9;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } KeyBus = 0XFF; KeyBus = 0XDF; //1101 1111 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=8;break; case 0X0D: Key_res=7;break; case 0X0B: Key_res=6;break; case 0X07: Key_res=5;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } KeyBus = 0XFF; KeyBus = 0XEF; //1110 1111 temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { Delay10ms(); temp=KeyBus; temp=temp&0X0F; if(temp!=0X0F) { temp=temp&0X0F; switch(temp) { case 0X0E: Key_res=4;break; case 0X0D: Key_res=3;break; case 0X0B: Key_res=2;break; case 0X07: Key_res=1;break; default: break; } while(temp!=0X0F) //松手检测 { temp=KeyBus; temp=temp&0X0F; } } } return Key_res; } //--------------------------------------外部中断1服务函数-----------------------------// void INT1_ISR() interrupt 2 { i = Key16_Scan(); //矩阵键盘扫描函数子程序 } //-----------------------------------矩阵键盘服务(功能)子函数-------------------// void Key16_Function(void) { if(i != 0) { switch(i) { case 1: P1=0XFE;P2=0XFF;break; case 2: P1=0XFD;P2=0XFF;break; case 3: P1=0XFB;P2=0XFF;break; case 4: P1=0XF7;P2=0XFF;break; case 5: P1=0XEF;P2=0XFF;break; case 6: P1=0XDF;P2=0XFF;break; case 7: P1=0XBF;P2=0XFF;break; case 8: P1=0X7F;P2=0XFF;break; case 9: P1=0XFF;P2=0XFE;break; case 10: P1=0XFF;P2=0XFD;break; case 11: P1=0XFF;P2=0XFB;break; case 12: P1=0XFF;P2=0XF7;break; case 13: P1=0XFF;P2=0XEF;break; case 14: P1=0XFF;P2=0XDF;break; case 15: P1=0XFF;P2=0XBF;break; case 16: P1=0XFF;P2=0X7F;break; default:P1=0X00;P2=0X00;break; } } }
三、矩阵键盘_多行扫描_普通写法
#include<STC15.H> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define KeyBus P6 //定义矩阵键盘接口 uchar Key_res =0; uchar i=0; void GPIO(void); //IO口初始化函数 void Delay10ms(); //@12.000MHz void Delay5ms(); //@12.000MHz void Delay1ms(); //@12.000MHz uchar Key16_Scan(void);//矩阵键盘扫描函数子程序 void Key16_Function(void); //矩阵键盘服务(功能)子函数 void main(void) { GPIO(); //IO口初始化函数 while(1) { Key_res =0; i=Key16_Scan(); //矩阵键盘扫描函数子程序 Key16_Function(); //矩阵键盘服务(功能)子函数 } } //-----------------------------------IO口初始化函数-----------------------------// void GPIO(void) { P0M1=0; P0M0=0; P1M1=0; P1M0=0; P2M1=0; P2M0=0; P3M1=0; P3M0=0; P4M1=0; P4M0=0; P5M1=0; P5M0=0; } //------------------------------------软件延时---------------------------------------// void Delay10ms() //@12.000MHz { unsigned char i, j; i = 117; j = 184; do { while (--j); } while (--i); } void Delay5ms() //@12.000MHz { unsigned char i, j; i = 59; j = 90; do { while (--j); } while (--i); } void Delay1ms() //@12.000MHz { unsigned char i, j; i = 12; j = 169; do { while (--j); } while (--i); } //---------------------------------------矩阵键盘扫描函数子程序-------------------------// uchar Key16_Scan(void) { uchar X_temp = 0,Y_temp = 0; uchar Key_down = 0; KeyBus = 0XFF; KeyBus = 0X0F; //高4位置0,低4位置1,此时有按键按下时,低四位的某一位会被拉低,由此定位按下的按键在第几列 Y_temp = KeyBus&0X0F; if(Y_temp!=0X0F) //如果检测到某列有按键按下(有按键按下时,低四位会有一位被拉低) { Delay5ms(); //按键消抖(不知道有无必要) KeyBus = 0X0F; Y_temp = KeyBus&0X0F;//将KeyBus低四位的按键信息赋值给Y_temp if(Y_temp!=0X0F) { KeyBus = 0X0F; Y_temp = KeyBus&0X0F; //将KeyBus低四位的按键信息赋值给Y_temp,反应列信息 KeyBus = 0XF0; X_temp = KeyBus&0XF0; //将KeyBus高四位的按键信息赋值给X_temp,反应行信息 if(Key_down == 0) //按键抬起检测, { switch(Y_temp) //判断列 { case 0X07: Key_res=1; break; case 0X0B: Key_res=2; break; case 0X0D: Key_res=3; break; case 0X0E: Key_res=4; break; default: return 0; //无按键按下,返回0 } switch(X_temp) //判断行 { case 0X70: return Key_res+12;break; case 0XB0: return Key_res+ 8;break; case 0XD0: return Key_res+ 4;break; case 0XE0: return Key_res; break; default: return 0; //无按键按下,返回0 } } } } else Key_down = 0; //按键被松开 if(Key_res) Key_down = 1; //标志按键被按下,防止重入 return Key_res; } //-----------------------------------矩阵键盘服务(功能)子函数-------------------// void Key16_Function(void) { if(i != 0) //按键按下 { switch(i) { case 1: P1=0XFE;P2=0XFF;break; case 2: P1=0XFD;P2=0XFF;break; case 3: P1=0XFB;P2=0XFF;break; case 4: P1=0XF7;P2=0XFF;break; case 5: P1=0XEF;P2=0XFF;break; case 6: P1=0XDF;P2=0XFF;break; case 7: P1=0XBF;P2=0XFF;break; case 8: P1=0X7F;P2=0XFF;break; case 9: P1=0XFF;P2=0XFE;break; case 10: P1=0XFF;P2=0XFD;break; case 11: P1=0XFF;P2=0XFB;break; case 12: P1=0XFF;P2=0XF7;break; case 13: P1=0XFF;P2=0XEF;break; case 14: P1=0XFF;P2=0XDF;break; case 15: P1=0XFF;P2=0XBF;break; case 16: P1=0XFF;P2=0X7F;break; default:P1=0X00;P2=0X00;break; } } }
四、矩阵键盘_多行扫描_外部中断
#include<STC15.H> #include<intrins.h> #define uchar unsigned char #define uint unsigned int #define KeyBus P6 //定义矩阵键盘接口 uchar Key_res =0; uchar i=0; void GPIO(void); //IO口初始化函数 void Delay10ms(); //@12.000MHz void Delay5ms(); //@12.000MHz void Delay1ms(); //@12.000MHz void INT1_INIT(void); //外部中断1初始化函数 uchar Key16_Scan(void);//矩阵键盘扫描函数子程序 void Key16_Function(void); //矩阵键盘服务(功能)子函数 void main(void) { GPIO(); //IO口初始化函数 INT1_INIT(); while(1) { KeyBus = 0X0F; Key16_Function(); //矩阵键盘服务(功能)子函数 } } //-----------------------------------IO口初始化函数-----------------------------// void GPIO(void) { P0M1=0; P0M0=0; P1M1=0; P1M0=0; P2M1=0; P2M0=0; P3M1=0; P3M0=0; P4M1=0; P4M0=0; P5M1=0; P5M0=0; } //------------------------------------软件延时---------------------------------------// void Delay10ms() //@12.000MHz { unsigned char i, j; i = 117; j = 184; do { while (--j); } while (--i); } void Delay5ms() //@12.000MHz { unsigned char i, j; i = 59; j = 90; do { while (--j); } while (--i); } void Delay1ms() //@12.000MHz { unsigned char i, j; i = 12; j = 169; do { while (--j); } while (--i); } //---------------------------------------外部中断1初始化函数-----------------------------// void INT1_INIT(void) { IT1=1; EX1=1; EA=1; } //---------------------------------------矩阵键盘扫描函数子程序-------------------------// uchar Key16_Scan(void) { uchar X_temp = 0,Y_temp = 0; uchar Key_down = 0; KeyBus = 0XFF; KeyBus = 0X0F; //高4位置0,低4位置1,此时有按键按下时,低四位的某一位会被拉低,由此定位按下的按键在第几列 Y_temp = KeyBus&0X0F; if(Y_temp!=0X0F) //如果检测到某列有按键按下(有按键按下时,低四位会有一位被拉低) { Delay1ms(); //按键消抖(不知道有无必要) KeyBus = 0X0F; Y_temp = KeyBus&0X0F;//将KeyBus低四位的按键信息赋值给Y_temp if(Y_temp!=0X0F) { KeyBus = 0X0F; Y_temp = KeyBus&0X0F; //将KeyBus低四位的按键信息赋值给Y_temp,反应列信息 KeyBus = 0XF0; X_temp = KeyBus&0XF0; //将KeyBus高四位的按键信息赋值给X_temp,反应行信息 if(Key_down == 0) //按键抬起检测, { switch(Y_temp) //判断列 { case 0X07: Key_res=1; break; case 0X0B: Key_res=2; break; case 0X0D: Key_res=3; break; case 0X0E: Key_res=4; break; default: return 0; //无按键按下,返回0 } switch(X_temp) //判断行 { case 0X70: return Key_res+12;break; case 0XB0: return Key_res+ 8;break; case 0XD0: return Key_res+ 4;break; case 0XE0: return Key_res; break; default: return 0; //无按键按下,返回0 } } } } else Key_down = 0; //按键被松开 if(Key_res) Key_down = 1; //标志按键被按下,防止重入 return Key_res; } //--------------------------------------外部中断1服务函数-----------------------------// void INT1_ISR() interrupt 2 { i = Key16_Scan(); //矩阵键盘扫描函数子程序 } //-----------------------------------矩阵键盘服务(功能)子函数-------------------// void Key16_Function(void) { EX1=0; if(i != 0) //按键按下 { switch(i) { case 1: P1=0XFE;P2=0XFF;break; case 2: P1=0XFD;P2=0XFF;break; case 3: P1=0XFB;P2=0XFF;break; case 4: P1=0XF7;P2=0XFF;break; case 5: P1=0XEF;P2=0XFF;break; case 6: P1=0XDF;P2=0XFF;break; case 7: P1=0XBF;P2=0XFF;break; case 8: P1=0X7F;P2=0XFF;break; case 9: P1=0XFF;P2=0XFE;break; case 10: P1=0XFF;P2=0XFD;break; case 11: P1=0XFF;P2=0XFB;break; case 12: P1=0XFF;P2=0XF7;break; case 13: P1=0XFF;P2=0XEF;break; case 14: P1=0XFF;P2=0XDF;break; case 15: P1=0XFF;P2=0XBF;break; case 16: P1=0XFF;P2=0X7F;break; default:P1=0X00;P2=0X00;break; } } EX1=1; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算