![]() |
lkc8210 发表于 2025-1-13 16:15 虽然可以,但是,对单片机的要求比较高,需要有下拉电阻控制器的单片机, 比如 STC8051U 系列,STC32系列等等。 IO设置为高祖, 1) 开内部下拉,关内部上拉,如果 IO = 1, 则: 接VCC的按键被按下。 2) 关内部下拉,开内部上拉,如果 IO = 0, 则: 接GND的按键被按下。 以上皆否则没有按键被按下。 然后,还有另一种双按键方案,需要单片机IO 支持强推挽输出。 IO出来,接一个电阻,然后对地电容,然后,接两个按键,按键A直接接地,按键B接一个等值电阻后接地。 IO强推挽,先充电5us, 然后,切换高阻,检测IO, IO 为 0, 则 按键 A 按下。 否则 5us 后再检测,IO 为 0 则按键B 按下, 反之 没有按键 按下。 如 判定为 按键B 按下,需要 再 充电一次复验, 防止是 在第二次检测时,实际按键A 按下。 |
lkc8210 发表于 2025-2-12 10:06 昨天查阅了IO内部电路,确实有些冒险,只在仿真中试用过,且仿真图有黄颜色的点,低压极短时间内仿真没报错,实际硬件没用过,请慎之。 |
WL0123 发表于 2025-2-8 08:33 使用你们的代码,编译通不过,报错not every exit path returns a value |
wlefa 发表于 2025-1-13 21:13 要加滤波消抖代码 ![]() |
xianfajushi 发表于 2025-2-10 21:57 ? “先赋值低电平再检测是否高” 先赋值低电平不就打开了内置对地的MOS管? 如果再按接电源正的按键不就短路? |
电路没问题,就看怎么写了,I/O口需要不断变换实时检测判断,B4高低切换,配合B2、B3设置开漏(或高阻抗输入)和标准I/O口设置切换来检测判断 |
电路图可以改一下 |
lei848200 发表于 2025-1-11 21:07 单片机的引脚又不是不能短路的,人家只检测低电平,短路没问题呀 |
lkc8210 发表于 2025-1-13 16:15 除了P0外的都可用来制作1个IO检测2个按键用,特别适合闲散IO,1个按键接地1个按键接电源,检测接地按键时IO先赋值高电平再检测是否低电平按下,同样道理检测接电源按键先赋值低电平再检测是否高电平按下即可。 |
打杂的 发表于 2025-2-7 13:47 楼主搞了快1个月还没有搞定?给你写个测试程序,肯定没有问题。如果不稳定把你电路中R5省略或改为1K
|
lkc8210 发表于 2025-1-13 16:15 可参看我的博文https://blog.csdn.net/xianfajushi/article/details/106518315 |
51hei.gif (791.92 KB, 下载次数: 0)
按照你们写的程序,实际测试按键无效。能写一个完整的程序吗?感谢,最好是51单片机,在学习,电路是没有问题,是我们之前工程师做到一个遥控器。 |
wlefa 发表于 2025-1-13 21:13 你说的“恰巧”有可能存在,也就是说上述代码确有漏洞。应该加一个限制条件,有任何按键按下才开始判读,规避“恰巧”。 char key_scan() { B4=0;B3=1;B2=1;//B4初始为0 if(!B2 || !B3)//有任何按键按下条件成立 { B4=1;//识别S1、S2 if(!B2)return 1; if(!B3)return 2; B4=0;//识别S3、S4 if(!B2)return 3; if(!B3)return 4; } return 0; } |
wlefa 发表于 2025-1-13 21:13 大概是概率低到一定程度就忽略了。 |
WL0123 发表于 2025-1-12 20:34 如果恰巧在 if(B2==0)return 1;语句之后才按下S1呢?又或者恰巧在else if(B3==0)return 2;语句后才按下S2呢?会不会出错? |
xianfajushi 发表于 2025-1-13 15:35 请问接电源的按键如何判断? |
可以进一步节省1个IO口,用2个IO口就能实现4个按键检测,2个电阻接地,2个电阻接电源,都当独立按键处理. |
IO口不够用,还不如用ADC读键值 |
本帖最后由 jjy1039 于 2025-1-15 10:10 编辑 b2=1;b3=1;b4=1; if(b2==0){ }//S1 if(b3==0){ }//S2 b2=1;b3=0;b4=1; if(b2==0){ }//S1 if(b4==0){ }//S4 b2=0;b3=1;b4=1; if(b3==0){ }//S2 if(b4==0){ }//S3 |
先b2、b3、b4都置1,此时s3、s4无效,可以读取s1和s2, 再b3置0,b2、b4置1,此时s2、s3无效,可以读取s1和s4, 再b2置0、b3、b4置1,此时s1、s4无效,可以读取s3和s2 以上缺点是,同时按下两个以上按钮,会导致误判,但是只要不同时按下两个以上,就可以使用 |
沙发的程序通过改变b4判断按键,符合电路图作者的思路,我下面还有另外一种思路,就是去掉电阻,利用改变b2和b3电平,也可以判断,而且误判可能性更小。 |
本人不才,问一下不按任何键,B2,B3读出来数据是1还是0? |
xiaobendan001 发表于 2025-1-12 14:20 如果你按着S1不放,if(B2==0)return 1;,程序已经返回,根本运行不到下面代码,只有S1和S2都没有按下才能运行到B4=0;,注意关键字return,这是基础知识。 |
B4=1,检测B2、B3是否有键按下, 有则处理按键。 没有,则B4=0,检测B2、B3是否有键按下。 |
xiaobendan001 发表于 2025-1-12 14:20 所以原代码提供者说明了实用代码需要补充完善啊,先理解一下电路和扫描按键如何编程吧 |
人中狼 发表于 2025-1-12 09:21 B4=1时,按S1我能理解,B4=0时,我按的仍然是S1,你试试这个代码返回的是几? |
xiaobendan001 发表于 2025-1-12 07:34 先看懂电路和代码再说吧 |
WL0123 发表于 2025-1-11 16:53 很明显这个不对,说下怎么完善吧 |
你这电路有问题吧?B2、B3如果不接上拉电阻,按键相当于直接短路路了。 |
这只是读键值的基本逻辑关系,实用代码需要补充完善。 char key_scan() { B4=1;B3=1;B2=1; if(B2==0)return 1; else if(B3==0)return 2; B4=0; if(B2==0)return 3; else if(B3==0)return 4; else return 0; } |