移位寄存器74HC164在现实中的应用,或许比你想象的还要多
在现有的电子产品中,74HC164(下简称164)扮演着重要的角色。它在以下三个方面有着典型的应用:
1) 八段数码管显示
2) LED灯;
3) 按键扫描。
在其它的一些方面上也有应用,比如显示模块。但应用的原理是一样的。
164是八位并行输出移位寄存器。有两个数据输入端,一个时钟输入端,八个输出端。我们一般将两个输入端连在一起当一个输入端来用。当时钟脉冲由“0”到“1”的跳变时,触发移位,即上升沿触发。当触发时,八位并行输出的最低位Q0得到数据端的信号(DATA),原Q0的数据上移一位,即Q1,依次类推,Q6上移到Q7,Q7的数据遗失。
因此,我们充分利用这点特性,来解决单片机口线紧张的问题。使用单片机的两个I/O口,一个用作时钟(CLK),一个用作数据(DATA),通过软件模拟串行输出,经过164移位,得到并行的输出。164要求数据在CLK的上升沿之前有25ns的建立时间,上升沿之后要有5ns的保持时间。如果单片机使用4MHz的晶振,一条单字节指令的执行时间是1us,使用8MHz的晶振是0.5us,已经远远大于164要求的时间。所以在建立和保持数据上不用考虑是否164会“忙不过来”。
在八段数码管上的应用:
现在一般使用两个八位数码管,组成一个可以显示两位数的显示模块。数码管有8个信号引脚,一个片选引脚。当片选被选中,加在段码管脚上的电平有效。我们使用单片机的四个I/O口来控制这两个数码管,两个片选,一个DATA,一个CLK。
在LED显示上的应用:
还是利用串入并出的原理,只不过是希望哪一个灯亮,就对哪个灯相应的位置0(使之点亮的电平)。同时接I/O口到三极管上,实现片选。如果灯的数量小于8个则不必。这样相比将LED直接接到I/O上,需要多消耗MCU几倍甚至十几倍的执行时间,换来的是MCU口线的充分利用。
当然,如果希望有若干个灯同时亮,就由单片机的DATA发出相应位为0的串行数据,经过移位以后,使相应LED点亮。这里也存在着片选先后的问题。
和上面一样,如果先开片选再移位的话,移位速度快,几个灯等于以同样的亮度点亮;如果移位速度慢,则使小灯依次点亮。当移位完成,开片选之后,同样需要使并行数据保持一段时间,再关片选。
在按键扫描上的应用:
同样使为了节约口线,使用164进行按键扫描。一般的显示板上的按键不会超过8个,所以不用加片选信号。仅仅由单片机的一个I/O口来读按键公共端即可。原理是这样的:按键公共端经过两个电阻接VCC,两个电阻之间抽头到MCU。按键的另一段接164的Q0~Q7。
综合应用:
在产品中,大部分情况是164同时肩负着数码管,LED显示和按键扫描的任务。这些任务的协调也很重要。硬件上需要对每个应用电路都加上片选,以保证在一个器件(如数码管)使用164的时候不会干扰到其它器件;
同时按键需要加二极管以保证在显示任务的时候不会出现按键的误判(比如按键一端上是高电平,正好按键被按下,但是单片机读的是高电平,仍然按没有按下处理)。
在软件上要尽量使各个任务的时间分散,避免出现局部闪烁,或者灵敏度不高的情况。对模拟串口的程序需要尽量优化使之效率最高。在开一个片选之前需要关闭其它的片选,以防器件间的干扰,良好的习惯是使用完一个器件之后就关掉它,使用的时候再开。还有一个需要注意的问题是模拟串口程序是否可重入的问题。
虽然现在很多任务没有使用中断来调用此程序,但是不避免“意外”的情况,两个任务同时调用模拟串口程序,使寄存器数据错乱,产生错误。比较好的方法是尽量利用堆栈,而不是对同一个寄存器赋值(但同时也加大了RAM的使用量)。