打印

*匠人做的<一条I/O,接6个按键的电路>---将老X彻底打趴下

[复制链接]
12839|56
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xuyiyi|  楼主 | 2010-3-21 16:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xuyiyi 于 2010-3-21 20:14 编辑

今天又一次拜读了老X的大作, *老x用51单片机做的VGA示波器——将匠人彻底打趴下,  再一次试图深刻理解吸收老X的技术风范,顺便也到老X的博客中去转了一圈,想寻找点新宝贝,结果发现,老X的博客 wwww.21ic.org 中有篇**:[版主原创]《两条I/O,接六个按键的电路(无附加集成块)》及配套程序

刚好昨天又一次拜读了匠人的大作《匠人手记》,心想,匠人很谦虚,老X用《两条I/O,接六个按键的电路(无附加集成块)》,而匠人书中的思想,编程思路,只需用《一条I/O,接六个按键的电路(无附加集成块)》,就可轻松搞定,就这么轻而易举的回敬了老X

*匠人用51单片机做的《一条I/O,接六个按键的电路(无附加集成块)》——将老X彻底打趴下

详情等老许再多看多抄几遍匠人的名著《匠人手记》,充分吸收匠人丰富多彩的思考问题解决问题的方式方法,再抽时间备齐实验元器件,整理后,回头咱们慢慢展开这个故事。

相关帖子

沙发
xuyiyi|  楼主 | 2010-3-21 16:06 | 只看该作者
也请21IC上元老级高手牛人,机电通吃的全才老X积极备战,再发动一场战争,再次将匠人彻底打趴下。
以后21IC每年来几次这种层次的区域性战争,还怕没人气?还怕不红火?哈哈!

使用特权

评论回复
板凳
njzt| | 2010-3-21 16:31 | 只看该作者

使用特权

评论回复
地板
hanweng| | 2010-3-21 17:04 | 只看该作者
帮顶

使用特权

评论回复
5
不亦心| | 2010-3-21 17:20 | 只看该作者

使用特权

评论回复
6
呆板书生| | 2010-3-21 17:22 | 只看该作者
IO引脚对于现在来说,已经意义是否那么大呢?

如果连二极管也不加,那就真正牛B

使用特权

评论回复
7
sj_dai| | 2010-3-21 18:50 | 只看该作者

搜了一下,这是用两条IO的电路图,具体代码见下
//6keyfor2io.c
//
//昨日网友啊龙发布了一个《两条I/O,接六个按键的电路(无附加集成块)》
//思路非常巧妙,仅用2个IO就可区分出无键和6个单独按键共7种状态,
//不过论坛上好像有许多人没搞清怎么去区分出这些状态,
//故针对该电路写了个配套的按键检测程序,希望大家喜欢!
//如有疑问也可发送邮件至:xwjfile@21cn.com讨论
//                                  xwj    2006/06/16
#i nclude <REG52.H>
#define uchar unsigned char
sbit IO1=P1^6;
sbit IO2=P1^7;
uchar keybuf,keydat;
bit bkeyok;
void delay_us(unsigned int n)
{
    while(--n);
}
void delay_ms(unsigned int n)
{
    do
    {
        delay_us(1000);
    }
    while(--n);
}
bit scan_key(void)
{
    uchar tempkey;
    IO1=1;IO2=1;
    if(!IO1)
    {
        if (!IO2)
            tempkey=3;
        else
            tempkey=2;
    }
    else
    {
        if (!IO2)
            tempkey=1;
        else
        {
            IO1=0;
            if (!IO2)
            {
                IO1=1;IO2=0;
                if (!IO1)
                    tempkey=4;
                else
                    tempkey=6;
            }
            else
            {
                IO1=1;IO2=0;
                if (!IO1)
                    tempkey=5;
                else
                    tempkey=0;
            }
               
        }
    }
    IO1=1;IO2=1;
    if((keybuf !=0) && (keybuf == tempkey))
    {
        bkeyok=1;
        keydat=tempkey;
    }
    keybuf=tempkey;
    return(bkeyok);
}
uchar read_key(void)
{
    bkeyok=0;
    return(keydat);
}
void doanything(uchar key)
{
    //----------按键处理只有有按键并正确消抖时才会进入,功能自己随便写
    ;            
}
void main(void)
{
    while(1)
    {
        if(scan_key())
            doanything(read_key());
        delay_ms(10);
    }
}

