STM32 硬件IIC OLED

Posted 一只小阿大:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32 硬件IIC OLED相关的知识,希望对你有一定的参考价值。

OLED屏幕

OLED即有机发光管(Organic Light-Emitting Diode,OLED)。OLED显示技术具有自发光、广视角、几乎无穷高的对比度、较低功耗、极高反应速度、可用于绕曲性面板、使用温度范围广、构造及制程简单等有点,被认为是下一代的平面显示屏新兴应用技术。

OLED显示和传统的LCD显示不同,其可以自发光,所以不需要背光灯,这使得OLED显示屏相对于LCD显示屏尺寸更薄,同时显示效果更优。

常用的OLED屏幕有蓝色、黄色、白色等几种。屏的大小为0.96寸,像素点为128*64,所以我们称为0.96oled屏或者12864屏。

OLED屏幕特点

1.模块尺寸:23.7 *23.8mm
2.电源电压:3.3-5.5V
3.驱动芯片:SSD1306
4.测试平台:提供 k60/k10,9s12XS128,51,stm32,stm8等单片机

OLED屏幕接线说明

OLED屏幕显存


OLED本身是没有显存的,他的现存是依赖SSD1306提供的,而SSD1306提供一块显存。

SSD1306显存总共为128*64bit大小,SSD1306将这些显存分成了8页。每页包含了128个字节。

OLED屏幕原理

STM32内部建立一个缓存(共128*8个字节),每次修改的时候,只是修改STM32上的缓存(实际上就是SRAM),修改完后一次性把STM32上的缓存数据写入到OLED的GRAM。

这个方法也有坏处,对于SRAM很小的单片机(51系列)就比较麻烦。

OLED屏幕常用指令


命令0X81: 设置对比度。包含两个字节,第一个0X81为命令,随后方法是的一个字节要设置这个对比度,值越大屏幕越亮。

命令0XAE/0XAF: 0XAE为关闭显示命令,0XAF为开启显示命令

0X8D: 包含两个字节,第一个为命令字,第二个为设置值,第二个字节的BIT2表示电荷泵的开关状态,该位为1开启电荷泵,为0则关闭。模块初始化的时候,这个必须要开启,否则看不到屏幕显示。

命令0XB0~B7:用于设置页地址,其低三位的值对应GRAM页地址。

命令0X00~0X0F:用于设置显示时的起始列地址低四位。

命令0X10~0X1F: 用于设置显示时的起始列地址高四位。

OLED屏幕字模软件的使用

OLED点阵的点亮方式,举个显示”P”的例子,最左边位最高位P7。

1.可以看出,要想显示”P”,首先写入0x1f,则显示一个竖杠,之后控制器自动水平移动到下一列。

2.再写入0X05,则出现两个小横杆,这个两个横杆就是0X05中0000 0101中两个1所处的位置,写完第二列后,控制器自动跳到第三列.

3.再写入0X07,第四列写入0X00后,P就显示出来了。这也说明,即使你只想再一列的最上端显示一个小点,即写入0X01.

4.即你不能一次性控制一个点阵,只能一次性控制八位点阵,即一列点阵。这也决定了字模选择的取模方式为“列行式“。

代码

main.c

#include "stm32f10x.h"
#include "SysTick.h"
#include "oled.h"

int main()
{
		unsigned char i = 0;
	
		initSysTick();
	
		I2C_Config();
		OLED_Init();
		delay_ms(2000);
		
		OLED_Fill(0XFF);  //ÆÁÄ»ÁÁ
		delay_ms(2000);
		OLED_Fill(0X00);  //ÆÁÄ»Ãð
		delay_ms(2000);
		
//		OLED_ShowStr(0, 3, "Hello World", 1);
//		OLED_ShowStr(0, 4, "Hello World", 2);
		while (1)
		{
				for(i=0;i<3;i++)
				{
				    OLED_ShowLJJ(i*16, 0, i);
		
				}
		}
}

oled.h

#ifndef _OLED_H_
#define _OLED_H_

#include "stm32f10x.h"
#define OLED_ADDRESS 0x78

