0.96寸OLED的HAL库的硬件I2C移植

文章讲述了作者将STM32项目从使用软件I2C控制OLED升级到使用HAL库的硬件I2C,包括修改命令发送、数据传输函数,以及移植江协科技的OLED模块新功能,如显示字符和字符串的图像化。同时提到了OLED_Clear方法和处理中文编码的问题。

在跟着我未曾谋面的恩师——江协科技学习STM32时,学到OLED这一块的时候使用的是标准库下的软件I2C。但我现在工作基本都是使用HAL库,而且硬件I2C相比与软件I2C更好配置,由此我产生了将程序移植过来的想法。

直接上打包好的连接,使用的是STM32F103C8T6的I2C1:
链接:https://pan.baidu.com/s/1SbDAPaLdGz9rS9gPA4Dkzg?pwd=1vqx
提取码:1vqx

一,修改的部分

说是移植,其实就是命令的收发由软件控制改为硬件控制。

发送命令
void OLED_SendCmd(uint8_t cmd)
{
	uint8_t sendbuf[2];
	sendbuf[0]=0x00;//写命令
	sendbuf[1]=cmd;
	HAL_I2C_Master_Transmit(&hi2c1,OLED_ADDRESS,sendbuf,2,100);
}
发送一位数据
void OLED_SendData(uint8_t data)
{
	uint8_t sendbuf[2];
	sendbuf[0]=0x40;//写数据
	sendbuf[1]=data;
	HAL_I2C_Master_Transmit(&hi2c1,OLED_ADDRESS,sendbuf,2,100);
}
发送定长数据
void OLED_SendDataByLength(uint8_t* data,uint8_t len)
{
	uint8_t sendbuf[128]={0};
	sendbuf[0]=0x40;
	for(uint8_t i=0;i<len;i++)
	{
		sendbuf[i+1]=data[i];
	}
	HAL_I2C_Master_Transmit(&hi2c1,OLED_ADDRESS,sendbuf,len+1,100);
}
设置光标
void OLED_SetCursor(uint8_t y,uint8_t x)
{
	OLED_SendCmd(0xB0|y);
	OLED_SendCmd(0x10|(x&0xF0)>>4);
	OLED_SendCmd(0x00|(x&0x0F));
}

其他的地方还做了一些小修改,比如除了显示十六进制数以外,显示其他类型的数据不需要传入长度

//显示字符串
void OLED_ShowString(uint8_t line,uint8_t column,char* str)
{
	for(uint8_t i=0;str[i]!='\0';i++)
	{
		OLED_ShowChar(line,column+i,str[i]);
	}
}
//显示十进制无符号数
void OLED_ShowNum(uint8_t line,uint8_t column,uint32_t num)
{
	uint8_t length=0;
	uint32_t tmp=num;
	while(tmp)
	{
		length++;//根据传入的数字计算显示的长度
		tmp/=10;
	}
	for(uint8_t i=0;i<length;i++)
	{
		OLED_ShowChar(line,column+i,num/OLED_Pow(10,length-i-1)%10+'0');
	}
}
//显示十进制有符号数
void OLED_ShowSignedNum(uint8_t line,uint8_t column,int32_t num)
{
	uint8_t length=0;
	int32_t tmp=num;
	uint32_t number;
	while(tmp)
	{
		length++;
		tmp/=10;
	}
	if(num>=0)
	{
		OLED_ShowChar(line,column,'+');
		number=num;
	}
	else
	{
		OLED_ShowChar(line,column,'-');
		number=-num;
	}
	for(uint8_t i=0;i<length;i++)
	{
		OLED_ShowChar(line,column+i+1,number/OLED_Pow(10,length-i-1)%10+'0');
	}
}
//显示二进制数
void OLED_ShowBinNum(uint8_t line,uint8_t column,int32_t num)
{
	uint8_t length=0;
	int32_t tmp=num;
	while(tmp)
	{
		length++;
		tmp>>=1;
	}
	for(uint8_t i=0;i<length;i++)
	{
		OLED_ShowChar(line,column+i,num/OLED_Pow(2,length-i-1)%2+'0');
	}
}

显示十六进制数的时候仍要添加长度参数

void OLED_ShowHexNum(uint8_t line,uint8_t column,int32_t num,uint8_t len)
{
	uint8_t single;
	OLED_ShowString(line,column,"0x");
	for(uint8_t i=0;i<len;i++)
	{
		single=num/OLED_Pow(16,len-i-1)%16;
		if(single<10)
		{
			OLED_ShowChar(line,column+i+2,single+'0');
		}
		else{
			OLED_ShowChar(line,column+i+2,single+'A'-10);
		}
	}
}

二,新加功能

对于up主江协科技与12月1日发布的OLED模块教学视频添加的新函数进行了移植,大部分都是直接粘的,新功能改为更加科学的修改显存数组的方式修改图片内容,调用更新函数进行显示的方法。