使用特权

评论回复
8
sj_dai| | 2010-3-21 19:08 | 只看该作者
看到这样的帖子总有点手痒,说点个人的看法

****首先这个方法确实非常巧妙,很有创意****

我没有针对代码进行详细分析,好像是先由上拉电阻判断S1和S2有没有按下,再看S3,S3会让两个IO输入都读到0,最后通过IO1和IO2之间能够传递的高电平关系判断其余的键。

在我看来觉得存在一些问题:
1.系统对电路安全性考虑存在不足,比如S1按下,程序让IO1输出高电平,这样会让IO1输出的高直接短路到地,程序最好先读IO1和IO2状态,如果为低,直接判断为S1和S2有按下返回,不执行输出高电平的操作。
2.在更改IO1和IO2的输出状态后有立刻去读输入状态,这样延时时间等于代码执行时间,有可能时间不足以让输出状态稳定,最好加适当延时操作或注释清楚。

使用特权

评论回复
9
sj_dai| | 2010-3-21 19:21 | 只看该作者
3.D1和D2好像可以去掉,不过不能完全肯定,去掉也许会有其它影响???

暂时只有这几点看法,至于一条IO的方法,没有看到图,一下想不出是怎么实现的,这两天看能不能想出点头绪来

使用特权

评论回复
10
xuyiyi|  楼主 | 2010-3-21 19:40 | 只看该作者
看到这样的帖子总有点手痒,说点个人的看法

****首先这个方法确实非常巧妙,很有创意****

我没有针对代码进行详细分析,好像是先由上拉电阻判断S1和S2有没有按下,再看S3,S3会让两个IO输入都读到0,最后通过IO1和IO2之间能够传递的高电平关系判断其余的键。

在我看来觉得存在一些问题:
1.系统对电路安全性考虑存在不足,比如S1按下,程序让IO1输出高电平,这样会让IO1输出的高直接短路到地,程序最好先读IO1和IO2状态,如果为低,直接判断为S1和S2有按下返回,不执行输出高电平的操作。
2.在更改IO1和IO2的输出状态后有立刻去读输入状态,这样延时时间等于代码执行时间,有可能时间不足以让输出状态稳定,最好加适当延时操作或注释清楚。sj_dai 发表于 2010-3-21 19:08


老许完全赞同你的观点,《两条I/O,接六个按键的电路(无附加集成块)》方案确实存在你说的电路安全性隐患, 但匠人书中的思想,编程思路,让老许这个搞单片机搞汇编搞了近三十年的老菜鸟,也自叹不如,真是青出于蓝而胜于蓝,老许搞单片机时可能匠人还在读小学(套用匠人某一时刻发言,匠人看后请不要生气),但现在匠人的思路及思考问题、解决问题的方式方法,远远超过了老许,看了《匠人手记》,胜读十年书,随随便便地套用引用一下,便可轻松搞定,只需用《一条I/O,接六个按键的电路(无附加集成块)》电路,并且没有网友sj_dai所言的电路安全性隐患,先天存在不足的现象,匠人独特的思考问题、解决问题的方式方法,让老许敬佩万分,自叹不如,除了向匠人学习还是学习,力求深刻领悟匠人超一流的思考问题、解决问题的方式方法。

使用特权

评论回复
11
luck851| | 2010-3-21 19:56 | 只看该作者
不错

使用特权

评论回复
12
xuyiyi|  楼主 | 2010-3-21 20:00 | 只看该作者
本帖最后由 xuyiyi 于 2010-3-22 06:21 编辑
3.D1和D2好像可以去掉,不过不能完全肯定,去掉也许会有其它影响???

