移位寄存器的串行扩展(74hc164)

来源:互联网 发布:linux修改当前时间 编辑:程序博客网 时间:2024/05/17 19:17

转自:http://jiancaihong.blog.hexun.com/17638422_d.html

 

1. 74HC164

74HC164是比较典型的移位寄存器,该移位寄存器有一个数据输入端口、一个时钟信号端口和八个输出端口。如图1所示。

 

查看更多精彩图片

    当时钟信号从低电平变为高电平的时候将输出一个数据到输出端D0,当时钟第二次由低电平变为高电平的时候将输出第二个数据到D0,而第一个数据将转移到D1端口。依此类推,每一个时钟周期中都有一个串行数据输出到D0,而其他的数据则不断往高位移动直到所有数据传输结束。如果不再有时钟周期输入,则这些数据将暂存在输出端。

如果需要有更多的输出端口,可以把多个74HC164串联起来用。串联的方法如图2所示。

 

查看更多精彩图片

在上图的串联电路中,左边的锁存器D7与右边锁存器的串行数据输入端连接,当左边的锁存器D0~D7数据全部输出以后,再输入一个串行信号,左边锁存器D7数据将作为右边锁存器的输入数据并从右边锁存器D0端输出,从而实现了多个字节数据的移位锁存。这样利用74HC164就实现了串行数据到并行数据的转换。

注意到在上面的两个图中,无论输出什么长度的数据,所需要的输入信号都只有两个,一个是串行数据输入,另一个是锁存器的时钟信号输入。如果我们把这两个输入端口连接到单片机的两个输出端口上,其中单片机的一个端口串行输出数据,另一个端口输出时钟信号以便控制串行数据的锁存方式,那么我们就只需要两个单片机端口几乎实现任意数量的并口输出。

2. 8051串口方式0的工作原理与时序

 

查看更多精彩图片

3 串口方式0的时序

8051串口方式0的时序如图所示,RXD(P3.0)为数据端,TXDP3.1)为同步移位脉冲端,每次串行发送、接收8位数据(一帧),低位在先。时钟为Fosc/12

(1)       发送

执行任何一条MOV SUBF,#data指令时,启动内部串行发送允许,SEND置高电平,随后在TXD同步移位时钟的作用下,将数据dataRXD端移位输出。一帧数据发送完毕时,内部发送中断请求TI有效。要再次发送一帧时,须用软件清TI

(2)       接收

在串行口控制寄存器SCON中,REN=1RI=0时,会启动一次接收过程。接收时,TXD仍为同步移位时钟输出,而串行移位数据仍从RXD移位输入。当接收完一帧后,内部接收中断请求RI有效,要再次接收一帧数据时,须用软件清零。

3. 电路原理

MCS-51单片机串行口方式0为移位寄存器方式,外接474LS164作为4LED显示器的静态显示接口,把8031RXD作为数据输出线,TXD作为移位时钟脉冲。74LS164TTL单向8位移位寄存器,可实现串行输入,并行输出。其中AB(第12脚)为串行数据输入端,2个引脚按逻辑与运算规律输入信号,共一个输入信号时可并接。T(第8脚)为时钟输入端,可连接到串行口的TXD端。每一个时钟信号的上升沿加到T端时,移位寄存器移一位,8个时钟脉冲过后,8位二进制数全部移入74LS164中。R(第9脚)为复位端,当R=0时,移位寄存器各位复0,只有当R=1时,时钟脉冲才起作用。Q1…Q8(第3-610-13引脚)并行输出端分别接LED显示器的hg···a各段对应的引脚上。在给出了8个脉冲后,最先进入74LS164的第一个数据到达了最高位,然后再来一个脉冲会有什么发生呢?再来一个脉冲,第一个脉冲就会从最高位移出,搞清了这一点,下面让我们来看电路,47LS164首尾相串,而时钟端则接在一起,这样,当输入8个脉冲时,从单片机RXD端输出的数据就进入到了第一片74LS164中了,而当第二个8个脉冲到来后,这个数据就进入了第二片74LS164,而新的数据则进入了第一片74LS164,这样,当第48个脉冲完成后,首次送出的数据被送到了最左面的164中。

 

查看更多精彩图片

4 整体原理图

4.源程序

/*************************************************************

利用中断方式进行处理

**************************************************************/

#include<reg51.h>

#define uchar unsigned char

 

sbit P3_3=P3^3;

uchar a=3;

char code tab[]={0x99,0xB0,0xA4,0xF9,0xF9,0xA4,0xB0,0x99};//4321与1234的字形码

void timer(uchar);

void int4(void);

void main(void)

{

    uchar i,j;

    SCON=0;

    EA=1;

    ES=1;

    for(;;)

    {

        P3_3=1;

        for(i=0;i<4;i++)

        {

            SBUF=tab[a];

            j=a;

            while(j==a);

        }

        P3_3=0;

        timer(100);

        if(a==255)

            a=7;

    }

}

void int4(void)interrupt 4

{

    TI=0;

    a--;

}

void timer(uchar t)

{

    uchar i;

    for(i=0;i<t;i--)

    {

        TMOD=0x01;

        TH0=10000/256;

        TL0=10000%256;

        TR0=1;

        while(!TF0);

        TF0=0;

    }

}

/*****************************************************************************/