极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 153793|回复: 50

Arduino学习笔记A1 - 使用4017数字集成块扩展Arduino开关输入端

  [复制链接]
发表于 2011-9-6 00:30:40 | 显示全部楼层 |阅读模式
本帖最后由 Ansifa 于 2014-6-29 15:02 编辑

使用4017数字集成块扩展Arduino开关阵列
--用3个单片机引脚读取10个开关状态

作者注:此方法并非扩展输入脚最佳方法,如果需要大量扩展输入脚的话(几十甚至上百路),可以使用74HC165或者CD4021做shiftin。而不是本文的4017。
http://playground.arduino.cc/Code/ShiftRegSN74HC165N
http://www.arduino.cc/en/Tutorial/ShiftIn



使用Arduino做制作,需要有一组开关控制Arduino状态。但是Arduino引脚不多,传统接法开关多了要占用很多引脚。减少引脚的方法有很多,可以选矩阵方式,编码器方式,还有本文要介绍的分时复用开关法等。

特点:十个开关占用三个数据引脚,之后每增加十个开关就增加一个引脚。
4017是一块十进制计数器,每输入一个CLK脉冲,Q0~Q9轮流产生高电平。每时刻有且只有一个引脚高电平。
二极管防止多个开关闭合时,有的输出端输出高电平,有的输出低电平,互相接上的话,会低电平引脚会干扰高电平脚的工作。
开关用10路拨动式小型开关,或者自己选择其他开关形式。

电路工作原理:
  • 先在RST(4017的复位脚MR)发出一个脉冲,使4017复位。
  • 此时有且只有Q0输出高电平(Q0对应开关S1,Q9对应开关S10),读取一次输出信号DATA。如果第一个开关S1闭合了,应该DATA得到高电平;如果S1断开了,就DATA得到低电平。此时记DATA结果对应第一个开关S1的状态。
  • 给CLK输出一个脉冲,让4017移位,有且只有Q1输出高电平(Q0,Q2~Q9均为低电平)。读取DATA。得到S2状态。
  • 不断给CLK脉冲。总共给10次脉冲,让4017由Q0移动到Q9,完成一次开关遍历,每次移动获取一次DATA状态。存为S1~S10状态。

电路原理图如图:


洞洞板图(由于引脚多,不建议面包板制作。)


关于在一块Arduino上使用多块模块:每增加一块模块,可以增加十路开关(当然你也可以使用两块4017做成行列矩阵控制100个开关。不过那个就属于另外话题了)。增加的方式是将两块模块的RST,CLK,VCC,GND接在一起,接到单片机的相应引脚,然后两个模块的DATA脚分别接单片机两个IO口。

Arduino程序例子:


const int rst = 2; //板子的RST脚接Arduino的D4口(自定义)
const int clk = 3; //板子的CLK脚接Arduino的D3口(自定义)
const int data1 = 4; //板子的DATA脚接Arduino的D2口(自定义)
//const int data2 = 5; //如果有第二块板子的话,两块板子共用RST和CLK引脚。DATA接Arduino的D5口,第三块板子可以类推接D6口(自定义)
void setup()
{
Serial.begin(9600);
pinMode(rst, OUTPUT);
pinMode(clk, OUTPUT);
pinMode(data1, INPUT);
//pinMode(data2,INPUT); //如果有第二块板子的话要定义IO
}
void loop()
{
int KeyStatus[10] = {0}; //按照总开关数定义。可能要改为20,30等
digitalWrite(rst, HIGH);
delayMicroseconds(10); //所有delayMicroseconds(10);均是给4017一个反应时间。
digitalWrite(rst, LOW);
delayMicroseconds(10);
for(int i = 0; i < 10; i++)
{
KeyStatus\[i\] = digitalRead(data1);
//KeyStatus[i+10] = digitalRead(data2); //读取第二个板子的状态,地址放在i+10
digitalWrite(clk, HIGH);
delayMicroseconds(10);
digitalWrite(clk, LOW);
delayMicroseconds(10);
}

for(int i = 0; i < 10; i++) //循环打印KeyStatus数组,i<10可能要改为i<20,30等
{
Serial.print(KeyStatus\[i\]);
Serial.print("\t");
}
Serial.println();
delay(100);
}



洞洞板实物图:



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 1 +5 收起 理由
弘毅 + 5 非常好的技术贴

查看全部评分

回复

使用道具 举报

发表于 2011-9-9 10:55:29 | 显示全部楼层
受益匪浅,谢谢!!!!
回复 支持 反对

使用道具 举报

发表于 2011-9-16 10:47:50 | 显示全部楼层
好方法,讲解很清楚明白,谢谢分享。刚学会用74C922键盘编码器的用法,原来还可以用这个,想知道这个芯片遍历一次需要多少时间?
回复 支持 反对

使用道具 举报

发表于 2011-10-11 10:06:04 | 显示全部楼层
从来都是IO不够,就换IO口多的芯片,实在是太懒了.感谢分享,果断收藏.
回复 支持 反对

使用道具 举报

发表于 2012-2-17 12:28:47 | 显示全部楼层
感謝樓主分享這樣的好東西.

請問這樣的作法可以應用在哪些地方?
回复 支持 反对

使用道具 举报

发表于 2012-4-3 14:58:01 | 显示全部楼层
4017? 我查到有CD4017BE TC4017BP HCF4017BE HEF4017BP CD4017,那种是斑竹说的?
回复 支持 反对

使用道具 举报

发表于 2012-4-3 15:04:38 | 显示全部楼层
lionelg 发表于 2012-4-3 14:58
4017? 我查到有CD4017BE TC4017BP HCF4017BE HEF4017BP CD4017,那种是斑竹说的?

没看见写的是74HEF4017...
回复 支持 反对

使用道具 举报

发表于 2012-4-10 15:42:57 | 显示全部楼层
看后受益匪淺。我现在开发时也出现I/O口不够用的问题。不过按键不是相互独立的,是4*4的矩阵开关模块,有什么好办法可以扩展IO口呢,谢谢!
回复 支持 反对

使用道具 举报

发表于 2012-5-26 11:10:20 | 显示全部楼层
138芯片可扩展外部中断源,并入串出芯片可扩展并口输入,串入并出(4094、595)可扩展并口输出
回复 支持 反对

使用道具 举报

发表于 2012-5-26 11:11:06 | 显示全部楼层
具体做法大家百度一下吧,提供个思路
回复 支持 反对

使用道具 举报

发表于 2012-5-26 22:19:30 | 显示全部楼层
好思路,感谢分享!
回复 支持 反对

使用道具 举报

发表于 2012-7-6 00:01:57 | 显示全部楼层
的确是个好办法 学习了
回复 支持 反对

使用道具 举报

发表于 2012-7-16 17:23:17 | 显示全部楼层
对我这个小菜鸟,真是大开眼界
回复 支持 反对

使用道具 举报

发表于 2012-7-23 14:08:06 | 显示全部楼层
不用换芯片了,谢谢啊
回复 支持 反对

使用道具 举报

发表于 2012-8-30 16:47:01 | 显示全部楼层
请教楼主,这个可以反着用吗,就是向data发信号,而不是像现在这样只是读
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-17 07:37 , Processed in 0.074620 second(s), 33 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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