资讯详情

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

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点阵类似于数字管,需要在连续显示的情况下进行消影操作,以确保亮灯时不会串联

可以将P点亮一个数据后,全置10口

显示图形

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

#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

标签: 4a05二极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台