Bootstrap

2021-04-22 51单片机玩转点阵

理论就不赘述了,网络上多得很,直接从仿真软件感性上操作认识点阵,首先打开ISIS仿真软件,放置一个点阵和电源与地线就可以开始了;由点阵任何一脚连线到地线,另一边对应的引脚就连接到电源,如图:点击运行看是否点亮?看到蓝色与红色的点表示电源正常但是没有任何亮点,这时对调一下电源与接地的连线或者反转一下点阵删除原来的连线后重新连接后运行可见点亮了点阵中的一个LED了,有时打开以前电路图,运行程序595驱动点阵显示全亮不显示字符,也要把点阵反转重新连接引脚。接下来连接上排另一引脚到电源试看,可见点亮了2个LED点,把上排第二引脚连线删除,连接下排第二个引脚试看,可见也点亮了2个LED点,由此可以推导出有2种接法:若要显示一个文字可以使用竖式也可以使用横式,取模软件对应的可以有这样的数据;而用横还是用竖则决定了哪一边接成数据,哪一边接成位,对应的单片机IO组就要送数据和位的信号了.

比如说要让点阵竖的一排都点亮,那么,就把下排当作数据,而上排对应的引脚就成为了位,如图;如果连接上排第二引脚到电源会怎样?仿真不伤电子元件的,可大胆一试如图;这样就点亮了2条竖线了,由此可以推导上排引脚都连接起来则整个点阵就都亮起来了,同理横式的就是反过来使用即上排为数据下排为位,因此,显示文字就有了竖式和横式,引脚的连线自上而下还是自下而上,自左而右还是自右而左后面讨论.显示文字或图像就是要控制哪些点亮哪些不亮就能组成文字或图像了.

到了这里是否有跃跃欲试的感觉?当然有了,那就来用单片机连接来控制点阵,首先连接电路如图点击运行试看没任何点亮,是因为还没有写一个字的代码,也没下载程序到单片机内,而单片机默认的引脚都是高电平的,除了P0组是开漏外,因此,P0组显示的不是红色和蓝色的,红色代表电源,蓝色代表接地.

接着找到一个字的数据,如:首先弄明白数据的类型,如边上的注释是我猜测的,事实上我也不知道这2个数组内容到底是什么,不过没关系,可以通过辅助工具看个大概这2组8个数据到底是什么,是否像注释的一样,这些数据来自问贴求问大佬为什么我的代码无法让8*8的led点阵点亮  用的是普中的板子?-编程语言-CSDN问答.

#include<reg52.h>//头文件

