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

单片机按键

[复制链接]
  • TA的每日心情
    开心
    9 小时前
  • 签到天数: 127 天

    [LV.7]常住居民III

    36

    主题

    404

    回帖

    2087

    积分

    荣誉版主

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

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

    使用道具 举报

  • TA的每日心情
    开心
    10 小时前
  • 签到天数: 164 天

    [LV.7]常住居民III

    5

    主题

    103

    回帖

    750

    积分

    高级会员

    积分
    750
    发表于 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转换的电压来判断逻辑电平的了.

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

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    46

    主题

    3071

    回帖

    6925

    积分

    超级版主

    积分
    6925
    发表于 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, 2024-5-23 19:12 , Processed in 0.057490 second(s), 43 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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