在我们的单片机应用系统中,常常会遇到 I/O 口不够的情况。譬如说接有外部 RAM 而且要求有 16 个以上的按键,8 位数码管以上的显示。而且还不包括其它的外围器件。这时整个系统的 I/O 资源就很吃紧了。系统的扩展性也不好。这时我们就需要考虑对单片机的 I/O 进行扩展了。
虽然专门的 I/O 扩展芯片市场上也有不少,但对于我们一般的应用,没有必要整的那么复杂。用一些简单的移位寄存器芯片一样可以实现我们的目标。下面我们首先来认识一下 74HC164 这款芯片。这款芯片的作用是把串行输入的数据并行输出。注意,它没有锁存功能,在允许输出的情况下,每一个时钟的上升沿,数据依次从最低位移向最高位。因此,在做数码管的输出显示的时候会出现拖影的想象,在设计此电路时要注意考虑此情况。
针脚 | 别名 | 说明 |
DSA DSB |
A B |
数据输入端,数据通过这两个输入端之一串行输入;任一输入端可以用作高电平使能端,控制另外一个输入端的数据输入。当其中任意一个为低电平,则禁止新数据输入;当其中有一个为高电平,则另一个就允许输入数据。因此两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。 |
Q0~Q7 | 数据输出端。 | |
CP | CLK | 时钟输入端。CP每次有低变高时,数据右移一位,输入到 Q0,Q0是两个数据输入端的逻辑与,它将上升时钟沿之前保持一个建立时间的长度。 |
MR | CLR | 复位清除端,低电平时,其它所有输入端都无效,同时所有输出端均为低电平。 |
GND | 接地端 | |
VCC | 电源端,接 +5V 电源 |
这里我们以 74HC164 驱动 LED 灯来进行说明。
当时钟信号(CP)从低电平变为高电平的时候将 DSA(B) 输入的一位数据输出到 Q0,当时钟第二次由低电平变为高电平的时候将 Q0 的数据移动到 Q1,新的数据依旧保存在 Q0。依此类推,每一个时钟周期中都有一个串行数据输入到 Q0,而其他的数据则不断往高位移动直到所有数据传输结束。如果不再有时钟周期输入,则这些数据将暂存在输出端。
备注:发送一个字节,先输入数据位最终将在Q7口输出,最后输入的数据位将在Q0口输出
如果需要有更多的输出端口,可以把多个74HC164串联起来用。串联的方法如图2所示:上一个芯片的 Q7 连接到下一个芯片的 DSA 和 DSB,以此类推理论是可以无限级联。
在驱动 LED 方面,可以 74HC164 Q0~Q7 可以直接加电阻串联 LED,但是为了增加灵活性适配各种型号的灯,这里我们采用 74HC164 驱动三极管方式,原理图如下:
备注:时钟引脚由低到高的上升沿时间不用太长,为ns级的,不需要使用延时函数
/**
* 74HC164 发送数据
* 该函数为 74HC164 发送字节的程序,该程序是先发送的是最低位
* 备注:发送一个字节,先输入数据位最终将在Q7口输出,最后输入的数据位将在Q0口输出
*
* 数据引脚为(第1脚+第2脚合并为数据引脚),第9脚为复位,通常直接接在VCC上
* 当有多片 74HC164 串联时,只有多次调用该发送程序,先发的字节将会自动溢出到下一个 74HC164
*/
void HC164_SendByte( u8 byte )
{
...
// 发送字节数据
for( i = 0; i < 8; i++ ){
// 取字节最低位
dat = byte & 0x01;
// 发送字节位
// 时钟脚上升沿一次,74HC164 会从其数据脚读取一位数据
GPIO_WriteLow(clockPort, clockPin);
dat ? GPIO_WriteHigh(dataPort, dataPin) : GPIO_WriteLow(dataPort, dataPin);
GPIO_WriteHigh(clockPort, clockPin);
// 将发送的字节右移1位
byte >>= 1;
}
}
备注:优先发送数据字节的低位或者高位没有强制规定,只要处理能正常处理正确即可
由于 74HC164 不带锁存器功能,也就是说在每移一位数据都会实时反应在输出口上,这样会导致输出口有不必要的电平变化,虽然非常短暂但是,但是有些情况下这是不允许发生的,如果对时序逻辑有要求的话。
而在上述的例子中,如果我们写一个 “跑马灯” 的程序并运行,就会非常明显的感受 LED 会有拖影。为了解决这个问题,我们可以加大三极管基级的电阻,通过增大阻值减少电流的方式减弱 LED 拖影。但是也可以使用带有锁存功能到 74HC595 芯片,具体参考《扩展IO口:移位寄存器 74HC595(含电路和程序)》
文章浏览阅读4.4w次,点赞11次,收藏56次。分类问题是人类所面临的一个非常重要且具有普遍意义的问题,我们生活中的很多问题归根到底都是分类问题。文本分类就是根据文本内容将其分到合适的类别,它是自然语言处理的一个十分重要的问题。文本分类主要应用于信息检索,机器翻译,自动文摘,信息过滤,邮件分类等任务。文本分类技术发展历史 1960-1970:那时主要通过人工+规则(关键词或者正则表达式)的方式,制定规则的人需要对某类目领域有足够的认知和了解。举_文本特征提取word2vec
文章浏览阅读1k次。本文利用libevent,实现一个C++线程池,,可自定义用户任务类,继承于任务task基类,重写任务基类的纯虚函数实现多态。比如将定义定义处理客户端的请求任务类,实现对客户端请求的并发处理。工作队列:可以理解为线程的队列,一个线程同时可以处理一个任务,空闲的线程回从任务队列取出任务执行。当工作队列空时,线程会睡眠。任务队列:用户将任务加入任务队列,然后通知工作队列,取出一个任务到线程中执行。_windows c++ 开发 客户端 libevent
文章浏览阅读3.4w次,点赞3次,收藏11次。篇一:《工作中存在的不足及改进措施》通过近一段时间的工作,反省自身,还存在许多不足和缺点,现将近期的工作、学习中存在的不足和缺点简要总结如下:1、自身的专业业务水平不高,事故应急处理能力不强.虽然通过学习和工作经验的积累,在业务水平上有了一定的提高,但业务水平和工作经验与其它老同志比还是比较低.在日常工作中偏重于日常生产工作,也忽视了自身思想素质的提高,工作中争强当先的意识不强.2、工作上满足于正..._工作不足之处及改进措施
文章浏览阅读2k次。常用的poi工具,如easy-excel,hutool读取excel是都是先将整个excel加载到内存中分析,然后再一行行遍历,当excel文件太大时读取的时间就会更长,如果我们只需要读取excel的前几行来进行预览就不能使用这种方式,应该按需读取。_java 读取大文件excel
文章浏览阅读237次。HTML_常用标签测试_html标签检测
文章浏览阅读482次。牛顿法是一种用于求解非线性方程组的迭代优化方法。其基本原理是基于泰勒级数展开和一阶导数的近似,通过不断迭代修正初始猜测解来逼近方程组的解。Fx0其中,Fxf1xf2x...fnxT是一个多元函数,xx1x2...xnT是待求解的变量向量。牛顿法的基本思想是,在当前的迭代点xk处,用一个一阶泰勒展开来近似fixfix≈fixkj1∑n∂xj∂fixk。
文章浏览阅读815次。文章目录摘要摘要_后端克里金插值分析
文章浏览阅读3.3w次,点赞10次,收藏36次。我们在 Windows 操作系统中写文档,做笔记,通常使用 Windows 自带的记事本,可是记事本不支持插入图片,创建表格等功能,从而不得不使用 Office Word。不知道大家有没有这样的感觉,使用 Office Word 写文档,效率极低,需要一边敲字,一边使用鼠标排版,比如:在文章中给团队的名字“LSGO软件技术团队”加粗,就需要先用鼠标选中这个词语,然后点击工具栏中“B”形状的工具..._有道云笔记如何建立 文档索引
文章浏览阅读137次。IP-guard 远程命令执行漏洞_ipg 漏洞
文章浏览阅读255次。2017年,全球数据泄露事件已不仅是呈翻倍的速度增长。16年的14亿条,到17年仅上半年的17亿条,这样的数据泄露规模你是否还在存在侥幸心理,就是那所谓的“怎么可能刚好落在我身上”。随着我们在工作、生活中的云化,就在今天,万物互联已经融入到我们每个人的生活中,相信在不就的将来,整个IOT时代也将会很快的到来。仔细回忆一下,今天我们所做的任何情都离不..._8,iot时代,数据安全有哪些新特征?
文章浏览阅读6.7k次,点赞47次,收藏143次。存放文本时,也可以使用Text数据类型,可以将TEXT列视为VARCHAR列,注意Text不能有默认值,大小0-2^16字节;同一查询在同一事务中多次进行,由于其它提交事务所做的修改和删除,每次返回不同的结果集,则发生不可重复读;多个连接开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据是的准确性;同一查询在同一个事务中多次执行,由于其它提交事务所做的插入操作,每次返回不同的结果集,此时发生幻读;同真是的表一样,视图包含列,其数据来自对应的真实表(基表)_mysql教程
文章浏览阅读550次,点赞10次,收藏6次。GD32官方的开发环境(基于Eclipse)的使用。_gd32e23 开发环境