/****************************************************
74hc595是一个串入并出移位寄存器,可以用来驱动数码管.比
较74hc164,它除了具有一个串行移位寄存器外,还有一个锁存
器.因此,它驱动数码管时,数码管不闪烁.另外,它还有一个OE
引脚.用来控制锁存器的输出,我们用一个引脚来控制它,可以
轻松实现数码管的亮灭效果.
采用四个一位数码管和四个74hc595芯片,静态显示.R1和R2是
两个跳线.插针P1是输入口,
插针从左到右分别定义为VCC(电源),GND(地),OE(输出使能),
RCLK(锁存时钟),SRCLK(移位时钟),DATA(数据输入).
P2定义与P1差不多,它是输出口,用于级连.
P1的第6针用于数据输入,接第一片74hc595的数据输入端14脚,
第一片74hc595的第9脚是串行数据输出端,我们把它接到第二
片74hc595的数据输入端14脚.依次级联下去.P2与P1前5个针定
义相同,P2的第6针接第4片74hc595的第9脚,用于级联下一个
PCB板.
我就是级连了两个四位数码管显示8位数字.
我分别试验了共阳和共阴数码管,采用两种驱动方式.一种是普
通I/O口方式;另一种是串口方式0.
74hc595移位寄存器移位时高位在前,在用普通I/O口进行移位
操作时没有问题.在用串口方式0时,由于串口方式0移位是低位
在前,所以数码表的编码与用普通I/O口进行移位操作时的编码
不同.如:共阳普通I/O口数字0的编码是0xC0(11000000b),而共
阳串口数字0的编码是0x03(00000011b).
下面是笔者的试验测试代码.
笔者用的是STC89C52RC单片机,11.0592M晶振.P1分别接VCC,GND,
P1^0,P1^1,P3^1和P3^0.串口方式必须用这两个I/O口,普通I/O
口也用这两个口.
PS:与74HC164比起来,在做这个测试的过程中发现,用普通I/O口
时没有问题,当使用串口方式时,每发送一个数字时,使用了四个
_nop_()延时,否则不能成功.
****************************************************/
#include <reg52.h>
#include <intrins.h>
#include "zh_type.h"
/* table0[]: 共阴,普通I/O口 */
uint8 code table0[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
/* table1[]: 共阳,普通I/O口 */
uint8 code table1[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/* table2[]: 共阴,串口 */
uint8 code table2[]=
{0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
/* table3[]: 共阳,串口 */
uint8 code table3[]=
{0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};
/*位定义*/
sbit send=P3^0; //I/O口方式位定义
sbit clk=P3^1; //I/O口方式位定义
sbit OE=P1^0; //定义输出端(两种方式位定义)
sbit LOCK=P1^1; //定义锁存端(两种方式位定义)
#define SERAIL_PORT
#ifdef SERAIL_PORT //串口方式0
void initUart(); //函数声明,初始化串口
//主函数
void main()
{
uint8 a[8];
uint8 i;
initUart();
for(i=0;i<8;i++) //发送8个数字
{
a[i]=table2[i];
SBUF=a[i];
_nop_();
_nop_();
_nop_();
_nop_();
}
LOCK=0;
LOCK=1; //移位结束,锁存端正脉冲
LOCK=0;
OE=0; //输出端有效
ES=0; //关闭串口中断
EA=0; //关总中断
while(1);
}
//初始化串口
void initUart()
{
SCON=0; //串口方式0
EA=1; //开总中断
ES=1; //开串口中断
TI=0; //清发送中断标志
}
//串口中断处理函数
void ser() interrupt 4
{
TI=0; //清发送中断标志
}
#else
void Display(uint8*,uint8); //显示函数声明
/*主函数*/
void main()
{
uint8 i;
uint8 a[8];
for(i=0;i<8;i++)
a[i]=i;
Display(a,8);
while(1);
}
/*显示程序*/
void Display(uint8* buff,uint8 cnt)
{
uint8 i,j,dis;
for(i=0;i<cnt;i++) //外循环,发送8个数
{
buff[i]=table0[buff[i]]; //译码
dis=buff[i];
for(j=0;j<8;j++) //内循环,发送1个数的8位
{
clk=0;
dis<<=1;
send=CY;
clk=1;
}
}
LOCK=0;
LOCK=1; //移位结束,锁存端正脉冲
LOCK=0;
OE=0; //输出端有效
}
#endif
|