void I2C_Config(void);
void I2C_WriteByte(uint8_t addr,uint8_t data);
void I2C_WriteCmd(unsigned char I2C_Command);
void I2C_WriteData(unsigned char I2C_Data);
void OLED_Init(void);
void OLED_SetPos(unsigned char x,unsigned char y);
void OLED_Fill(unsigned char Fill_Data);
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x,unsigned y,unsigned char ch[],unsigned TextSize);
void OLED_ShowCN(unsigned char x,unsigned y,unsigned char N);
void OLED_ShowMouMou(unsigned char x,unsigned char y,unsigned char N);

#endif

oled.c

#include "stm32f10x.h"
#include "oled.h"
#include "delay.h"
#include "codetab.h"

/**
 *¹¦ÄÜ£ºI2CÅäÖÃ
 *²ÎÊý£ºvoid
 *·µ»ØÖµ£ºvoid
 */
void I2C_Config(void)
{
		GPIO_InitTypeDef GPIO_initStruct;
		I2C_InitTypeDef  I2C_initStruct;
	
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,  ENABLE);
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 ,  ENABLE);

		//PB6 -- SCL    PB7 -- SDA
		GPIO_initStruct.GPIO_Mode  = GPIO_Mode_AF_OD;
		GPIO_initStruct.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
		GPIO_initStruct.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOB, &GPIO_initStruct);

		I2C_DeInit(I2C1);
		I2C_initStruct.I2C_Ack = I2C_Ack_Enable;                                //Ó¦´ðÊÇ·ñʹÄÜ
		I2C_initStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  //µØÖ·£¬Êý¾ÝλÊǶàÉÙ£¬ÓÐ7bitºÍ10bit
		I2C_initStruct.I2C_ClockSpeed = 400000;                                 //ʱÖÓËÙ¶È 400Kb
	  I2C_initStruct.I2C_DutyCycle = I2C_DutyCycle_2;                         // 2:1 »òÕß16:9¶¼ÐÐ
		I2C_initStruct.I2C_Mode = I2C_Mode_I2C;                                 //ģʽI2Cģʽ
		I2C_initStruct.I2C_OwnAddress1 = 0x30;                                  //Ö÷»úµØÖ·£¬0x30Ëæ±ã¸øµÄ
		I2C_Init(I2C1, &I2C_initStruct);
		I2C_Cmd(I2C1,  ENABLE);

}

/**
 *¹¦ÄÜ£ºI2Cд×Ö½Ú
 *²ÎÊý£ºaddr µØÖ·£¬data Êý¾Ý
 *·µ»ØÖµ£ºvoid
 */
/* ΪɶÏÂÃæûEV8_2¾ÍÖ±½Ó¹Ø±ÕÁË£¬ÓÐwhileÑ­»·»áµÈ´ýдÍ꣬ËùÒÔû±ØÒª */
void I2C_WriteByte(uint8_t addr,uint8_t data)
{
		while( I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));                                 //¼ì²éI2C×ÜÏßÊÇ·ñ·±Ã¦
	
		I2C_GenerateSTART( I2C1, ENABLE);                                               //¿ªÆôI2C1
		while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_MODE_SELECT ));                 //EV5 Ö÷ģʽ
	
		I2C_Send7bitAddress(I2C1, OLED_ADDRESS , I2C_Direction_Transmitter );           //·¢ËÍÆ÷¼þµØÖ·
		while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ));   //EV6
	
		I2C_SendData( I2C1 , addr );                                                    //¼Ä´æÆ÷µØÖ·
		while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_BYTE_TRANSMITTING ));           //EV8
	
		I2C_SendData( I2C1 , data );                                                    //Òª·¢Ë͵ÄÊý¾Ý
		while( !I2C_CheckEvent( I2C1 , I2C_EVENT_MASTER_BYTE_TRANSMITTING ));           //EV8 

		I2C_GenerateSTOP( I2C1, ENABLE );                                               //¹Ø±ÕI2C×ÜÏß

}

/**
 *¹¦ÄÜ£ºÐ´ÃüÁî
 *²ÎÊý£ºI2C_Command ÐèҪдÈëµÄÃüÁî
 *·µ»ØÖµ£ºvoid
 */
void WriteCmd(unsigned char I2C_Command)
{
		I2C_WriteByte(0x00,I2C_Command);
}

/**
 *¹¦ÄÜ£ºÐ´Êý¾Ý
 *²ÎÊý£ºI2C_Data ÐèҪдÈëµÄÊý¾Ý
 *·µ»ØÖµ£ºvoid
 */
