STM32 i2c 驱动0.42寸OLED,这是个项目中使用的方案,调试也是比较费劲,主要是取字模和代码的匹配,下个篇章中详解一下取字模的过程,在这个方案中的使用。
本文使用的测试代码
STM32i2c驱动0.42寸OLED,SSD1306资源-CSDN文库
有个项目需要使用一个最小的OLED进行显示,选来选去,找了一个0.42寸的超级小的OLED.这里简单记录一下实际项目中调试该OLED的过程。
该OLED的尺寸图
该OLED的行列图
该OLED的硬件接口
硬件上使用STM32F030F4Px连接该OLED
这里需要注意的是PA5/PA6使用i2c功能,需要设计上拉电阻
原理图比较简单,就不多叙述了。
时钟配置如下,使用内部HSI时钟,倍频到48Mhz,这里也很重要和时钟的延时有很多关系,如果延时函数配置不正确,会导致I2C时序不对,进而配置不对OLED,当然这里你也可以使用外部时钟
使用的stm32cubemx版本,这个最好用最新的版本
stm32cubemx中关于I2C管脚的配置,配置成为输出就可以了
生成的工程使用如下设置
OLED初始化函数
void write_i(uint8_t cmd)
{
OLED_send_cmd(cmd);
}
void InitSSD1306()
{
// RES=0;
// delay(1000);
// RES=1;
///delay(10);
HAL_Delay(1000);
write_i(0xAE); /*display off*/
write_i(0xD5); /*set osc division*/
write_i(0xF0);
write_i(0xA8); /*multiplex ratio*/
write_i(0x27); /*duty = 1/40*/
write_i(0xD3); /*set display offset*/
write_i(0x00);
write_i(0x40); /*Set Display Start Line */
write_i(0x8d); /*set charge pump enable*/
write_i(0x14);
write_i(0x20); /*Set page address mode*/
write_i(0x02);
write_i(0xA1); /*set segment remap*/
write_i(0xC8); /*Com scan direction*/
write_i(0xDA); /*set COM pins*/
write_i(0x12);
write_i(0xAD); /*Internal IREF Setting*/
write_i(0x30);
write_i(0x81); /*contract control*/
write_i(0x2F); /*128*/
write_i(0xD9); /*set pre-charge period*/
write_i(0x22);
write_i(0xdb); /*set vcomh*/
write_i(0x20);
write_i(0xA4); /*Set Entire Display On/Off*/
write_i(0xA6); /*normal / reverse*/
write_i(0x0C); /*set lower column address*/
write_i(0x11); /*set higher column address*/
write_i(0xAF); /*display ON*/
}
反转屏幕函数,这个很有用,调试的时候比较方便
void OLED_reverse_All(unsigned char mode)//(1黑底白字,0白底黑字)
{
if(mode){
OLED_send_cmd(0xA6);//1亮0灭
}else{
OLED_send_cmd(0xA7);//1灭0亮
}
}
主函数中进行闪烁灯的操作,以及刷新屏幕
HAL_Delay(1000);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);//LED twinkle
OLED_full_OLED();
HAL_Delay(1000);
OLED_clean_OLED();
HAL_Delay(1000);
OLED_drawString(28, 0, "012345678901234", 8, 16);//128 = 16*8
OLED_drawString(28, 16, "012345678901234", 8, 16);//128 = 16*8
OLED_drawString(28, 32, "012345678901234", 8, 16);//128 = 16*8
OLED_display();
hal库使用I2C需要对SDA管脚进行输入输出配置,这里没有直接对寄存器操作,而是使用库函数,也能满足使用需求
#define IIC_SDA_PIN GPIO_PIN_6
#define IIC_SCL_PIN GPIO_PIN_5
#define IIC_SDA_H HAL_GPIO_WritePin(IIC_SDA, IIC_SDA_PIN, GPIO_PIN_SET)
#define IIC_SDA_L HAL_GPIO_WritePin(IIC_SDA, IIC_SDA_PIN, GPIO_PIN_RESET)
#define IIC_SCL_H HAL_GPIO_WritePin(IIC_SCL, IIC_SCL_PIN, GPIO_PIN_SET)
#define IIC_SCL_L HAL_GPIO_WritePin(IIC_SCL, IIC_SCL_PIN, GPIO_PIN_RESET)
void IIC_OUT(void)//SDA是输出方向
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin=IIC_SDA_PIN;
GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出模式
HAL_GPIO_Init(IIC_SDA,&GPIO_InitStructure);
}
void IIC_IN(void)//SDA是输入方向
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin=IIC_SDA_PIN;
GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Mode=GPIO_MODE_INPUT; //输入上拉模式
HAL_GPIO_Init(IIC_SDA,&GPIO_InitStructure);
}
实际测试效果图如下,
使用的测试代码如下
STM32i2c驱动0.42寸OLED,SSD1306资源-CSDN文库
其中keil的版本号如下