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

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

在跟着我未曾谋面的恩师——江协科技学习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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值