74LS164在单片机中的使用
2015-05-12 来源:51hei
在单片机系统中,如果并行口的IO资源不够,那么我们可以使用74LS164来扩展并行IO口,节约单片机IO资源。74LS164是一个串行输入并行输出的移位寄存器,并带有清除端。
74LS164的引脚可以查看数据手册。
proteus仿真图和代码附上。
#include
#define HIGH 1
#define LOW 0
#define SEG_PORT P0
sbit DATA = P0^4;
sbit CLK = P0^5;
unsigned char Timer0IRQEvent = 0;
unsigned char Time1SecEvent = 0;
unsigned int TimeCount = 0;
unsigned char SegCurPosition = 0;
code unsigned char SegCode[10] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F};
code unsigned char SegPosition[4] = {0xFE,0xFD,0xFB,0xF7};
unsigned char SegBuf[4] = {0};
void LS164_DATA(unsigned char x)
{
if(x)
{
DATA = 1;
}
else
{
DATA = 0;
}
}
void LS164_CLK(unsigned char x)
{
if(x)
{
CLK = 1;
}
else
{
CLK = 0;
}
}
/**********************************************************
*函数名称:LS164Send
*输 入:byte单个字节
*输 出:无
*功 能:74LS164发送单个字节
***********************************************************/
void LS164Send(unsigned char byte)
{
unsigned char j;
for(j=0;j<=7;j++)
{
if(byte&(1<<(7-j)))
{
LS164_DATA(HIGH);
}
else
{
LS164_DATA(LOW);
}
LS164_CLK(LOW);
LS164_CLK(HIGH);
}
}
/**********************************************************
*函数名称:SegRefreshDisplayBuf
*输 入:无
*输 出:无
*功 能:数码管刷新显示缓存
***********************************************************/
void SegRefreshDisplayBuf(void)
{
SegBuf[0] = TimeCount%10;
SegBuf[1] = TimeCount/10%10;
SegBuf[2] = TimeCount/100%10;
SegBuf[3] = TimeCount/1000%10;
}
/**********************************************************
*函数名称:SegDisplay
*输 入:无
*输 出:无
*功 能:数码管显示数据
***********************************************************/
void SegDisplay(void)
{
unsigned char t;
SEG_PORT = 0x0F;
t = SegCode[SegBuf[SegCurPosition]];
LS164Send(t);
SEG_PORT = SegPosition[SegCurPosition];
if(++SegCurPosition >= 4)
{
SegCurPosition = 0;
}
}
/**********************************************************
*函数名称:TimerInit
*输 入:无
*输 出:无
*功 能:定时器初始化
***********************************************************/
void TimerInit(void)
{
TH0 = (65536 - 5000)/256;
TL0 = (65536 - 5000)%256;
TMOD = 0x01;
}
/**********************************************************
*函数名称:Timer0Start
*输 入:无
*输 出:无
*功 能:定时器启动
***********************************************************/
void Timer0Start(void)
{
TR0 = 1;
ET0 = 1;
}
/**********************************************************
*函数名称:PortInit
*输 入:无
*输 出:无
*功 能:I/O初始化
***********************************************************/
void PortInit(void)
{
P0 = P1 = P2 = P3 = 0xFF;
}
/**********************************************************
*函数名称:main
*输 入:无
*输 出:无
*功 能:函数主题
***********************************************************/
void main(void)
{
PortInit();
TimerInit();
Timer0Start();
SegRefreshDisplayBuf();
EA = 1;
while(1)
{
if(Timer0IRQEvent)
{
Timer0IRQEvent = 0;
if(Time1SecEvent)
{
Time1SecEvent = 0;
if(++TimeCount >= 9999)
{
TimeCount = 0;
}
SegRefreshDisplayBuf();
}
SegDisplay();
}
}
}
/**********************************************************
*函数名称:Timer0IRQ
*输 入:无
*输 出:无
*功 能:定时器中断函数
***********************************************************/
void Timer0IRQ(void) interrupt 1
{
static unsigned int cnt = 0;
TH0 = (65536 - 5000)/256;
TL0 = (65536 - 5000)%256;
Timer0IRQEvent = 1;
if(++cnt >= 200)
{
cnt = 0;
Time1SecEvent = 1;
}
}
下一篇:计数器(状态机按键检测)程序