STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)
创始人
2024-01-28 11:55:14
0

目录

本文通过四种方法实现OLED显示

设备选择

OLED介绍

接线表设计

OLED应用

1.标准库模拟IIC实现OLED显示

2.标准库IIC实现OLED显示

3.HAL库模拟IIC实现OLED显示

4.HAL库IIC实现OLED显示

实现效果

代码下载


本文通过四种方法实现OLED显示

设备选择

1.单片机:STM32F103

2.0.96寸OLED显示屏 

OLED介绍

OLED (Organic Light-Emitting Diode):有机发光二极管又称为有机电激光显示,OLED显示技术具有自发光的特性,采用薄的有机材料涂层和玻璃基板,当有电流通过时,这些有机材料就会发光,而且OLED显示屏幕可视角度大,功耗低。OLED由于同时具备自发光、不需背光源(只上电是不会亮的,驱动程序和接线正确才会点亮)、对比度高、厚度薄、视角广、反应速度快、可用于挠曲面板、使用温度范围广、结构及制程简单等优异之特性。最先接触的12864屏都是LCD的,需要背光,功耗较高,而OLED的功耗低,更加适合小系统;由于两者发光材料的不同,在不同的环境中,OLED的显示效果较佳。模块供电可以是3.3V也可以是5V,不需要修改模块电路,OLED屏具有多个控制指令,可以控制OLED的亮度、对比度、开关升压电路等指令。操作方便,功能丰富,可显示汉字、ASCII、图案等。
 

接线表设计

序号激光测距模块单片机STM32
1VCC3.3V/5V
2SCLPB6
3SDAPB7
4GNDGND

OLED应用

这里选用0.96寸OLED显示屏,它支持IIC通信,因此代码将以IIC展开。

整个实现过程,分为四种方式实现。

1.标准库模拟IIC实现OLED显示

