完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
本帖最后由 JankinHuang 于 2017-9-27 19:16 编辑
我打了一个矩阵键盘的静态显示代码 但烧录进单片机后 蜂鸣器一直响个不停(蜂鸣器和矩阵键盘的IO口有同时用到) 但我怎么改都改不好 不知道哪里疏漏了 想请大神帮我看看 代码如下: #include #define uchar unsigned char #define uint unsigned int #define DIG P0 #define KEY P1 uchar code dig[17]= { 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(uint msec); void keyscan(); //子函数声明 uchar num; //定义全局变量 存储健值用于数码管显示 void main() { while(1) { keyscan(); DIG = dig[num]; } } void delay(uint msec) { uchar a,b; for(;msec>0;msec--) { for(a=38;a>0;a--) { for(b=130;b>0;b--); } } } void keyscan() { uint down = 0; KEY=0xf0; //检测列 if(KEY != 0x0f) { delay(1); //检测抖动 if(KEY != 0x0f) //0000 1111 { KEY = 0x0f; //IO口输入 switch(KEY) //IO口输出检测 { case (0x07):num=0;break; //第一列被检查出 0000 0111 case (0x0b):num=1;break; //第二列被检查出 0000 1011 case (0x0d):num=2;break; //第三列被检查出 0000 1101 case (0x0e):num=3;break; //第四列被检查出 0000 1110 } KEY = 0xf0; //检测行 1111 0000 switch(KEY) { case(0x70):num=num;break; //第一行被测出 //0111 0000 case(0xb0):num=num+4;break; //第二行被测出 //1011 0000 case(0xd0):num=num+8;break; //第三行被测出 //1101 0000 case(0xe0):num=num+12;break; //第四行被测出 //1110 0000 } while( (down<50) && (KEY != 0xf0) ) //松手检测 { delay(1); down++; } } } }
|
|
相关推荐
22个回答
|
|
|
最好能上电路图,由可能是硬件电路设计错了,蜂鸣器和键盘用共同的端口,为什么这样设计
|
|
|
|
|
|
我用的是普中的单片机 然后矩阵键盘是P1 蜂鸣器是P1.5 然后他们有给一个程序算是例子吧 那个我烧录进单片机里面蜂鸣器只会响一声 于是我就照着那个修改 但还是一直响 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
从电路图看这个电路设计有缺陷,P1.5通过ULN2003D第5通道放大驱动蜂鸣器,只有P2.5保持低电位蜂鸣器才不通电。矩阵键盘使用了P1的全部I/O,无法避免蜂鸣器误动作,建议楼主看看板子上有没有跳线帽之类的装置,可以临时改变电路结构。
|
|
|
|
|
wulinwl 发表于 2017-9-27 21:07 不知道你有没有看到我的程序 普中给的程序能够使蜂鸣器只响一声 我照着那个程序改 写的一个程序是蜂鸣器一直在响的 |
|
|
|
|
|
你的程序里没有代码。
试试把你的程序里扫描键盘先做KEY = 0xf0;的检测,再做KEY = 0x0f;的检测,就是把检测行列次序对调一下,然后按键释放判断改成判断KEY != 0x0f |
|
|
|
|
人中狼 发表于 2017-9-27 22:15 嗯行 我试试 然后 我重新上传了代码 |
|
|
|
|
人中狼 发表于 2017-9-27 22:15 调换之后已经没有之前的情况了 可是为什么会这样 普中给的程序跟我之前的顺序是一样的 可是他的并不会
|
|
|
|
|
|
没看到普中的代码,这里的电路有个问题就是驱动蜂鸣器的引脚,要看是低电平还是高电平驱动,在检测按键释放的时候,本身程序就会延时一段时间,再加上按键按下后没有释放的时间,这个整体时间会比较长,如果这时驱动蜂鸣器引脚的电平正好是能使蜂鸣器发声的电平,那么蜂鸣器就会响了,这也跟电路如何设计的有关。
|
|
|
|
|
人中狼 发表于 2017-9-27 22:50 谢谢你 代码的话我有重新上传 如果可以就帮我看看好吗 不行的话也还是谢谢你 |
|
|
|
|
|
我也用的普中的板子 好坑 看郭天祥的书 然后根据自己的板子修改程序 感觉普中的程序写的好复杂 另外我有V3.0板子的好几种程序 楼主需要吗
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include
typedef unsigned char uint8; typedef unsigned int uint16; uint8 smg[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}; void delay(uint16 i) { uint8 j,k; for(;i>0;i--) for(j=38;j>0;j--) for(k=130;k>0;k--); } uint8 keyscan() { uint8 keyvalue; P1=0x0f; if(P1!=0x0f) //检测哪一列有按键按下 { delay(2); if(P1!=0x0f) { switch(P1) { case 0x07: keyvalue=0;break; case 0x0b: keyvalue=4;break; case 0x0d: keyvalue=8;break; case 0x0e: keyvalue=12;break; } P1=0xf0; //检测哪一行有按键按下 switch(P1) { case 0x70: keyvalue=keyvalue+3;break; case 0xb0: keyvalue=keyvalue+2;break; case 0xd0: keyvalue=keyvalue+1;break; case 0xe0: keyvalue=keyvalue;break; } while(P1!=0xf0); } return keyvalue; } } void main() { uint8 key; P0=~smg[0]; while(1) { key=keyscan(); P0=~smg[key]; } } */ #include typedef unsigned char uint8; typedef unsigned int uint16; uint8 smg[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71}; void delay(uint16 i) { uint8 j,k; for(;i>0;i--) for(j=38;j>0;j--) for(k=130;k>0;k--); } /* uint8 keyscan() { uint8 value,h,l; P1=0x0f; l=P1; l=P1&0x0f; //判断那一列按下 if(l!=0x0f) { delay(1); if(l!=0x0f) { l=P1&0x0f; l=l|0xf0; //让行为高电平 P1=l; h=P1; h=h&0xf0; //判断哪一行有按键按下 l=l&0x0f; //那一列有按键按下,这条语句不可省略,否则结果出错 value=l+h; //整合行和列就是那个按键按下去的 } } return value; } */ uint8 keyscan() { uint8 value,h,l; P1=0x0f; l=P1&0x0f; if(l!=0x0f) { delay(1); if(l!=0x0f) { l=P1&0x0f; l=l|0xf0; P1=l; h=P1&0xf0; l=l&0x0f; value=h+l; } return value; } } void xianshi() { uint8 key; key=keyscan(); switch(key) { case 0xe7: P0=~smg[0];break; case 0xeb: P0=~smg[1];break; case 0xed: P0=~smg[2];break; case 0xee: P0=~smg[3];break; case 0xd7: P0=~smg[4];break; case 0xdb: P0=~smg[5];break; case 0xdd: P0=~smg[6];break; case 0xde: P0=~smg[7];break; case 0xb7: P0=~smg[8];break; case 0xbb: P0=~smg[9];break; case 0xbd: P0=~smg[10];break; case 0xbe: P0=~smg[11];break; case 0x77: P0=~smg[12];break; case 0x7b: P0=~smg[13];break; case 0x7d: P0=~smg[14];break; case 0x7e: P0=~smg[15];break; } } void main() { P0=~smg[0]; while(1) { xianshi(); } } |
|
|
|
|
|
/******************************************************************************** * 描述: * * 矩阵键盘数码管显示键值 * * 排线连接方法:JP8(P1) 与JP4(矩阵键盘接口)连接 P0与JP3(静态数码管)连接 * * 矩阵键盘定义: * * P1.1-P1.3为行线,P1.4-P1.7为列线 * * 喇叭接P1.5口 矩阵键盘P1口, * * 注意:请将JP165短路冒断开 * ********************************************************************************/ #include #define uchar unsigned char //宏的定义变量类型 uchar 代替 unsigned char #define uint unsigned int //宏的定义变量类型 uint 代替 unsigned int uchar dis_buf; //显示缓存 uchar temp; uchar key; //键顺序码 void delay(uchar x); //x*0.14MS // 此表为 LED 的字模 0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71}; /************************************************************* * * * 延时子程序 * * * *************************************************************/ void delay(uchar x) { uchar j; while((x--)!=0) //CPU执行x*12次 { for(j=0;j<125;j++) {;} } } /************************************************************* * * * 键扫描子程序 (3*4 的矩阵) P1.4 P1.5 P1.6 P1.7为列 * * P1.1 P1.2 P1.3为行 * * * *************************************************************/ void keyscan(void) { temp = 0; P1=0xF0; //高四位输入 列为高电平 行为低电平 delay(1); //延时 temp=P1; //读P1口 temp=temp&0xF0; //屏蔽低四位 temp=~((temp>>4)|0xF0); if(temp==1) // p1.4 被拉低 key=1; //第1个按键键值 else if(temp==2) // p1.5 被拉低 key=2; //第2个按键键值 else if(temp==4) // p1.6 被拉低 key=3; //第3个按键键值 else if(temp==8) // p1.7 被拉低 key=4; //第4个按键键值 else key = 16; P1=0x0F; //低四位输入 行为高电平 列为低电平 delay(1); //延时 temp=P1; //读P1口 temp=temp&0x0F; temp=~(temp|0xF0); if(temp==1) //第一行 p1.0 被拉低 key=key+0; else if(temp==2) //第二行 p1.1 被拉低 key=key+4; else if(temp==4) //第三行 p1.2 被拉低 key=key+8; else if(temp==8) //第四行 p1.3 被拉低 key=key+12; else key = 16; dis_buf = key; //键值入显示缓存 dis_buf = dis_buf & 0x0f; } /************************************************************* * * *判断键是否按下 * * * *************************************************************/ void keydown(void) { P1=0xF0; //将高4位全部置1 低四位全部置0 if(P1!=0xF0) //判断按键是否按下 如果按钮按下 会拉低P1其中的一个端口 { keyscan(); //调用按键扫描程序 } } /************************************************************* * * * 主程序 * * * *************************************************************/ main() { P0=0xFF; //置P0口 P1=0xFF; //置P1口 delay(10); //延时 while(1) { keydown(); //调用按键判断检测程序 P0 = LED7Code[dis_buf%16]&0x7f; //LED7 0x7f为小数点 共阴和共阳此处也是不一样; %16表示输出16进制 } } |
|
|
|
|
|
/*******************************************************************************
* * 普中科技 -------------------------------------------------------------------------------- * 实 验 名 : 矩阵键盘显示试验 * 实验说明 : 静态数码管显示矩阵键盘键值 * 连接方式 : 见连接图 * 注 意 : *******************************************************************************/ #include //--定义使用的IO口--// #define GPIO_DIG P0 #define GPIO_KEY P1 //--定义全局变量--// unsigned char code DIG_CODE[17]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码 unsigned char KeyValue; //用来存放读取到的键值 //--声明全局函数--// void Delay10ms(unsigned int c); //延时10ms void KeyDown(); //检测按键函数 /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main(void) { while(1) { KeyDown(); GPIO_DIG = ~DIG_CODE[KeyValue]; } } /******************************************************************************* * 函 数 名 : KeyDown * 函数功能 : 检测有按键按下并读取键值 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void KeyDown(void) { char a = 0; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f)//读取按键是否按下 { Delay10ms(1);//延时10ms进行消抖 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下 { //测试列 GPIO_KEY=0X0F; switch(GPIO_KEY) { case(0X07): KeyValue=0;break; case(0X0b): KeyValue=4;break; case(0X0d): KeyValue=8;break; case(0X0e): KeyValue=12;break; } //测试行 GPIO_KEY=0XF0; switch(GPIO_KEY) { case(0X70): KeyValue=KeyValue+3;break; case(0Xb0): KeyValue=KeyValue+2;break; case(0Xd0): KeyValue=KeyValue+1;break; case(0Xe0): KeyValue=KeyValue;break; } while((a<50) && (GPIO_KEY!=0xf0)) //检测按键松手检测 { Delay10ms(1); a++; } } } } /******************************************************************************* * 函 数 名 : Delay10ms * 函数功能 : 延时函数,延时10ms * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Delay10ms(unsigned int c) //误差 0us { unsigned char a, b; //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--// for (;c>0;c--) { for (b=38;b>0;b--) { for (a=130;a>0;a--); } } } |
|
|
|
|
|
楼主可以参考我给你发的两个程序
|
|
|
|
|
|
#include
//--定义使用的IO口--// #define GPIO_DIG P0 #define GPIO_KEY P1 //--定义全局变量--// unsigned char code DIG_CODE[17]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码 unsigned char KeyValue; //用来存放读取到的键值 //--声明全局函数--// void Delay10ms(unsigned int c); //延时10ms void KeyDown(); //检测按键函数 /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main(void) { while(1) { KeyDown(); GPIO_DIG = ~DIG_CODE[KeyValue]; } } /******************************************************************************* * 函 数 名 : KeyDown * 函数功能 : 检测有按键按下并读取键值 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void KeyDown(void) { char a = 0; GPIO_KEY=0x0f; if(GPIO_KEY!=0x0f)//读取按键是否按下 { Delay10ms(1);//延时10ms进行消抖 if(GPIO_KEY!=0x0f)//再次检测键盘是否按下 { //测试列 GPIO_KEY=0X0F; switch(GPIO_KEY) { case(0X07): KeyValue=0;break; case(0X0b): KeyValue=4;break; case(0X0d): KeyValue=8;break; case(0X0e): KeyValue=12;break; } //测试行 GPIO_KEY=0XF0; switch(GPIO_KEY) { case(0X70): KeyValue=KeyValue+3;break; case(0Xb0): KeyValue=KeyValue+2;break; case(0Xd0): KeyValue=KeyValue+1;break; case(0Xe0): KeyValue=KeyValue;break; } while((a<50) && (GPIO_KEY!=0xf0)) //检测按键松手检测 { Delay10ms(1); a++; } } } } /******************************************************************************* * 函 数 名 : Delay10ms * 函数功能 : 延时函数,延时10ms * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Delay10ms(unsigned int c) //误差 0us { unsigned char a, b; //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--// for (;c>0;c--) { for (b=38;b>0;b--) { for (a=130;a>0;a--); } } } |
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
265 浏览 0 评论
【原创】【RA4M2-SENSOR开发板评测】低功耗+USB综合测试
789 浏览 0 评论
1306 浏览 2 评论
787 浏览 0 评论
【RA4M2-SENSOR开发板评测】Analogue+Timers综合测试
1587 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
16899 浏览 31 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 23:42 , Processed in 0.973199 second(s), Total 74, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
9462