暂时只有这几点看法,至于一条IO的方法,没有看到图,一下想不出是怎么实现的,这两天看能不能想出点头绪来 ...
sj_dai 发表于 2010-3-21 19:21


D1和D2去掉,那S3键就失效了,因此,没法去掉。
至于一条IO的方法,引用匠人语录:
戏法人人会变,各有巧妙不同:
下面就来揭穿匠人的戏法 :

老许抄袭引用了《匠人手记》书中<手记17  用普通I/O口检测模拟值〉之章节,经老许简化后搭电路实测,略感线性差点,通过单片机内部线性修正,组成4-6位A/D转换器还是有实用价值的,更何况本案例中,识别6个按键,只需用到3位A/D转换器,因些,匠人的独特的思想、思路,思考问题、解决问题的方式方法,抄录过来直接可应用于《一条I/O,接六个按键的电路(无附加集成块)》。

使用特权

评论回复
13
牛牛特工| | 2010-3-21 20:13 | 只看该作者
本帖最后由 牛牛特工 于 2010-3-21 20:16 编辑

恩 楼上说的与我的猜测相同
使用AD检测检测电阻


使用普通IO测电阻是否是利用RC充放电来实现的?
没看过手记 仅猜猜
按键电阻那部分 串一固定电容
将IO设为输出 送高电平, 后再改为输入 电容会向电阻放电,经过时间T 电压低于阈值
利用T 与C的公式 可得出R
因为看到某些解释IO测电容的** 估计应该类似的

使用特权

评论回复
14
sj_dai| | 2010-3-21 20:23 | 只看该作者
:)
原来谜底是用ADC方法进行检测,我个人认为这个双IO的方法在构思上要更为巧妙一些,当然这只是个人感觉。

对于S3失效的问题,我没想明白呢,如果S3按下,D1和D2都是直接接地,如果是先直接读IO1和IO2,读得10表示S1按下,读得01表示S2按下,读得00表示S3按下,因为前提是不支持多个键同时按下,好像这样就能区分这三个键。

使用特权

评论回复
15
dongshan| | 2010-3-21 20:28 | 只看该作者
过于追求奇技淫巧,并不是好事情. 系统分析综合能力,才是王道.

使用特权

评论回复
16
xuyiyi|  楼主 | 2010-3-21 20:36 | 只看该作者
恩 楼上说的与我的猜测相同
使用AD检测检测电阻


使用普通IO测电阻是否是利用RC充放电来实现的?
没看过手记 仅猜猜
按键电阻那部分 串一固定电容
将IO设为输出 送高电平, 后再改为输入 电容会向电阻放电,经过 ...
牛牛特工 发表于 2010-3-21 20:13


牛牛特工就是牛!一眼就看穿匠人的小把戏。

使用特权

评论回复
17
牛牛特工| | 2010-3-21 20:41 | 只看该作者
本帖最后由 牛牛特工 于 2010-3-21 20:42 编辑

:curse:
其实真费事 可以把这些东西给整到芯片里去 像是触摸按键IC
同意15楼

使用特权

评论回复
18
xuyiyi|  楼主 | 2010-3-21 20:58 | 只看该作者
过于追求奇技淫巧,并不是好事情. 系统分析综合能力,才是王道.
dongshan 发表于 2010-3-21 20:28


说的有理,我们还是多学习学习匠人、老X的系统分析综合能力, 才是王道.

使用特权

评论回复
19
itelectron| | 2010-3-21 21:28 | 只看该作者
51 可没有  AD   属于 投机呵呵

使用特权

评论回复
20
dongshan| | 2010-3-21 21:29 | 只看该作者
说的有理,我们还是多学习学习匠人、老X的系统分析综合能力, 才是王道.
xuyiyi 发表于 2010-3-21 20:58


只怕他们不肯传授啊. 在这里能见到许老板,有幸,有幸!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

2448

帖子

6

粉丝