51单片机使用8×8点阵显示心形以及各种其他图案教程

您所在的位置:网站首页 3的图案 51单片机使用8×8点阵显示心形以及各种其他图案教程

51单片机使用8×8点阵显示心形以及各种其他图案教程

2024-07-17 15:06| 来源: 网络整理| 查看: 265

文章目录 一.硬件连接二.595的使用三.动态刷新四.取模软件的使用五.显示心形完整代码六.利用定时器实时刷新显存7.显示数字与字母8.整合后的代码

一.硬件连接

我使用的是普中A3的开发板,板子已经默认连接好了,点阵的列线接到了595芯片,行线直接连接到了单片机的P0口。 在这里插入图片描述 在这里插入图片描述

二.595的使用

我只讲用到的引脚: OE:输出使能控制脚,它是低电才使能输出,所以接GND,所有你要在开发板上找到J24这个排针,用跳线帽把DE跟GND连接到一起。 RCLK:存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。此引脚连接到了单片机的P35引脚 SRCLK:移位寄存器时钟引脚,上升沿时,移位寄存器中的bit 数据整体后移,并接受新的bit。此引脚连接到了单片机的P36引脚 SER:串行数据输入引脚。此引脚连接到了单片机的P34引脚

595输出一个字节:

#define SER P34 //串行数据输入引脚 #define RCLK P35 //存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。 #define SRCLK P36 //移位寄存器时钟引脚,上升沿时,移位寄存器中的bit数据整体后移,并接受新的bit void _74HC595_Write_Byte(u8 Data) { u8 i; RCLK=0; for(i=0;i>1; } RCLK=1; RCLK=0; } 三.动态刷新

我们采用行列式的点阵刷新方式,列线从左到右依次选中,行线(595)输出对应数据。

void refresh_buff(u8 *buff) //对应取模软件:行列式、逆向 { u8 i,Data=0x80; for(i=0;i>1; Delay_us(); //消影 P0=0xFF; } } static unsigned char Love_Heart[8]={0x1C,0x22,0x42,0x84,0x84,0x42,0x22,0x1C}; //爱心图案 void main() { while(1) { refresh_buff(Love_Heart); //显示心形图案 } }

我们现在只需要写入8*8像素的图案数组就能显示出对应图形。怎么样?代码是不是很优雅简洁。

四.取模软件的使用

我们使用文字取模软件PCtoLCD2002完美版 1.首先我们选择图形模式: 2.然后点击设置图标,配置选项跟我一样,然后点确定 在这里插入图片描述

3.然后选择新建一个BMP图片 在这里插入图片描述 4.然后你就能在上面绘画啦,鼠标左键点亮,右键取消像素点。绘制好你想要的图形后点击生成字模,然后复制生成的数组到程序里面就行啦。 在这里插入图片描述

五.显示心形完整代码

refresh.c

#include "refresh.h" void Delay_us() //@11.0592MHz { u8 i; i = 50; while (--i); } void _74HC595_Write_Byte(u8 Data) { u8 i; RCLK=0; for(i=0;i>1; } RCLK=1; RCLK=0; } void refresh_buff(u8 *buff) //对应取模软件:行列式、逆向 { u8 i,Data=0x80; for(i=0;i>1; Delay_us(); //消影 P0=0xFF; } }

refresh.h

#ifndef __REFRESH_H__ #define __REFRESH_H__ #include #define SER P34 //串行数据输入引脚 #define RCLK P35 //存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。 #define SRCLK P36 //移位寄存器时钟引脚,上升沿时,移位寄存器中的bit数据整体后移,并接受新的bit void refresh_buff(u8 buff[]); //显存动态刷新函数 #endif

main.c

#include #include "refresh.h" #include "img.h" u8 show_buff[8];//显存 8byte; void main() { while(1) { refresh_buff(Love_Heart0); } }

img.h 此文件用来存放各种取模后的图形数组

/********图案/文字取模********/ //取模方式:行列式、逆向、阴码、像素8*8 static unsigned char Love_Heart0[8]={0x1C,0x22,0x42,0x84,0x84,0x42,0x22,0x1C};/*"空心图形",0*/ static unsigned char Love_Heart1[8]={0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C};/*"实心图形",1*/

