电子网首页 > 开源与设计

【CW32L012】硬件IIC驱动OLED

2025-11-23 00:50 | 来源:电子世界报

【前言】

在武汉沁源的智小车上,使用的OLED驱动用的是软件模拟IIC,我这篇将分享将其代码修改为硬件IIC驱动。并在饭盒派上实现显示温度测量。

【硬件选择】

饭盒派有一个OLED接口,硬件接到了SCL(PB6),SDA(PB7),此次工程也选择这两个IO做为硬件IIC的驱动IO。

【驱动移植】

找到智能小车的驱动,把他的OLED.c/h以及字库OLED_date.c/h移植到前面我做好的温度测量工程中(详见帖子:【CW32L012】5、芯片温度值测量-电子产品世界论坛)

image.png

【代码修改】

1、将其模拟IIC的代码去除。

2、添加SCL、SDA的IO配置函数,代码如下:

void OLED_GPIO_Init(void)
{
	  GPIO_InitTypeDef GPIO_InitStructure = {0};
		/*      开启GPIOB时钟        */
    __SYSCTRL_GPIOB_CLK_ENABLE();
		
		/*      复用引脚为IIC        */
		PB06_AFx_I2C1SCL();                                            
		PB07_AFx_I2C1SDA();

		/*      配置IO的为输出模式        */
    GPIO_InitStructure.Pins = I2C1_SCL_GPIO_PIN | I2C1_SDA_GPIO_PIN;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
}

3、添加IIC初始化函数:

void OLED_I2C_Config(void)
{
	  I2C_DeInit(CW_I2C1);
	  I2C_MasterConfigTypeDef I2C_InitStruct;
    
          I2C_MasterInitDefault(&I2C_InitStruct);               // I2C初始化为默认值
	  I2C_MasterInit(CW_I2C1, &I2C_InitStruct, 96000000UL); // I2C配置
	  I2C_MasterCmd(CW_I2C1, ENABLE);                       // I2C模块使能
}

这里说明一下,武汉芯源的固件库做得非常不错,只需要把默认的结构体,与CPU工作时钟传进去,就帮配置好了。当然如何想配置更加详细的IIC总线,可以将I2C_Initstruct进行个性化的传参,达到你想要的结果。

4、修改OLED发送命令的函数。

使用过OLED(芯片为ssd1306)的都知道,发送指令的函数是在发送从机地址(0x3C),之后发送0x00,再发送指令代码,因此我编写代码如下:

void OLED_WriteCommand(uint8_t Command)
{
	uint8_t tx_buf[2];                                  
	tx_buf[0] = 0x00;        //发送command 第1位为0x00
	tx_buf[1] = Command;     //接着发送命令                              
	I2C_MasterSendDataToSlave(CW_I2C1, 0x3C, tx_buf, 2);
}

5、修改OLED发送数据的函数

发送数据,在我们发送从机地址后,跟着发送0x40,再接着发送我们需要发送的数据,因此,需要重新生成一个数组,在我们发送数据的基础上+1,然后把数据放进新数组里,再接着发送(有点浪费资源),在我的另一篇帖子里,有更加好的解决方法,详见:【分享开发笔记,赚取电动螺丝刀】OLED刷新终极优化-电子产品世界论坛

代码如下:

void OLED_WriteData(uint8_t *Data, uint8_t Count)
{
	uint8_t tx_buf[Count+1];
	tx_buf[0] = 0x40;
	for(uint8_t i=1;i<Count+1;i++)
	{
		tx_buf[i] = Data[i-1];
	}
	I2C_MasterSendDataToSlave(CW_I2C1, 0x3C, tx_buf, Count+1);
}

好了所有移植就完成啦,非常简单。

在app.c中添加oled的初始化代码,把电压值打印到屏中:

#include "app.h"
#include "bsp_adc.h"
#include "cw32l012_systick.h"
#include "cw32l012_adc.h"
#include "OLED.h"

void Run(void)
{
	uint32_t valueAdcAcc;
	uint16_t valueAdc;
	float fTsDegree, fVoltage;
	ADC_Temp_Init();
	CW_ADC1->START_f.START    = 1;                 //开始转换
	OLED_Init();
	while(1)
	{
		if(CW_ADC1->ISR_f.EOS)
		{
			valueAdc = CW_ADC1->RESULT1_f.RESULT;              //获取1.2V电压转换值
			fVoltage = ADC_BgrResult2Avcc(valueAdc);           //计算出ADD电压值
			valueAdc = CW_ADC1->RESULT0_f.RESULT;              //获取温度值计数值
			fTsDegree = ADC_GetTs(fVoltage, valueAdc);         //计算出温度
			printf("The Temperature is %2f\r\n", fTsDegree);
			printf("The Reference voltage is %2f\r\n", fVoltage);
			OLED_Printf(1,0,OLED_6X8,"Hello");
			OLED_Printf(1,16,OLED_6X8,"Temp  %.2f", fTsDegree);
			OLED_Printf(1,24,OLED_6X8,"voltage %.2f", fVoltage);
			OLED_Update();
		}
		SysTickDelay(1000);
	}
	
}

【实验效果】

39bf913c73b29d3ffeac58082cc0a1ec.jpg

我把源代码上传,大家有需要OLED屏驱动的可以自取!

OLED.zip


阅读全文

推荐技术

返回顶部