Proteus仿真-点阵(实验二)

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

一、位移缓存器

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

一、管脚说明

在这里插入图片描述
管脚编号:缺口左边为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位移缓存器的工作方式后,我们可以通过它写一个流水灯的样例.
如图下,代码就不贴出了.
在这里插入图片描述

二、Matrix点阵

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

电路图
在这里插入图片描述

比如点亮第一个灯,那么第一行给出低电平,第一列给出高电平即可,按照这样的思路完成点阵实验。
前面我们已经熟悉了数码管的静态显示和动态显示,实在不懂可以看我之前发的博客,这里我就不赘述了。
要画出一个好的图形,需要用到取模软件.
我们要在实验中得到这样的一个图形.
在这里插入图片描述
Proteus仿真图如下
元器件,AT89C52,MATRIX,74HC595
在这里插入图片描述

完整代码如下.

#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;	//循环开始.
   } 
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
总的效果应该这样,由于不会截取动图,先这样了,下次学习改进.
由于刚学单片机,难免存在一些知识漏斗,请批评指正.

  • 24
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值