void WriteData(unsigned char I2C_Data)
{
		I2C_WriteByte(0x40,I2C_Data);
}

/**
 *¹¦ÄÜ£º³õʼ»¯OLED
 *²ÎÊý£ºvoid
 *·µ»ØÖµ£ºvoid
 */
void OLED_Init(void)
{
    	delay_ms(100);
		WriteCmd(0xAE); //display off
		WriteCmd(0x20);	//Set Memory Addressing Mode	
		WriteCmd(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
		WriteCmd(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7
		WriteCmd(0xc8);	//Set COM Output Scan Direction
		WriteCmd(0x00); //---set low column address
		WriteCmd(0x10); //---set high column address
		WriteCmd(0x40); //--set start line address
		WriteCmd(0x81); //--set contrast control register
		WriteCmd(0xff); //ÁÁ¶Èµ÷½Ú 0x00~0xff
		WriteCmd(0xa1); //--set segment re-map 0 to 127
		WriteCmd(0xa6); //--set normal display
		WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
		WriteCmd(0x3F); //
		WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
		WriteCmd(0xd3); //-set display offset
		WriteCmd(0x00); //-not offset
		WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
		WriteCmd(0xf0); //--set divide ratio
		WriteCmd(0xd9); //--set pre-charge period
		WriteCmd(0x22); //
		WriteCmd(0xda); //--set com pins hardware configuration
		WriteCmd(0x12);
		WriteCmd(0xdb); //--set vcomh
		WriteCmd(0x20); //0x20,0.77xVcc
		WriteCmd(0x8d); //--set DC-DC enable
		WriteCmd(0x14); //
		WriteCmd(0xaf); //--turn on oled panel
}

/**
 *¹¦ÄÜ£ºÉèÖÃ×ø±ê
 *²ÎÊý£ºx xÖᣬy yÖá
 *·µ»ØÖµ£ºvoid
 */
void OLED_SetPos(unsigned char x,unsigned char y)
{
		WriteCmd(0xb0 + y);
		WriteCmd((x&0xf0)>>4|0x10);
		WriteCmd((x&0x0f)|0x01);
}

/**
 *¹¦ÄÜ£ºÈ«ÆÁÌî³ä
 *²ÎÊý£ºFill_Data ÐèÒªÌî³äµÄÊý¾Ý
 *·µ»ØÖµ£ºvoid
 */
void OLED_Fill(unsigned char Fill_Data)
{
		unsigned char n;
		unsigned char m;
	
		for(m=0;m<8;m++)
		{
				WriteCmd(0xb0 + m);
				WriteCmd(0x00);
				WriteCmd(0x10);
			
				for(n=0;n<128;n++)
				{
						WriteData(Fill_Data);
				}
		}
}

/**
 *¹¦ÄÜ£ºÇåÆÁ
 *²ÎÊý£ºvoid
 *·µ»ØÖµ£ºvoid
 */
void OLED_CLS(void)
{
		OLED_Fill(0x00);
}

/**
 *¹¦ÄÜ£º¿ªÆôOLED
 *²ÎÊý£ºvoid
 *·µ»ØÖµ£ºvoid
 */
void OLED_ON(void)
{
		WriteCmd(0x8D); //ÉèÖõçºÉ±Ã
		WriteCmd(0x14); //¿ªÆôµçºÉ±Ã
		WriteCmd(0xAF); //¿ªÆôÏÔʾ
}

/**
 *¹¦ÄÜ£º¹Ø±ÕOLED
 *²ÎÊý£ºvoid
 *·µ»ØÖµ£ºvoid
 */
void OLED_OFF(void)
{
		WriteCmd(0x8D); //ÉèÖõçºÉ±Ã
		WriteCmd(0x10); //¹Ø±ÕµçºÉ±Ã
		WriteCmd(0xAE); //¹Ø±ÕÏÔʾ
}

void OLED_ShowStr(unsigned char x,unsigned y,unsigned char ch[],unsigned TextSize)
{
		unsigned char c = 0;
		unsigned char i = 0;
		unsigned char j = 0;
	
		switch(TextSize) //Ñ¡Ôñģʽ
		{
			case 1:
			{
					while(ch[j] != '\\0') //ÅжÏÊÇ·ñµ½´ï×îºóһλ
					{
							c = ch[j] - 32; //´óСдת»»
							
							if(x > 126) //ÅжÏÆÁÄ»ÊÇ·ñ·ÅµÃÏÂ,OLEDÊÇ128*8×Ö½Ú
							{
									x = 0;
									y++;
							}
							
							OLED_SetPos(x,y);//ÉèÖÃ×ø±ê
							
							for(i=0;i<6;i++)
							{
									WriteData(F6x8[c][i]);	
							}
							
							x+=6;
							j++;
					}
			}break;
			
			case 2:
			{
					while(ch[j] != '\\0')  //ÅжÏÊÇ·ñµ½´ï×îºóһλ
					{
							c = ch[j] - 32;   //´óСдת»»
							
							if(x > 120)       //ÅжÏÆÁÄ»ÊÇ·ñ·ÅµÃÏÂ,OLEDÊÇ128*8×Ö½Ú
							{
									x = 0;
									y++;
							}
							
							OLED_SetPos(x,y); //ÉèÖÃ×ø±ê
							
							for(i=0;i<8;i++)  //ÒòΪÊÇ16½øÖƵÄËùÒÔ·ÖΪÁ½¸ö8λÀ´Ð´£¬ÕâÊÇÉϰ벿·Ö
							{
									WriteData(F8X16[c*16+i]);
							}
							
							OLED_SetPos(x,y+1); //ÉèÖÃ×ø±ê Èç¹ûÕâÀïÉèÖõÄÊÇy²»ÊÇy+1»áµ¼ÖÂÏÔʾµÄ×Ö·û´®Ö»ÏÔʾһ°ë
							
							for(i=0;i<8;i++)  //Ìøתµ½ÏÂÒ»Ò³£¬ÕâÊÇÏ°벿·Ö
							{
									WriteData(F8X16[c*16+i+8]);
							}
							
							x+=8;
							j++;
							
					}
			}break;
					
		}


}	

void OLED_ShowCN(unsigned char x,unsigned y,unsigned char N)
{
		unsigned char i;
		unsigned int addr = 32*N;
		OLED_SetPos(x,y);
	
		for(i=0;i<16;i++)
		{
				WriteData(F16X16[addr]);
				addr += 1;
		}
		
		OLED_SetPos(x,y+1);
		for(i=0;i<16;i++)
		{
				WriteData(F16X16[addr]);
				addr += 1;
		}
}	

void OLED_ShowMouMou(unsigned char x,unsigned char y,unsigned char N)
{
		unsigned char i;
		unsigned int addr = 32*N;
		OLED_SetPos(x,y);
	
		for(i=0;i<16;i++)
		{
				WriteData(MouMou[addr]);
				addr += 1;
		}
		
		OLED_SetPos(x,y+1);
		for(i=0;i<16;i++)
		{
				WriteData(MouMou[addr]);
				addr += 1;
		}
		
}	



codetab.h

//unsigned char F16X16[] =
//{
//		0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,
//		0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"ζÈ",0*/
//		0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,
//		0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"ʪ¶È",1*/
//};

unsigned char F16X16[] =
{
		0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30,0x00,0x00,
		0x00,0x0F,0x04,0x04,0x0F,0x08,0x0A,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x08,0x00,/*"ßè",0*/
		0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30,0x00,0x00,
		0x00,0x0F,0x04,0x04,0x0F,0x08,0x0A,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x08,0x00,/*"ßè",1*/
};

unsigned char MouMou[] =
{		0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30,0x00,0x00,
		0x00,0x0F,0x04,0x04,0x0F,0x08,0x0A,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x08,0x00,/*"ßè",0*/
		0x00,0xFC,0x04,0x04,0xFC,0x00,0x10,0xD8,0x14,0x13,0xF0,0x14,0x18,0x30

以上是关于STM32 硬件IIC OLED的主要内容,如果未能解决你的问题,请参考以下文章

STM32使用IIC总线通讯协议在OLED屏幕上显示字符串汉字图像(硬件IIC)

STM32 软件IIC OLED温湿度显示

STM32CubeMX驱动4脚OLED模块

STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)

STM32实现0.96寸OLED显示模拟IIC和IIC四种实现(标准库和HAL库)

STM32使用IIC总线通讯协议在OLED屏幕上显示字符串汉字温湿度(软件IIC)