找回密码
 立即注册
楼主: 朱家臣

单片机按键

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:460
  • 最近打卡:2025-05-03 07:38:35
已绑定手机
已实名认证

110

主题

2224

回帖

5470

积分

版主

积分
5470
发表于 2023-9-28 10:23:55 | 显示全部楼层
朱*** 发表于 2023-9-27 18:37
论如何也要谢谢王工这几天解答

不客气,我也学习了到新的电路设计
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:495
  • 最近打卡:2025-05-03 07:45:19

30

主题

347

回帖

3484

积分

荣誉版主

积分
3484
发表于 2023-10-21 20:37:20 | 显示全部楼层
本帖最后由 浦江一水 于 2023-10-21 20:57 编辑

偶尔看到了此帖, 发觉电路设计是有点巧妙之处.
而且谈论的话题时间还不算久远. 参与一下, 谈谈我的理解看法...

根据楼主给出的部分电路图看, 估计是在剖析一个成品电路板, 测绘电路时重新绘制电原理图.
可能存在一点遗漏(错误)使人误解(看不懂)了.

我的判断是从数码管开始推测...

首先是二组共阳极的三位数码管模块,组成6位数码管显示.6个9012三级管(PNP),分别控制对每位数码管阳极供电.
这6个三级管的集电极是连在一起的, 估计是测绘时漏掉了, 应该是还要接VCC电源正极的.

现以第一位数码管Q11和第一个发光二极管D1为例来分析...
当P1.0为高电平时Q11三极管导通,可给第一位数码管供电,(如果此时P1.6为低电平,那么D1发光管也可点亮的)
如果此时P0口数据数据输出8个bit中有0电平的话,那么第一个数码管就有笔划(段)显示点亮了...
其它三级管和发光管依次类推, 道理是一样的...

如果P1.0到P1.6的输出都是低电平0, 那么6个三级管都是不导通的, 由此可控制数码管和发光管都不会亮.

由于CPU与数码管之间没有其它电路芯片存在,那么可以确定,这6位数码管的显示只能是动态扫描显示方式了.

再看7个键输入是如何形成的...
很显然,CPU是读引脚P1.7电平来判断键输入的. 无论哪个键按下, 都是从读这个脚的电平来判断. 可能是开关量,也可能是模拟量...

当没有键按下时, 由于R28电阻上拉, 读回高电平1. 这是无疑的.
当P0口轮流给各位(bit)输出0电平,(一次输出只能有1个位是0,其余都必须是1)
此时从P1.7读回是低电平的话,就可判断是对应是哪个键被按下了...

这里要插叙一下P1.7端口的电压问题了. 这是要看P0口输出电阻和R28电阻(图中没标出),以及二极管D7等等是如何配置了.
大致算算,如果R28上拉电阻是10K以上,P0口每路输出接200Ω,D7等若是普通二极管,当有按键按下时,二极管导通后存在压降0.7V,
从P1.7读入电压在1V以下是有可能的.
(如果电压较高难以判断高低电平的话,那就用ADC的方法用模拟电压来判断,因为按键与不按键,返回电压是不同的)

综上所述, 这个电路, 仅用两个8位的IO口, 实现6位数码管显示、6颗发光二极管亮灭、7个按键输入的功能, 确实是有创意、有一定巧妙之处的.

那么,接下来程序该如何编写呢?硬件简单了,往往程序就要复杂了……

谈谈思路...

首先, LED数码管要实现动态扫描显示,这部分原理是需要做做功课的,已经是成熟的技术了,在此就不再赘述了.

在动态扫描显示的过程中, 每一位数码管点亮后,再移位点亮前, 是有几个ms级延时等待的, 就利用这个延时等待的间歇时间...

在 P0.0 ... P0.6 轮流有一位输出低电平(其它位高电平),轮流读P1.7的电平,
如果是高电平,没键按下,如果是低电平,那就是对应的S1...S7被按下了.

至于, D1...D6发光管的亮灭控制, 也可以是利用数码管动态扫描显示的间歇时间进行:
让P1.6位低电平,(做好点亮发光管的准备)
用P1.0 ... P1.5 来控制6个三极管供电, 点亮对应的发光二极管.

如果这思路对了, 具体的源代码就应该就好写了...

回顾楼主在13#楼的代码, 分析一下...

void main ()
{
  if( P17==0)     //如果P17是低电平...
  {
    P0=0x82;      //10000010 _GFEDC_A  段 显示6
    P1=0xfb;      //11111011   //bit7=1 为读P1.7准备,是有意义的,bit6=1 发光管不亮, 低6位111011 何意思? 第三位数码管不亮?
  }
  else
  {
    P0=0x92;      //10010010 _GF_DC_A  段 显示5
    P1=0xf7;      //11110111  //bit7=1 为读P1.7准备,是有意义的,bit6=1 发光管不亮, 低6位110111 何意思? 第四位数码管不亮?
  }
  //.....         //在此要为读P17口做准备了..... P0口多位是0了!
}

这段代码,仅仅考虑了数码管输出控制,没有考虑读P1.7之前需要做什么.
因为P0口给出的bit都有几个0电平存在, 所以无论你是否按键, 返回的键值是一样的.
按理论讲, 读P1.7返回应该是0, 但是可能由于电阻的配置, 读不到可判为0的电压(另说是5V--3.6V变化). 那么就一直返回高电平了...
那么也就使人想到,读取P1.7的状态, 很可能是根据ADC转换的电压来判断逻辑电平的了.

这是我的理解分析, 仅供参考...

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:51
  • 最近打卡:2025-05-02 10:07:51

73

主题

5883

回帖

1万

积分

超级版主

积分
12081
发表于 2023-10-23 15:22:39 | 显示全部楼层
这属于LED数码管扫描显示+按键读取的经典应用,基本每个学生初学单片都用的电路。
但楼主电路哟写错误,COM驱动的三极管C极没有接电源地。
如果按键没有多键按下,则不需要串二极管,串二极管可以多键按下。
扫描键时,COM端输出高,禁止数码管显示,然后就可以按正常的方式读取按键了。
回复 支持 反对

使用道具 举报 送花

3

主题

16

回帖

77

积分

注册会员

积分
77
发表于 2023-10-25 16:21:47 | 显示全部楼层
首先谢谢梁工的精彩的分析,的确是象你分析的哪样,但是按键按下时17角电压是3.6V
有的上STC90C52RC,如何用ADC来写程序
回复 支持 反对

使用道具 举报 送花

3

主题

16

回帖

77

积分

注册会员

积分
77
发表于 2023-10-25 16:23:17 | 显示全部楼层
梁工是哪里人
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 20:20 , Processed in 0.184029 second(s), 75 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表