0.96寸OLED12864显示汉字和图像(HAL库)

一、使用STM32CubeMx新建Keil工程

这个不详细介绍,网上一搜一大把,需要把PB8,PB9配置为开漏输出,初始电平为高电平

二、移植OLED驱动程序

我使用的是江协科技的OLED驱动程序,下载地址:0.96寸OLED显示屏_免费高速下载|百度网盘-分享无限制

下载程序源码后,选择一个版本解压

根据需要选择GB2312/UTF-8

进入Hardware目录,复制里面的四个文件,将其粘贴到自己的工程中

打开Keil工程,将这四个文件添加到工程中

添加头文件路径

需要注意的是:江协的程序是基于标准库的,要将其移植到HAL库中,只需要改动一些代码就行了

#include "stm32f1xx_hal.h" //将"stm32f10x.h"  替换为"stm32f1xx_hal.h"


void OLED_W_SCL(uint8_t BitValue)
{
	/*根据BitValue的值,将SCL置高电平或者低电平*/
	//GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)BitValue);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, (GPIO_PinState)BitValue); //把标准库的函数替换为HAL库的函数
	/*如果单片机速度过快,可在此添加适量延时,以避免超出I2C通信的最大速度*/
	//...
}

void OLED_W_SDA(uint8_t BitValue)
{
	/*根据BitValue的值,将SDA置高电平或者低电平*/
	//GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)BitValue);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, (GPIO_PinState)BitValue); //把标准库的函数替换为HAL库的函数
	/*如果单片机速度过快,可在此添加适量延时,以避免超出I2C通信的最大速度*/
	//...
}

