zl程序教程

您现在的位置是:首页 >  其它

当前栏目

8x8点阵显示图形或动态显示字符串

字符串 显示 图形 动态显示
2023-09-11 14:21:43 时间

8x8点阵

显示原理

LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列

LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以“8”字型排列而已

LED点阵屏与数码管一样,有共阴和共阳两种接法,不同的接法对应的电路结构不同

LED点阵屏需要进行逐行或逐列扫描,才能使所有LED同时显示

在这里插入图片描述

共阳接法:每一行的发光二极管的阳极引脚都是连在一起的

在这里插入图片描述

共阴接法则是每一行的发光二极管的阴极引脚是连在一起的

开发板上的点阵可以理解为从上到下的行标号分别是h,g,f,e,d,c,b,a,从左到右的列标号分别是P0_7~P0_0,a,b,c编号可以不用管,反正数据的高位在8x8点阵中是在高位部分的,即靠LCD那部分

74HC595

因为8x8点阵需要的引脚较多,为了节约单片机的IO口,用74HC595芯片实现串行输入并行输出驱动点阵

74HC595是串行输入并行输出的移位寄存器,可用3根线输入串行数据,8根线输出并行数据,多片级联后,可输出16位、24位、32位等,常用于IO口扩展。

在这里插入图片描述

//74HC595移位寄存器配置
void _595sendByte(u_char dat)
{
	unsigned char i;
	for(i = 0;i < 8;i++)
	{
		SER = dat&(0x80>>i);//从dat的高位开始取值,分别与上0x80,0x40,0x20...则可以取出对应位的值,放到SER中
		SRCLK = 1;	//每来一次上升沿,则移一个位
		SRCLK = 0;	//重新置0,为下一个上升沿作准备
	}
	RCLK1 = 1;	//待全部移位完成,RCLK来上升沿,将数据全部移到右边的端口上并行输出
	RCLK1 = 0;
}

概括来说:SER放入的是待并行输出的数据,只能一位一位放,放入后SRCLK来上升沿则将已放入的位向下移,待全部数据放入并移好位后,RCLK来上升沿将所以数据搬到端口并行输出

消隐操作

因为同样是cpu不断扫描点阵屏,所以8x8点阵也跟数码管差不多,需要在连续显示的案例中进行消影操作,确保亮灯时不会串位

可以将P0口在亮完一个数据后全置1

显示一个图形

先用取字模软件取出想要显示的图形的数据

#include <REGX52.H>
#include "Delay.h"

typedef unsigned char u_char;

sbit RCLK1 = P3^5;
sbit SRCLK = P3^6;
sbit SER = P3^4;

//待显示的图形的数据,圆脸
unsigned char icon[] = {0x3C,0x42,0x95,0x85,0x85,0x95,0x42,0x3C};	

//74HC595移位寄存器配置
void _595sendByte(u_char dat)
{
	unsigned char i;
	for(i = 0;i < 8;i++)
    {
		SER = dat&(0x80>>i);//从dat的高位开始取值,分别与上0x80,0x40,0x20...则可以取出对应位的值,放到SER中
		SRCLK = 1;	//每来一次上升沿,则移一个位
		SRCLK = 0;	//重新置0,为下一个上升沿作准备
	}
	RCLK1 = 1;	//待全部移位完成,RCLK来上升沿,将数据全部移到右边的端口上并行输出
	RCLK1 = 0;
}

/**
  * @brief图形显示
  * @param column控制列,dat控制行
  * @retval无
  */
void show_graphics(u_char column,u_char dat)
{
	_595sendByte(dat);		//控制行,595芯片并行输出数据
	P0 =~ (0X80>>column);	//控制列,根据参数选择P0的哪一位为0,当column为0,则P0 =~0x80,P0_7口为低电平
	Delay(1);			
	P0 = 0xFF;				//延时后将P0口全置1,作消影操作
}

