51单片机使用8×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<8;i++)	//低位在前
	{
		SRCLK=0;
		if(Data & 0x01) SER=1;
		else SER=0;
		SRCLK=1;
		Data=Data>>1;
	}
	RCLK=1;
	RCLK=0;
}

三.动态刷新

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

void refresh_buff(u8 *buff)	//对应取模软件:行列式、逆向
{
	u8 i,Data=0x80;
	for(i=0;i<8;i++)	//从左到右
	{
		_74HC595_Write_Byte(buff[i]);
		P0=~Data;
		Data=Data>>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<8;i++)	//低位在前
	{
		SRCLK=0;
		if(Data & 0x01) SER=1;
		else SER=0;
		SRCLK=1;
		Data=Data>>1;
	}
	RCLK=1;
	RCLK=0;
}

void refresh_buff(u8 *buff)	//对应取模软件:行列式、逆向
{
	u8 i,Data=0x80;
	for(i=0;i<8;i++)	//从左到右
	{
		_74HC595_Write_Byte(buff[i]);
		P0=~Data;
		Data=Data>>1;
		Delay_us();	//消影
		P0=0xFF;
	}
}

refresh.h

#ifndef __REFRESH_H__
#define __REFRESH_H__

#include <STC89C5xRC.H>

#define SER P34 //串行数据输入引脚
#define RCLK P35 //存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。
#define SRCLK P36 //移位寄存器时钟引脚,上升沿时,移位寄存器中的bit数据整体后移,并接受新的bit

void refresh_buff(u8 buff[]);	//显存动态刷新函数

#endif

main.c

#include <STC89C5xRC.H>
#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 <STC89C5xRC.H>
#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<8;i++)
		{
			u8 j;
			for(j=0;j<7;j++){
				chr[j]=chr[j+1];
			}
			if(*str>64)	//大写字母
				chr[7]=letter[*str-'A'][i];
			else	//数字
				chr[7]=number[*str-'0'][i];
			memcpy(show_buff,chr,8);
			Delay_ms(100);	//修改延时时间将调整滚动速度
		}
		str++;
  }
}

//清除缓存区
void Clear_Buff(void)
{
	memset(show_buff,0,8);
}

来看看效果吧!

51单片机点阵显示滚动字符

8.整合后的代码

其实变化不大,就是一些细节的地方小改了一下而已。
这里直接贴出整个工程链接吧

  • 38
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
回答: 当出现"pull 分支报错 fatal: Need to specify how to reconcile divergent branches"的错误时,这意味着在合并分支时存在冲突,需要指定如何解决这些冲突。在SourceTree中,有几种方法可以解决这个问题。 一种方法是使用回滚提交。回滚提交是指将分支恢复到之前的某个提交状态。在SourceTree中,你可以切换到线上分支,然后找到要回滚的提交记录,右击该提交记录,选择回滚,然后点击确定即可。这样就可以将分支恢复到指定的提交状态。\[2\] 另一种方法是重置当前分支到某个提交。重置当前分支是指将当前分支的指针移动到指定的提交,丢弃之后的提交记录。在SourceTree中,你可以切换到线上分支,然后找到要重置的提交记录,右击该提交记录,选择重置,然后点击确定即可。这样就可以将当前分支重置到指定的提交状态。\[2\] 如果你只需要合并某个分支的部分代码,可以使用遴选方式。具体操作是,在开发分支的提交记录上找到要遴选到线上分支的那条提交记录,右击该提交记录,选择遴选,然后点击确定即可。这样就可以将指定的提交记录合并到线上分支中。\[3\] 希望以上解答对你有帮助。 #### 引用[.reference_title] - *1* *2* *3* [【Git】常用命令和sourceTree的使用](https://blog.csdn.net/sj13036141506/article/details/128708160)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值