/**************************************************/
/*               IIC Start                        */
/**************************************************/
void IIC_Start()
{OLED_GPIO(OLED_SDA,1);OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_SDA,0);OLED_GPIO(OLED_CLK,0);
}/**************************************************/
/*               IIC Stop                         */
/**************************************************/
void IIC_Stop()
{OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_SDA,0);OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_SDA,1);OLED_GPIO(OLED_CLK,1);}void IIC_Wait_Ack()  //检测应答
{OLED_GPIO(OLED_SDA,0);OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_CLK,0);}
/**************************************************/
/*             IIC Write byte                     */
/**************************************************/
void Write_IIC_Byte(uint8_t IIC_Byte)
{uint8_t i;uint8_t m,da;da=IIC_Byte;OLED_GPIO(OLED_CLK,0);for(i=0;i<8;i++)		{m=da;//	OLED_SCLK_Clr();m=m&0x80;if(m==0x80){OLED_GPIO(OLED_SDA,1);}else OLED_GPIO(OLED_SDA,0);da=da<<1;OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_CLK,0);}}
/*********************************************/
/*      	IIC Write Command		   	     */
/*********************************************/
void Write_IIC_Command(uint8_t IIC_Command) //写命令
{IIC_Start();Write_IIC_Byte(0x78);	// OLED的I2C地址(禁止修改)IIC_Wait_Ack();	Write_IIC_Byte(0x00);	// OLED 指令(禁止修改)			IIC_Wait_Ack();Write_IIC_Byte(IIC_Command); IIC_Wait_Ack();	IIC_Stop();
}
/*********************************************/
/*       	IIC Write Data	  	   	         */
/*********************************************/
void Write_IIC_Data(uint8_t IIC_Data)   //写数据
{IIC_Start();Write_IIC_Byte(0x78);		// OLED的I2C地址(禁止修改)		IIC_Wait_Ack();	Write_IIC_Byte(0x40);		// OLED 数据(禁止修改)IIC_Wait_Ack();	Write_IIC_Byte(IIC_Data);IIC_Wait_Ack();	IIC_Stop();
}
void OLED_WR_Byte(uint8_t dat,uint8_t cmd) 
{if(cmd){Write_IIC_Data(dat);}else {Write_IIC_Command(dat);}
}

2.标准库IIC实现OLED显示

/*** @brief  I2C_Configuration,初始化硬件IIC引脚* @param  无* @retval 无*/
void I2C_Configuration(void)
{I2C_InitTypeDef  I2C_InitStructure;GPIO_InitTypeDef  GPIO_InitStructure; /*I2C1外设时钟使能 */OLED_I2C_CLK_INIT(OLED_I2C_CLK,ENABLE);/*I2C1外设GPIO时钟使能 */RCC_APB2PeriphClockCmd(OLED_I2C_SCL_GPIO_CLK | OLED_I2C_SDA_GPIO_CLK,ENABLE);/* I2C_SCL、I2C_SDA*/GPIO_InitStructure.GPIO_Pin = OLED_I2C_SCL_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;          // 开漏输出GPIO_Init(OLED_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = OLED_I2C_SDA_PIN;GPIO_Init(OLED_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);   /* I2C 配置 */I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;    /* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */I2C_InitStructure.I2C_OwnAddress1 =0x10;    //主机的I2C地址.和其它设备不重复即可I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* I2C的寻址模式 */I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;                             /* 通信速率 */I2C_Init(OLED_I2C, &I2C_InitStructure);                                         /* I2C1 初始化 */I2C_Cmd(OLED_I2C, ENABLE);                                                    /* 使能 I2C1 */}/*** @brief  I2C_WriteByte,向OLED寄存器地址写一个byte的数据* @param  addr:寄存器地址*                   data:要写入的数据* @retval 无*/
void I2C_WriteByte(uint8_t addr,uint8_t data)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 默认0x78while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, addr);//寄存器地址while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, data);//发送数据while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线
}/*** @brief  WriteCmd,向OLED写入命令* @param  I2C_Command:命令代码* @retval 无*/
void WriteCmd(unsigned char I2C_Command)//写命令
{I2C_WriteByte(0x00, I2C_Command);
}/*** @brief  WriteDat,向OLED写入数据* @param  I2C_Data:数据* @retval 无*/
void WriteDat(unsigned char I2C_Data)//写数据
{I2C_WriteByte(0x40, I2C_Data);
}/*** @brief  OLED_Init,初始化OLED* @param  无* @retval 无*/
void OLED_Init(void)
{delay_ms(1000);     // 1s,这里的延时很重要,上电后延时,没有错误的冗余设计WriteCmd(0xAE); //display offWriteCmd(0x20); //Set Memory Addressing Mode    WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8); //Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel
}

3.HAL库模拟IIC实现OLED显示

static void OLED_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_Struct;/* GPIO Ports Clock Enable */__HAL_RCC_GPIOB_CLK_ENABLE();GPIO_Struct.Pin = GPIO_PIN_7| GPIO_PIN_6;GPIO_Struct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_Struct.Speed =	GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_Struct);}void OLED_GPIO(uint8_t add,uint8_t date)
{if(add==0){if(date==1) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);else if(date==0)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);}else if(add==1){if(date==1) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);else if(date==0)HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);}
}
/**************************************************/
/*               IIC Start                        */
/**************************************************/
void IIC_Start()
{OLED_GPIO(OLED_SDA,1);OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_SDA,0);OLED_GPIO(OLED_CLK,0);
}/**************************************************/
/*               IIC Stop                         */
/**************************************************/
void IIC_Stop()
{OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_SDA,0);OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_SDA,1);OLED_GPIO(OLED_CLK,1);}void IIC_Wait_Ack()  //检测应答
{OLED_GPIO(OLED_SDA,0);OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_CLK,0);}
/**************************************************/
/*             IIC Write byte                     */
/**************************************************/
void Write_IIC_Byte(uint8_t IIC_Byte)
{uint8_t i;uint8_t m,da;da=IIC_Byte;OLED_GPIO(OLED_CLK,0);for(i=0;i<8;i++)		{m=da;//	OLED_SCLK_Clr();m=m&0x80;if(m==0x80){OLED_GPIO(OLED_SDA,1);}else OLED_GPIO(OLED_SDA,0);da=da<<1;OLED_GPIO(OLED_CLK,1);OLED_GPIO(OLED_CLK,0);}}
/*********************************************/
/*      	IIC Write Command		   	     */
/*********************************************/
void Write_IIC_Command(uint8_t IIC_Command) //写命令
{IIC_Start();Write_IIC_Byte(0x78);	// OLED的I2C地址(禁止修改)IIC_Wait_Ack();	Write_IIC_Byte(0x00);	// OLED 指令(禁止修改)			IIC_Wait_Ack();Write_IIC_Byte(IIC_Command); IIC_Wait_Ack();	IIC_Stop();
}
/*********************************************/
/*       	IIC Write Data	  	   	         */
/*********************************************/
void Write_IIC_Data(uint8_t IIC_Data)   //写数据
{IIC_Start();Write_IIC_Byte(0x78);		// OLED的I2C地址(禁止修改)		IIC_Wait_Ack();	Write_IIC_Byte(0x40);		// OLED 数据(禁止修改)IIC_Wait_Ack();	Write_IIC_Byte(IIC_Data);IIC_Wait_Ack();	IIC_Stop();
}
void OLED_WR_Byte(uint8_t dat,uint8_t cmd) 
{if(cmd){Write_IIC_Data(dat);}else {Write_IIC_Command(dat);}
}

4.HAL库IIC实现OLED显示

//写命令
void OLED_WR_CMD(uint8_t cmd)
{HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);
}
//写数据
void OLED_WR_DATA(uint8_t data)
{HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);
}void WriteCmd()
{HAL_Delay(1000);     // 1s,这里的延时很重要,上电后延时,没有错误的冗余设计OLED_WR_CMD(0xAE); //display offOLED_WR_CMD(0x20); //Set Memory Addressing Mode    OLED_WR_CMD(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidOLED_WR_CMD(0xb0); //Set Page Start Address for Page Addressing Mode,0-7OLED_WR_CMD(0xc8); //Set COM Output Scan DirectionOLED_WR_CMD(0x00); //---set low column addressOLED_WR_CMD(0x10); //---set high column addressOLED_WR_CMD(0x40); //--set start line addressOLED_WR_CMD(0x81); //--set contrast control registerOLED_WR_CMD(0xff); //亮度调节 0x00~0xffOLED_WR_CMD(0xa1); //--set segment re-map 0 to 127OLED_WR_CMD(0xa6); //--set normal displayOLED_WR_CMD(0xa8); //--set multiplex ratio(1 to 64)OLED_WR_CMD(0x3F); //OLED_WR_CMD(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentOLED_WR_CMD(0xd3); //-set display offsetOLED_WR_CMD(0x00); //-not offsetOLED_WR_CMD(0xd5); //--set display clock divide ratio/oscillator frequencyOLED_WR_CMD(0xf0); //--set divide ratioOLED_WR_CMD(0xd9); //--set pre-charge periodOLED_WR_CMD(0x22); //OLED_WR_CMD(0xda); //--set com pins hardware configurationOLED_WR_CMD(0x12);OLED_WR_CMD(0xdb); //--set vcomhOLED_WR_CMD(0x20); //0x20,0.77xVccOLED_WR_CMD(0x8d); //--set DC-DC enableOLED_WR_CMD(0x14); //OLED_WR_CMD(0xaf); //--turn on oled panel
}