void main()
{
	u_char i;
	SRCLK = 0;	//初始化SRCLK和RCLK为0
	RCLK1 = 0;
	while(1)
	{
		/*开发板上可以理解为从上到下是h,g,f,e,d,c,b,a,从左到右为P0_7~P0_0
		a,b,c编号可以不用管,反正数据的高位在8x8点阵中是在高位部分的,即靠LCD那部分*/
		//_595sendByte();
		for(i = 0;i < 8;i++)
		{
            /*进行快速扫描,i控制的是列,因为行的数据已经通过字模软件生成了,只要在i列的时候显示这一列的哪一行要亮,根据人眼			余晖暂留,就可看到一个图形*/
			show_graphics(i,icon[i]);
		}
	}
}

在这里插入图片描述

动态显示字符或图形

实验现象是Hello!从右往左滚动显示

#include <REGX52.H>
#include "Delay.h"

typedef unsigned char u_char;

sbit RCLK1 = P3^5;
sbit SRCLK = P3^6;
sbit SER = P3^4;

//待显示的图形的数据
//Hello!
unsigned char code icon[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
							0xFE,0x10,0x10,0x10,0xFE,0x00,0x3C,0x42,
							0x4A,0x4A,0x32,0x00,0xFE,0x02,0x02,0x00,
							0xFE,0x02,0x02,0x3C,0x42,0x42,0x42,0x3C,
							0x00,0xFD,0x00,0x00,0x00,0x00,0x00,0x00,
							0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//74HC595移位寄存器配置
void _595sendByte(u_char dat)
{
	unsigned char i;
	for(i = 0;i < 8;i++)
	{	
		SER = dat&(0x80>>i);//从dat的高位开始取值,分别与上0x80,0x40,0x20...则可以取出对应位的值,放到SER中
		SRCLK = 1;	//每来一次上升沿,则移一个位
		SRCLK = 0;	//重新置0,为下一个上升沿作准备
	}
	RCLK1 = 1;	//待全部移位完成,RCLK来上升沿,将数据全部移到右边的端口上并行输出
	RCLK1 = 0;
}

/**
  * @brief图形显示
  * @param column控制列,dat控制行
  * @retval无
  */
void show_graphics(u_char column,u_char dat)
{
	_595sendByte(dat);		//595芯片并行输出数据控制行
	P0 =~ (0X80>>column);	//根据参数选择P0的哪一位为0,当column为0,则P0 =~0x80,P0_7口为低电平
	Delay(1);			
	P0 = 0xFF;				//延时后将P0口全置1,作消影操作
}
void main()
{
	u_char i;
	u_char offset = 3;		//定义偏移量
	u_char count = 0;		//用于计数
	SRCLK = 0;				//初始化SRCLK和RCLK为0
	RCLK1 = 0;
	while(1)
	{
		for(i = 0;i < 8;i++)
		{
			show_graphics(i,icon[i+offset]);	//数据加上偏移量
		}
		count++;
		if(count > 10)	//控制滚动的速度,越小则越快
		{
			count = 0;
			offset++;
			if(offset > 35)		//防止访问数组溢出
			{
				offset = 0;
			}
		}
	}
}

在这里插入图片描述

code

在定义显示字符或图形的数据时,往往数据会比较大,如果不加其他关键字,直接定义,则保存在RAM区,而RAM的大小比较小,可能会放不下,所以可以加关键字code,把数据定义在ROM区,即flash区,但放在ROM区的数据只能读不能改,如想修改数组里的某一个值是不允许的

unsigned char code icon[] = {0xFE,0x10,0x10,0x10,0xFE,0x00,0x3C,0x42};	//将数组放在ROM区,只能读不能写

注意点

如果用单片机的引脚直接驱动这些端口(不一定是8x8点阵),而不使用芯片时,是否可行?

答案是不可行

因为单片机的引脚是弱上拉,其接了一个上拉的电阻,如果输出低电平还正常,如果输出高电平驱动能力就不够了,驱动LED灯时会很暗

解决办法:可以在单片机引脚和接收信号的引脚之间加个三极管,三极管接一个VCC,此时单片机的高电平就相当于信号,不直接驱动,而是导通三极管,用VCC的电平驱动其他引脚

在这里插入图片描述

代码地址:https://gitee.com/ONE_Day168/dynamicdisplay.git