void OLED_GPIO_Init(void)
{
	uint32_t i, j;
	
	/*在初始化前,加入适量延时,待OLED供电稳定*/
	for (i = 0; i < 1000; i ++)
	{
		for (j = 0; j < 1000; j ++);
	}

/*可以注释掉引脚配置,在STM32CubeMX中配置PB8,PB9*/
	
	/*将SCL和SDA引脚初始化为开漏模式*/
//    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//	
//	GPIO_InitTypeDef GPIO_InitStructure;
// 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
//	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
// 	GPIO_Init(GPIOB, &GPIO_InitStructure);
//	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
// 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	/*释放SCL和SDA*/
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

打开OLED.Data.h文件,检查宏定义OLED_CHN_CHAR_WIDTH的值是否正确

编译程序,如果出现这样的报错,那么就点击魔术棒→C/C++→在Misc Controls中填入--no-multibyte-chars

编译无错误

如果OLED显示中文逗号,或者,一个方框里面问号的图形,检查编码是否正确

如果还不能显示正确的文字,勾选Use MicroLIB

三、OLED显示汉字

先使用OLED显示一下你好,世界!

将程序下载到开发板中,可以看到,!的位置上显示了一个方框,内部一个问号的图形

打开OLED_Data.c文件,找到365行,发现是因为没有定义!的字模数据,所以显示了这个默认图形

打开取模软件,点击字模生成和液晶面板选项,点阵格式选择阴码,取模方式选择列行式,取模走向选择逆向,输出数制为十六进制,自定义格式选择C51格式,去掉行前缀和行后缀的花括号。

完成设置后,输入!,点击生成字模即可

把生成的字模数据复制到OLED_CF16x16数组中

可以看到,添加了!的字模数据后,!就可以显示出来了

如果想显示其他大小的汉字,比如32X32大小的汉字,可以这样做:

首先,打开取模软件,把字宽和字高设置为32,输入汉字,生成字模

然后,在OLED_Data.h文件中定义字模基本单元(结构体)

typedef struct 
{
	char Index[OLED_CHN_CHAR_WIDTH + 1];	//汉字索引
	uint8_t Data[128];						//字模数据
} ChineseCell32X32_t;

在OLED_Data.c中定义一个数组来存储汉字字模数据

不要忘记在OLED_Data.h中声明这个数组

在OLED.h中,定义两个宏,表示16X16和32X32的汉字大小

然后参考OLED_ShowChinese函数,编写OLED_ShowChinese2函数,尝试将16X16大小的汉字和32X32大小的汉字用一个函数显示出来

void OLED_ShowChinese2(int16_t X, int16_t Y, uint8_t CF_Size,char *Chinese)
{
	uint8_t pChinese = 0;
	uint8_t pIndex;
	uint8_t i;

	char SingleChinese[OLED_CHN_CHAR_WIDTH + 1] = {0};
	
	for (i = 0; Chinese[i] != '\0'; i ++)		//遍历汉字串
	{
		SingleChinese[pChinese] = Chinese[i];	//提取汉字串数据到单个汉字数组
		pChinese ++;							//计次自增
		
		/*当提取次数到达OLED_CHN_CHAR_WIDTH时,即代表提取到了一个完整的汉字*/
		if (pChinese >= OLED_CHN_CHAR_WIDTH)
		{
			pChinese = 0;		//计次归零
			
			/*遍历整个汉字字模库,寻找匹配的汉字*/
			/*如果找到最后一个汉字(定义为空字符串),则表示汉字未在字模库定义,停止寻找*/
			if(CF_Size == OLED_CF16X16)
			{
				for (pIndex = 0; strcmp(OLED_CF16x16[pIndex].Index, "") != 0; pIndex ++)
				{
					/*找到匹配的汉字*/
					if (strcmp(OLED_CF16x16[pIndex].Index, SingleChinese) == 0)
					{
						break;		//跳出循环,此时pIndex的值为指定汉字的索引
					}
				}
				
				/*将汉字字模库OLED_CF16x16的指定数据以16*16的图像格式显示*/
				OLED_ShowImage(X + ((i + 1) / OLED_CHN_CHAR_WIDTH - 1) * 16, Y, 16, 16, OLED_CF16x16[pIndex].Data);				
			}
			else if(CF_Size == OLED_CF32X32)
			{
				for (pIndex = 0; strcmp(OLED_CF32x32[pIndex].Index, "") != 0; pIndex ++)
				{
					/*找到匹配的汉字*/
					if (strcmp(OLED_CF32x32[pIndex].Index, SingleChinese) == 0)
					{
						break;		//跳出循环,此时pIndex的值为指定汉字的索引
					}
				}
				
				/*将汉字字模库OLED_CF16x16的指定数据以32*32的图像格式显示*/
				OLED_ShowImage(X + ((i + 1) / OLED_CHN_CHAR_WIDTH - 1) * 32, Y, 32, 32, OLED_CF32x32[pIndex].Data);				
			}
		}
	}
}

在OLED.h中声明这个函数

用OLED分别显示16X16大小的汉字:你好世界,32X32大小的汉字:世界你好

把程序下载到开发板上,现象如下

如果要显示其他大小的汉字也可以参照上面的方法

四、OLED显示图像

打开取模软件,点击模式→图形模式,新建图像,宽:16,高:16

绘制图像,点击鼠标左键绘制,鼠标右键取消

在OLED_Data.c中定义数组

在OLED_Data.h中声明数组

调用OLED_ShowImage函数显示图像

接下来是显示图片,我们可以用Matlab对图片进行一些处理

I = imread('OIP-C.bmp'); 
subplot(1,2,1);
imshow(I) % 显示原图
title('原图');

thresh1 = graythresh(I);
I1 = im2bw(I,thresh1); % 对图像直接进行二值化

I2 = imresize(I1,[64,64]);%调整图片大小,调整为宽64,高64

subplot(1,2,2);
imshow(I2);
title('最终图像');
imwrite(I2,'最终图像.bmp','bmp');

处理结果如下:

点击打开一个bmp图像,这样取模软件就能自动绘制出图像

点击生成字模,重复上述定义数组等步骤,最后结果如下:

下载地址:【免费】江协科技0.96寸OLED驱动函数(HAL库移植)资源-CSDN文库

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值