实现效果

 由于频闪的原因,拍不全。

从代码上可以发现,IIC实现比模拟IIC实现起来要简单不少。

代码下载

创作不易,下面提供下载链接,涉及以上四种实现方法源码。

如有问题或需求可私信交流

源码下载地址:

STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)-C文档类资源-CSDN文库

吾芯电子工作室

相关内容

热门资讯

5万元小本生意做什么好 做点什... 如今市场上有着很多的投资小项目,而导致这些项目出现的原因自然是因为当下人们生活水平以及消费水平的迅速...
小本创业好项目有哪些(月入5万... 1.铁板鱿鱼近几年来走在城市的大街小巷,随处可闻铁板鱿鱼的奇特香味,铁板鱿鱼的制作技术胜在配方上,技...
加盟小本创业好项目有哪些? 加... 创业对于很多人来说,是一件需要勇气去实现的事,由于其不只有资金方面的风险,对投资者的精力方面也有着一...
2020小本创业做什么好必看 ... 创业并不是一件简单的事情,稍有偏差,就有可能迎来失败的结局,因此有一个好的创业项目至关重要,那么20...
小本创业点子项目 小本创业点子... 一个好的创业点子往往能够在创业中起到意想不到的作用,那么有哪些创业点子适合致富呢?下面由小编与大家分...
2016小本创业点子推荐 20... 新的一年马上就要过去了,很多想创业的朋友准备大干一场。关于创业,先要对当下的发展有清楚的认识,了解发...
小本创业点子推荐 热门生意小成... 1开家少儿书店现在很多图书都可以在网上阅览,但是孩子看纸质书好一点,可以开办一家专门服务于少儿的书店...
千元投资创业项目 千元创业 1... 社会永远是最穷的人和最富有的人,那么穷人应该永远是穷人吗?不,有些人选择学习以寻找出路,有些人选择经...
创业金点子大全 创业金点子大全...   最能够赚钱的创业好点子:美甲店手有女人“第二张脸”之称,如今越来越多的女性开始关心起指甲美容。随...
恭喜! 南京胖哥第二个孩子出生   恭喜!南京胖哥第二个孩子出生,儿子7斤8两,一出生嗷嗷哭嗓门还大,“他跟姐姐真的长得好像好像”(...