显示效果:我对你是实心的哦!哈哈哈 在这里插入图片描述

这样你就能显示你想要显示的任何图案啦!img.h里面有我做好的一个空心和实心图案,如果我想实现一个空心实心转换的动画,需要怎么做呢?

六.利用定时器实时刷新显存

由于我们使用的是STC89C52RC单片机,RAM大小512byte,ROM大小8K,创建一个8byte的数组用来当显存完全够了哈!然后这个系列单片机有定时器2,我们就用定时器2中断实时刷新显存。

先初始化配置定时器2,打开定时器2中断,每5ms中断一次,在中断服务函数里面执行refresh_buff(show_buff);函数,这样显存(点阵)刷新率就有200HZ。现在我们只需要在主循环里面把要显示的图案复制到显存就行。

u8 show_buff[8];//创建一个显存 8byte; //5ms 定时器2中断,动态刷新显存,刷新率200HZ void Timer2_Isr(void) interrupt 5 { TF2 = 0; refresh_buff(show_buff); //动态刷新显存 } void Timer2_Init(void) { T2MOD = 0; //初始化模式寄存器 T2CON = 0; //初始化控制寄存器 TL2 = 0x00; //设置定时初始值 TH2 = 0xEE; //设置定时初始值 RCAP2L = 0x00; //设置定时重载值 RCAP2H = 0xEE; //设置定时重载值 TR2 = 1; //定时器2开始计时 ET2 = 1; //使能定时器2中断 EA=1; }

main.c文件需要引入string.h头文件,主要用到他里面的memcpy()函数,实现内存复制。

#include #include "string.h" //memcpy() #include "refresh.h" #include "img.h" u8 show_buff[8];//显存 8byte; void Delay500ms() //@11.0592MHz { unsigned char data i, j, k; i = 4; j = 129; k = 119; do { do { while (--k); } while (--j); } while (--i); } void main() { Timer2_Init(); while(1) { memcpy(show_buff,Love_Heart0,sizeof(Love_Heart0)); //复制空心图案到显存 Delay500ms(); memcpy(show_buff,Love_Heart1,sizeof(Love_Heart1)); //复制实心图案到显存 Delay500ms(); } }

最终实现的效果,这不赶紧把.hex文件发给你正在学51单片机的女朋友?发完女朋友想分手别来找我哈,哈哈哈哈。

51单片机点阵显示动态心形

51单片机点阵显示动画心动

7.显示数字与字母

其实实现了显存动态刷新后,咱们可以自定义封装很多函数了,本质都是在8*8像素的白纸上画画嘛,比如封装一个显示字母的函数,封装一个滚动显示字符串的函数等等。

这个过程对你以后学习OLED,LCD屏幕很有帮助哦,因为原理都差不多的。

本来想对所有ASCII字符进行取模,由于RAM空间太小了放不下,只能把数字放到内部RAM,大写字母放到外部RAM中。