大部分的函数无脑cv即可,这里只说明一下有修改的函数

/*
* X:起始点的x坐标
* Y:起始点的y坐标
* Char:要显示的字符
* FontSize:显示的尺寸
*/
void OLED_ShowCharByImage(uint8_t X, uint8_t Y, char Char, uint8_t FontSize)
{
	if (FontSize == OLED_8X16)		//字体为宽8像素,高16像素
	{
		/*将ASCII字模库OLED_F8x16的指定数据以8*16的图像格式显示*/
		OLED_ShowImage(X, Y, 8, 16, OLED_F8x16[Char - ' ']);
	}
	else if(FontSize == OLED_6X8)	//字体为宽6像素,高8像素
	{
		/*将ASCII字模库OLED_F6x8的指定数据以6*8的图像格式显示*/
		OLED_ShowImage(X, Y, 6, 8, OLED_F6x8[Char - ' ']);
	}
}
/*
* X:起始点的x坐标
* Y:起始点的y坐标
* String:要显示的字符串
* FontSize:显示的尺寸	
*/
void OLED_ShowStringByLength(uint8_t X, uint8_t Y, char *String, uint8_t FontSize)
{
		uint8_t i;
	for (i = 0; String[i] != '\0'; i++)		//遍历字符串的每个字符
	{
		/*调用OLED_ShowChar函数,依次显示每个字符*/
		OLED_ShowCharByImage(X + i * FontSize, Y, String[i], FontSize);
	}
}

这两个函数在江协科技的工程中叫做OLED_ShowChar()OLED_ShowString(),由于与最开始的函数名冲突,因而对函数名进行了修改,具体功能不变

三,关于OLED_Clear()方法

  • OLED_Clear() 清空显存数组,需要配合OLED_Update()
  • OLED_ClearArea() 清空部分显存数组,需要配合OLED_Update()
  • OLED_ClearImmediately() 直接向OLED发送数据,将所有像素点写入0x00

四,OLED_ShowChinese()中遇到的问题

在这里插入图片描述
在OLED_Data.h文件中添加了编码格式的适配,我这里采用的是GB2312的编码格式,而江协科技采用的UTF-8。想要正常使用,必须用编码格式转换软件将这几个OLED文件转成你用的格式然后再添加进工程,直接使用keil中的小扳手更改编码格式再重编译是没有的,没错,我就这么犯傻了

五,涉及到的函数

在这里插入图片描述

stm32系列OLED相关中的函数是直接向OLED发送命令,不需要更新,后续更新OLED功能是通过对显存数组进行操作,需要通过OLED_Update()进行显示才会生效

六,函数注释

大部分我写的函数都没有添加注释,具体使用方法请认准本家 B站up主:江协科技。jiangxiekeji.com

### 移植0.96OLED显示屏的HAL代码 #### 准备工作 为了成功移植0.96OLED显示屏的HAL代码到不同的平台或微控制器单元(MCU),前期准备工作至关重要。这包括获取必要的驱动代码以及了解目标MCU的具体特性。 对于基于STM32系列MCU的情况,可以从LCDWiKi网站下载适用于特定型号屏幕(如0.96inch OLED Module SKU:MC096GX)的IIC驱动代码[^1]。这些资源提供了基础框架,有助于简化后续的工作流程。 #### 使用STM32CubeMX配置项目 利用STM32CubeMX工具来初始化新工程项目并设置所需的外设参数是一个高效的选择。通过此工具可以快速生成初始代码结构,并确保所选MCU的各项功能得到适当配置。特别是当涉及到硬件IIC接口时,这种方法能够显著减少手动编码的需求,提高开发效率[^4]。 #### 修改和适配现有代码 一旦拥有了初步构建好的环境,则需针对具体应用场景调整已有的源码片段。如果原版代码是按照软件方式实现IIC协议的话,在迁移到其他支持硬件IIC特性的平台上时可能需要做出相应改动;反之亦然。此外还需注意不同版本之间API差异可能导致兼容性问题的发生[^2]。 #### 测试与优化 完成上述步骤之后便进入了测试阶段。此时应该编写简单的应用程序用于验证基本显示功能是否正常运作。随着项目的推进还可以进一步探索性能调优的可能性,比如尝试改变缓冲区大小或是调整刷新率等措施以获得更佳视觉效果的同时保持较低功耗水平。 ```c // 示例:初始化OLED设备函数模板 void OLED_Init(void){ // 初始化硬件IIC或其他通信接口 HAL_I2C_MspInit(&hi2c1); // 发送命令序列启动显示器 uint8_t init_cmd[] = { /* 填入具体的初始化指令 */ }; HAL_I2C_Master_Transmit(&hi2c1, OLED_ADDRESS << 1, init_cmd, sizeof(init_cmd), HAL_MAX_DELAY); } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值