unsigned char code shuju[]={0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位

打开电脑上的计算器,选项到程序员,如图,那如何在计算器上输入数据查看?首先看第一组8个数据,发现有数字也有字符,通常有字符的可推断为16进制,16进制内容是这样:0123456789ABCDEF,看数组内有FE字符即可断定,当然有经验的看到数据由0x也可断定是16进制数据,想了解的0x详情的自行摆渡去,不赘述了,0x后面2个就是数据了,因此,在计算器上点击按钮F和E,当然,得先在计时器上选16进制才能数人字符,输入字符后会是什么?如图,看到的是1111 1110正好对应一组IO的8个引脚的高低电平,再输入另外的数据试看,这样一看通常就是数据组了;

当然也不急,可再看第二数组,按顺序弄3个试看,可看到其中的0在移动,由显示可推测是位控制数据.

由上查看数组,并结合点阵引脚点亮的电平,可用来确定数据送给哪组IO从而完成显示文字。由上面点亮点阵可知0(低电平)点亮的竖式,因此,可确定第一组数据送点阵上排引脚,第二组数据送点阵下排引脚,点阵上排连接单片机P2组因此写代码时送给P2,点阵下排连接单片机P3组,同理写代码时送P3。
好,大致了解并初步确定之后,新建这个单片机代码工程,复制之上代码,写一个单片机运行的空循环代码,如下。由于引用了头文件REG52因此可以直接使用IO组,不需要再写声明IO组。

#include<reg52.h>//头文件

unsigned char code shuju[]={0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位

void main()
{
	while(1)
	{
		
	}
}

精彩正式开始了,先试着送2个数组内的数据给点阵试看会如何?添加代码如下,并下载到仿真中后点击运行仿真,看到点阵都没亮,只看到点阵引脚有红色和蓝色的点。

#include<reg52.h>//头文件

unsigned char code shuju[]={0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位

void main()
{
	P2=shuju[0];
	P3=sjwei[0];
	while(1)
	{
		
	}
}


为了方便,修改代码用变量作为数组的索引,这样就改变一个变量的值也就同时改变了对数组索引的数据的使用,修改如下:

#include<reg52.h>//头文件

unsigned char code shuju[]={0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位

void main()
{
	unsigned char b=1;
	P2=shuju[b];
	P3=sjwei[b];
	while(1)
	{
		
	}
}

编译代码工程后下载到仿真,运行:

鹅鹅,这回看到点阵显示2个点了,哈哈,同时由之上的试验可以对比到为何出现2个点看计算器的BF和82图片,接下来把代码移动到循环内运行8个数据,看会如何?修改如下:

#include<reg52.h>//头文件

unsigned char code shuju[]={0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位

void main()
{
	unsigned char b=1;

	while(1)
	{
		P2=shuju[b];
		P3=sjwei[b];
		if(++b>7)b=0;
	}
}

编译代码工程后下载到仿真,运行:鹅鹅鹅,看到图形了,是个文字H?还是图形车轮?从演示可以看到引脚电平变化;

逐一测试问贴数据,并采用了消隐措施,看图会发现不同的地方。
 

 接下来编写3组数据循环自动切换显示:当然可以不断添加数据组。

#include<reg52.h>//头文件

unsigned char code shuju[][8]={{0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00}, {0x18,0x24,0x12,0x12,0x12,0x24,0x18,0x00}, {0x00,0x7C,0x02,0x02,0x02,0x7C,0x00,0x00}};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位

void main()
{
	unsigned char b=0, j=0, xd=0, h=0;
	unsigned int ys=0;
	while(1)
	{
		P2=shuju[j][b];
		P3=sjwei[b];
		while(++xd);//显示延时
		P3=255;//换位消隐
		if(++b>7)b=0;
		if(++ys>=1747)
		{
			ys=0;
			if((++j)>=3)j=0;
		}
	}
}

 让文字移动起来:值计算替换数组节约空间使用。

使用2片595驱动点阵:兼顾回复单片机小白求助,三个74hc595控制三个lcd1602的设计思路 - 24小时必答区 
51蛋骗鸡-玩转点阵-595级联驱动-字幕移动实例资源 - 24小时必答区

#include<reg52.h>//头文件

sbit ds=P1^0;//数据线  595的14脚
sbit shcp=P1^1;//数据输入时钟线 595的11脚
sbit stcp=P1^2;//输出存储器锁存时钟线 595的12脚
sbit mr=P1^3;//数据清零

unsigned char code shuju[]={
0x00,0x38,0x44,0x54,0x44,0x38,0x00,0x00,0x00,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x00,0x00,0x00,0x40,0x40,0x40,0x4f,0x70,0x00,
0x00,0x00,0x0c,0x14,0x24,0x7f,0x04,0x00,0x00,0x82,0x82,0xFE,0x82,0x82,0x00,0x00,0x18,0x24,0x12,0x12,0x12,0x24,0x18,0x00,
0x00,0x7C,0x02,0x02,0x02,0x7C,0x00,0x00
};//数据
unsigned char code sjwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位,用移位函数,移位运算符,数字.
unsigned int QY(unsigned char sj, unsigned char jz)
{
	return (sj-sj/jz*jz);
}
void QuDong595(unsigned char sj)
{
	unsigned char aa=8;
	while(aa--)
	{
		ds=sj>>7;sj<<=1;//十六进制数据发送
//		ds=QY(sj,2);sj/=2;//十进制数据发送
    shcp=1;//上升沿发生移位 上升沿时数据寄存器的数据锁存。
    shcp=0;
	}
	stcp=0;      
  stcp=1;//上升沿将数据送到输出锁存器   
  stcp=0;
}

void main()
{
	unsigned char b=0, j=0, xd=0, h=0;	unsigned int ys=0;
	while(1)
	{
		P2=shuju[b+j];P3=sjwei[b];
		QuDong595(shuju[b+j]);QuDong595(sjwei[b]);//%256
		while(++xd);//显示延时
		P3=255;//换位消隐
		mr=0;mr=1;
		if(++b>7)b=0;
		if(++h==0)//切换数据延时+显示延时
		if((++j)>=8*6)j=0;
		
	}
}

数据%256 QuDong595(~shuju[(7-b)+(8*8-j)]);

 数据7-b,7-b+j

利用取整特性求余提高速度,利用询问式提高速度,都能充分减少时间占用,提高时间支配能力。调换数据与位发送顺序取反。

使用硬件消隐,仿真接太多了,以至于发生不能完整显示转向去掉LED排后正常,花费很多时间排查

;