引言:
74HC595是一个实现串行转并行功能的芯片,这也是我们51单片机学习接触到的第一个通过控制时序线完成数据输入输出的芯片,这样的芯片在以后会遇到很多,像是完成数据存储的EEPROM需要用到的I2C协议,还有完成计时功能的时钟DS1302,他们在与主机进行交互时必然需要数据的输入和读取,所以我们在输入读取时就需要控制几根由引脚控制的总线,通过控制这些总线的电平变化,我们就可以完成数据输入和读取。这些都是我自己的理解,有错误的地方希望可以得到指正。
在此之前我先讲一下在学习这些模块中需要理解的一些知识:
总线:一般的我们会有几根时钟线,其中一根数据时钟线负责暂时存放一位数据,一根输入时钟线能将数据时钟线的数据发送到寄存器,另一根总线控制整个过程。当然每个芯片都有不同,像是DS18B20温度传感器只有一根线就能完成所有操作,I2C只有两根线,而SPI则有4根线,但是总体来说一定包含了以上3个功能,或是将它们的功能分开成多根线,或是将它们功能合并从而减少线的数量。
上升沿/下降沿:上升沿即是一根线由低电平转变为高电平的的过程,而下降沿就是高电平转变为低电平的过程。在上升沿或者下降沿的过程中就可以完成数据输入或读取的操作,具体视芯片的协议时序而定。
然后74HC595这个芯片是怎样工作的呢,是怎样做到将一串数据并行同时输出的呢。下图是74HC595数据手册上给出的时序图,也就是在程序设计中,根据这个时序图我们就可以实现该芯片的功能。
首先,RCK相当于控制整个过程,在程序中先将RCK置为低电平,待数据存储完成后置为高电平完成上升沿将寄存器内的数据发送出去。SER用于暂时存储一位数据,CLK在每次下降沿会将SER数据存储在寄存器中。不过不知为何,这个时序图有点难看懂,主要思路是这样的吧,去参考代码的话更好理解吧。
接下来让我们分析一下点阵屏的原理,首先我们51单片机开发板上的点阵屏是一个8X8的一个点阵屏,点亮点阵屏的方法和led灯原理是一样的,led灯就是发光二极管嘛,当一个灯正极一边处于高电平状态负极一边处于低电平状态时,该灯会有电流通过,led灯就会发光,所以去看看原理图,控制led灯的端口是不是都是控制二极管的负极?所以在程序中,我们给一个引脚设置为0,该led灯就会发光。而点阵屏无非就是灯的数量多了一些,所以这里用到一个很神奇的控制方式:用P0端口与74HC595共同控制点阵屏。
控制方式:
P0端口和74HC595共同控制,分别是列方向控制和行方向控制。P0端口控制负极,从正方向看,P0端口是在行方向控制的,也就是说给P0端口的一个引脚赋值为0,那它对应的那一列是可以亮的,最低位在每行右方,最高位在每行左方。而74HC595控制正极,而且是纵向控制,给74HC595发送的数据中,赋值为1的对应的那一行是可以亮的,最低位在每列上方,最高位在每列下方。所以要使点阵屏的一个灯亮,需要在P0端口设置那一列的电平为低,在74HC595中设置那一行的电平为高。
PS:可以利用字模提取软件提取一个含有8个元素的数组,通过在快速地将每一列显示,形成一个字。
/*74HC595*/
#include <8051.h>
#define _nop_() __asm nop__endasm
#define CLK P3_5
#define SCK P3_6
#define SER P3_4
typedef unsigned char u8;
u8 b1[]={0xBE,0xAB,0xBE,0xAB,0x3F,0xF6,0xB3,0xBE};
u8 h1[]={0x45,0x2A,0x51,0x9D,0xF7,0x38,0x24,0x32};
u8 w1[]={0x89,0x7F,0x29,0x00,0x2A,0xFF,0x2A,0x60};
u8 k[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
void _74HC595(u8 dat);
void delay10ms(void); //误差 0us
void main(void)
{
while(1)
{
for(u8 i=0;i<8;i++)//逐列将该列并行数据输入,也就是一列一列显示,但是刷新的够快就是全部显示了
{
P0=k[i];//控制一行,将该行某一个点置为低电平,该列可以亮
_74HC595(h1[i]);//控制一列,将该列某一个点置为高电平,该列可以亮
//通过对P0端口和74HC595共同作用,P0取低电平,并行数据取高电平,对应的灯就亮
_74HC595(0x00);//消影
}
}
}
/*完成数据串行转并行的过程
其实就是将一串数据逐位存放
到寄存器中,然后一次性输出
即为并行输出。
*/
void _74HC595(u8 dat)
{
u8 i=0,j=0;
SER=0;//串行数据输入线,用来存放数据
RCK=0;//串行寄存器时钟线,进行上升沿,即由低电平到高电平的过程,将所有数据并行输出。
for(i=0;i<8;i++)
{
SER=dat>>7;
dat <<= 1;
CLK=1;//串行输入时钟,进行下降沿即可将SER中存放的数据存放到寄存器中
j++;
j++;
CLK=0;//下降沿
}
RCK=1;//进行上升沿,将8位数据输出
}
void delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
上一篇:51单片机---点亮LED灯
下一篇:如何用51单片机点亮一盏LED灯