Proteus仿真-点阵(实验二)

时间:2024-03-26 16:28:04

文章借鉴https://blog.csdn.net/qq_41639829/article/details/82222753,并在基础上加以总结改进.

一、位移缓存器

74HC595是一个8位串行输入、并行输出的位移缓存器,也就是1个I/O口输入,8个I/O口输出.

一、管脚说明

Proteus仿真-点阵(实验二)
管脚编号:缺口左边为1号角,然后按照逆时针编号。

1~7脚 ,15脚(Q n):并行输出脚

8脚(GND):接地

9脚(SOUT也称Q7’):用于级联,移位寄存器中数据多于八位时,就会这八位数据送到下一个595

10脚(MR):低电平时触发,清空移位寄存器中已有数据,接高电平即可。

11脚(SH_CP):移位寄存器时钟,每一次上升沿(低电平到高电平)寄存器做一次移位,接受一位数据

12脚(ST_CP):存储寄存器时钟。上升沿时,数据从移位寄存器转存带存储寄存器

13脚(OE):595使能管脚,接低电平即可以让595输出数据

14脚(DS):输入串行数据

16脚(VCC):电源脚
注意:最先输入的数据由Q7输出

DS串行输入的数据为0111 1111
此过程为:串行数据输入时钟(11脚 SH_CP)寄存器时钟(12脚 ST_CP)为低电平,DS输入数据0;然后SH_CP变为高电平(上升沿触发),DS数据进入Q0中,紧接着SH_CP变成0,来为下一次数据输入准备。然后DS得到数据1,SH_CP再次变为高电平,Q0中的0进入Q1,1进入Q0。等八位数据进入寄存器后,SH_CP变为高电平,则可以输出数据。然后变为低电平,为下一次数据输出做准备。
1.SH_CP=0,Ds=0,SH_CP=1,Q0=Ds=0
2.SH_CP=0,Ds=1,SH_CP=1,Q1=Q0=0,Q0=Ds=1.
2.SH_CP=0,Ds=1,SH_CP=1,Q2=Q1=0,Q1=Q0=1,Q0=Ds=1.

以此类推
掌握了74HC595位移缓存器的工作方式后,我们可以通过它写一个流水灯的样例.
如图下,代码就不贴出了.
Proteus仿真-点阵(实验二)

二、Matrix点阵

在Proteus中我选择的是绿色的8x8的点阵,其类型是行共阴!

电路图
Proteus仿真-点阵(实验二)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190415204731408.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzE4NDk4,size_16,color_FFFFFF,t_70
比如点亮第一个灯,那么第一行给出低电平,第一列给出高电平即可,按照这样的思路完成点阵实验。
前面我们已经熟悉了数码管的静态显示和动态显示,实在不懂可以看我之前发的博客,这里我就不赘述了。
要画出一个好的图形,需要用到取模软件.
我们要在实验中得到这样的一个图形.
Proteus仿真-点阵(实验二)
Proteus仿真图如下
元器件,AT89C52,MATRIX,74HC595
Proteus仿真-点阵(实验二)

完整代码如下.

#include<reg52.h>
#include<intrins.h>

//intrins.h函数,一般出现在C51单片机编程中,一般程序中需要使用到空指令_nop_();字符循环移位指令_crol_等时使用
//OE	第13脚	输出有效(低电平)
//MR	第10脚	主复位(低电平)

typedef unsigned char uchar;
typedef unsigned int uint;

/*
   上面引脚控制行,行共阴,即低电平选中
   下面引脚控制列,列共阳,即高电平选中
*/

sbit SER = P3^4;    //p3.4串行数据输入   DS
sbit SCK = P3^6;    //串行输入时钟,上升沿有效    SHCP	第11脚	数据输入时钟线
sbit RCK = P3^5;    //串行寄存器时钟,上升沿有效  STCP	第12脚	输出存储器锁存时钟线

void SendTo595(uchar Data);

char shu=0xFE;			
   				 
char a[8]={0x00,0x66,0x99,0x81,0x42,0x24,0x18,0x00};//列

void delay(unsigned int n)//延时函数
{
   unsigned int i=0,j=0;
   for(i=0;i<n;i++)
       for(j=0;j<123;j++);
}

void Hang()//行扫描
{
   P1=shu;
   shu=_crol_(shu,1);
}
void main(){
   int i=0;
   RCK=0;
   while(1){
   	for(i=0;i<8;i++){
   		Hang();
   		SendTo595(a[i]);	//串行,控制列.
   		delay(3);
   	} 
   } 
}
void SendTo595(uchar Data){
   int i;
   for(i=0;i<8;i++){
   	SCK=0;
   	SER = 0x80&Data;
   	Data = _crol_(Data,1);
   	SCK=1;
   	_nop_();	//等待一个机器指令时间.
   }
   /*位移寄存器完毕,转移到存储寄存器*/
  RCK = 1;         //上升沿,存储寄存器变为高电平 延迟两个时钟周期
  _nop_();
  _nop_();
  RCK = 0;	//不加出错,因为电平不变化,存储寄存器的内容不变,为第一次输入的移位寄存器内容0x00.
}

在此基础上,实现滚动的I LOVE YOU字符.

//把原先a数组改变,把原先主函数改变替换.
char a[32]={0x3e,0x08,0x08,0x08,0x08,0x08,0x08,0x3e,
   0x00,0x66,0x99,0x81,0x42,0x24,0x18,0x00,
   0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x7e,
   0x00,0x3e,0x08,0x08,0x08,0x08,0x08,0x08} ;
   
void main(){
   int i=0,changeRow=0;
   RCK=0;
   while(1){
   	int speed=12;	  //控制速度
   	while(speed--){
   		for(i=0;i<8;i++){
   			Hang();
   			SendTo595(b[i+changeRow]);	//串行,控制列.
   			delay(4);
   		} 
   	}
   	changeRow++;	//原来的第二行,变成第一行了.
   	if (changeRow>=24)	changeRow=0;	//循环开始.
   } 
}

Proteus仿真-点阵(实验二)
Proteus仿真-点阵(实验二)

Proteus仿真-点阵(实验二)
总的效果应该这样,由于不会截取动图,先这样了,下次学习改进.
由于刚学单片机,难免存在一些知识漏斗,请批评指正.