摘 要:本文介绍了一种新型的,由广州周立功单片机发展有限公司设计的键盘及数码控制芯片ZLG7289A。它是具有SPI串行接口功能的,可同时驱动8位共阴极数码管(或64只独立LED)的智能显示驱动芯片,只需一片单片机即可完成LED显示,键盘接口的全部功能。
关键词:ZLG7289A ; LED ;键盘控制 ; 串行接口
引言
现代数字式智能仪器中,人机对话配置是不可缺少的组成部分,一般来说,人对仪器状态的干预和数据输入最常用的设备是键盘,而仪器输出运行状态及运行结果最常用的是LED/LCD显示器和数码管等。
广州周立功单片机发展有限公司设计了一种新型键盘及数码管控制芯片ZLG7289A。它是具有SPI串行接口功能的可同时驱动8位共阴极数码管(或64只独立LED)的智能显示驱动芯片,该芯片同时可接多达64个键的键盘矩阵。只用单片机即可完成LED显示,键盘接口的全部功能。ZLG7289A内部含有译码器,可直接接受BCD码或16进制码,并同时具有2种译码方式。此外,还有多种控制指令,如消隐,闪烁,左移,右移等指令。ZLG7289A具有片选信号,可方便的实现多于8位的显示或多于64个键的键盘接口。
ZLG7289A技术特点:
1)串行接口,无须外围元件可直接驱动LED。
2)各位独立控制译码/不译码及消隐、闪烁功能。
3)左移、右移指令。
4)具有段寻址指令,方便控制独立LED。
5)64键键盘控制器,内含去抖动电路。
ZLG7289A引脚说明
该芯片采用28脚DIP封装,工作电压为4.5-5.5V。引脚说明见表1。
表1: ZLG7289A引脚说明(略)
指令介绍及时序图
ZLG7289A的指令结构可以分为三种类型:纯指令、带有数据的指令和读键盘数据指令。
ZLG7289A内部含有译码器,可直接接受BCD码或16进制码,并同时具有两种译码方式。
① 不带数据的纯指令。
指令结构如表2所示。指令宽度为8个bit,即微处理器需发送8个CLK脉冲。例如:复位指令,测试指令,左、右移指令,循环左、右移指令。时序图如图1所示。
表2 :不带数据的纯指令结构(略)
图1 纯指令时序图(略)
② 带有数据的指令。
指令结构如表3所示。宽度为16个bit,即微处理器需发送16个CLK脉冲。命令由两个字节组成。前半部分为指令,后半部分为数据。例如:闪烁控制、消隐控制、段点亮、关闭控制等指令。时序图如图2所示。
控制指令
表3: 带有数据的控制指令结构(略)
下载数据指令
下载数据但不译码。指令结构见表4。
表4: 下载数据但不译码的指令结构(略)
通过译码下载数据。指令结构见表5。
表5: 通过译码下载数据的指令结构(略)
图2 带有数据的指令时序图(略)
③ 读键盘数据指令
该指令从ZLG7289A读出当前的键盘代码。宽度为16个bit,前8个为微处理器发送到ZLG7289A的指令(指令结构为:D7D6D5D4D3D2D1D0=00010101),后8个bit为ZLG7289A返回的键盘代码(d7d6d5d4d3d2d1d0)。
执行此指令时,ZLG7289A的DATA端在第9个CLK脉冲的上升沿变为输出状态,并与第16个脉冲的下降沿恢复为输入状态,等待接收下一个指令。时序图如图3所示。
图3 读取键盘指令(略)
应用电路
硬件连接方法
如图4所示为ZLG7289A的电路应用原理图。单片机AT89C51的引脚P0.1-P0.4分别接到ZLG7289A的/CS,CLK,DIO,/KEY端。ZLG7289A应连接共阴极数码管。在应用中用不到的键盘和数码管可以不接。省去键盘和数码管不会影响其它部分电路的正常工作。若想增加按键,只需将ZLG7289A的18-23引脚拉出,分别接到按键上即可。在按键电路中,应有下拉电阻,以提高驱动能力。
图4 典型应用原理图(略)
ZLG7289A需要一个外接晶体振荡电路供系统工作典型值为fosc=12MHz,c=15pF。
ZLG7289A的/RET复位端在一般应用情况下可以直接和VCC相连,在需要较高可靠性的情况下,可以连接一外部复位电路或直接由微处理器控制。在上电或RESET端由低电平变为高电平后,ZLG7289A大约要经过10-15秒的时间才会进入正常工作状态。
因为芯片可直接驱动LED数码管显示,电流较大,且为动态扫描方式。为提高电路抗干扰能力、减小电源噪声干扰,应用时可在电源的正负极并入一个100
F的电容。
软件实现
ZLG7289A采用串行方式与微处理器通讯,串行数据从DATA引脚送入芯片,并由CLK端同步。当片选信号变为低电平后,DATA引脚上的数据在CLK引脚的上升沿被写入7289的缓冲寄存器。
接口程序
下面一段是实用接口程序,程序编译通过并经过验证。程序中延时程序时间控制以ZLG7289A外接12MHz晶体振荡器为准。
void p_key(void)
{
if (key==0)
{
s_buf=0x15; //有键按下
send();
receive();
a=r_buf;
cs=1;
s_buf=0xa1; //左移
send();
cs=1;
s_buf=0x81;//下载数据且译码
send();
s_buf=a;
send();
cs=1;
}
void receive(void)
{
dio=1;
rr0=8; //串行接收
goon1: clk=1;
delay(8);
CY=dio;
aa=r_buf;
aa=(aa<<1);
r_buf=aa;
clk=0;
delay(8);
rr0=rr0-1;
if (rr0==0) goto goon1;
dio=0;
}
void send(void) //串行送数
{
rr0=8;
cs=0;
delay(50);
go_on: aa=s_buf;
aa=(aa<<1);
s_buf=aa;
dio=CY;
delay(50);
clk=1;
delay(8);
clk=0;
delay(8);
rr0=rr0-1;
if (rr0!=0) goto go_on;
dio=0;
}
void delay(nn)
{
unsigned char i;
for(i=0;i<nn;i++) {;}
}
|