/********图案/文字取模********/ //取模方式:行列式、逆向、阴码、像素8*8 static unsigned char Love_Heart0[8]={0x1C,0x22,0x42,0x84,0x84,0x42,0x22,0x1C};/*"爱心图形",0*/ static unsigned char Love_Heart1[8]={0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C};/*"爱心图形",1*/ static unsigned char Love_Heart2[8]={0x00,0x1C,0x3C,0x78,0x78,0x3C,0x1C,0x00};/*"小心心",2*/ unsigned char number[][8]={ {0x00,0x7E,0x81,0x81,0x81,0x7E,0x00,0x00},/*"0",0*/ {0x00,0x00,0x82,0xFF,0x80,0x00,0x00,0x00},/*"1",1*/ {0x00,0xC6,0xA1,0x91,0x89,0x86,0x00,0x00},/*"2",2*/ {0x00,0x42,0x81,0x89,0x89,0x76,0x00,0x00},/*"3",3*/ {0x00,0x30,0x28,0xA6,0xFF,0xA0,0x00,0x00},/*"4",4*/ {0x00,0x5F,0x89,0x89,0x89,0x71,0x00,0x00},/*"5",5*/ {0x00,0x7C,0x92,0x89,0x89,0x72,0x00,0x00},/*"6",6*/ {0x00,0x00,0x01,0xF1,0x0D,0x03,0x00,0x00},/*"7",7*/ {0x00,0x76,0x89,0x89,0x89,0x76,0x00,0x00},/*"8",8*/ {0x00,0x4E,0x91,0x91,0x49,0x3E,0x00,0x00},/*"9",9*/ }; //8*8 24大小字母 unsigned char xdata letter[][8]={ {0x00,0x80,0xF8,0x27,0x3C,0xE0,0x80,0x00},/*"A",0*/ {0x00,0x81,0xFF,0x89,0x89,0x76,0x00,0x00},/*"B",1*/ {0x00,0x7E,0x81,0x81,0x81,0x43,0x00,0x00},/*"C",2*/ {0x00,0x81,0xFF,0x81,0x81,0x7E,0x00,0x00},/*"D",3*/ {0x00,0x81,0xFF,0x89,0x9D,0xC3,0x00,0x00},/*"E",4*/ {0x00,0x81,0xFF,0x89,0x1D,0x03,0x00,0x00},/*"F",5*/ {0x00,0x3C,0x42,0x81,0x91,0x73,0x10,0x00},/*"G",6*/ {0x00,0x81,0xFF,0x08,0x08,0xFF,0x81,0x00},/*"H",7*/ {0x00,0x81,0x81,0xFF,0x81,0x81,0x00,0x00},/*"I",8*/ {0x00,0x00,0x01,0x01,0xFF,0x01,0x01,0x00},/*"J",9*/ {0x00,0x81,0xFF,0x89,0x14,0xE3,0x81,0x00},/*"K",10*/ {0x00,0x81,0xFF,0x81,0x80,0x80,0xC0,0x00},/*"L",11*/ {0x81,0xFF,0x0F,0xF0,0x0F,0xFF,0x81,0x00},/*"M",12*/ {0x00,0x81,0xFF,0x8C,0x31,0xFF,0x01,0x00},/*"N",13*/ {0x00,0x7E,0x81,0x81,0x81,0x7E,0x00,0x00},/*"O",14*/ {0x00,0x81,0xFF,0x89,0x09,0x06,0x00,0x00},/*"P",15*/ {0x00,0x7E,0xA1,0xA1,0xC1,0x7E,0x00,0x00},/*"Q",16*/ {0x00,0x81,0xFF,0x89,0x19,0xE6,0x80,0x00},/*"R",17*/ {0x00,0xC6,0x89,0x89,0x91,0x63,0x00,0x00},/*"S",18*/ {0x00,0x03,0x81,0xFF,0x81,0x03,0x00,0x00},/*"T",19*/ {0x00,0x01,0x7F,0x80,0x80,0x7F,0x01,0x00},/*"U",20*/ {0x00,0x01,0x1F,0xE0,0x38,0x07,0x01,0x00},/*"V",21*/ {0x00,0x0F,0xF0,0x1F,0xF0,0x0F,0x00,0x00},/*"W",22*/ {0x00,0x81,0xE7,0x18,0xE7,0x81,0x00,0x00},/*"X",23*/ {0x00,0x01,0x8F,0xF0,0x8F,0x01,0x00,0x00},/*"Y",24*/ {0x00,0x83,0xE1,0x99,0x87,0xC1,0x00,0x00},/*"Z",25*/ };

现在封装一个显示滚动字母与数字的函数

u8 show_buff[8];//显存 8byte; //显示图片 void Show_Img(u8 *img) { memcpy(show_buff,img,8); } //显示一个字母 void Show_Char(u8 let) { u8 i=let-'A'; //获取偏移值,字母顺序按照ASCII码表 memcpy(show_buff,letter+i,8); } //显示一个数字 void Show_Num(u8 num) { memcpy(show_buff,number+num,8); } //显示滚动 大小字母混合数字串 void Show_StrNum(u8 *str) { u8 chr[8]={0}; //暂存拼接后的图形 while(*str!='\0')//判断是不是非法字符! { u8 i; for(i=0;i


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3