STM32使用IIC协议驱动0.96寸OLED屏

IIC是常用的协议之一,它通过不同的地址来区分设备,并且端口需要是开漏模式,并且需要接上拉电阻

STM32使用IIC协议驱动0.96寸OLED屏_第1张图片

 要使用IIC驱动OLED,首先要配置IIC

void I2C_Configuration(void)
{
	I2C_InitTypeDef I2C_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	I2C_InitStructure.I2C_ClockSpeed = 100000;  
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x22;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 
	I2C_Init(I2C1,&I2C_InitStructure);
	I2C_Cmd(I2C1, ENABLE);
	
}

然后编写写入函数

void OLED_CMD(unsigned char cmd)
{
		I2C_GenerateSTART(I2C1, ENABLE);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
	
		I2C_Send7bitAddress(I2C1, 0x78, I2C_Direction_Transmitter);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
		
		I2C_SendData(I2C1,0x00);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_SendData(I2C1,cmd);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_GenerateSTOP(I2C1, ENABLE);
		
}

void OLED_DATA(unsigned char dat)
{
		I2C_GenerateSTART(I2C1, ENABLE);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
	
		I2C_Send7bitAddress(I2C1, 0x78, I2C_Direction_Transmitter);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)==ERROR);
		
		I2C_SendData(I2C1,0x40);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_SendData(I2C1,dat);
		while(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
	
		I2C_GenerateSTOP(I2C1, ENABLE);
}

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)为判断事件的函数

有以下多种事件

//从机发送地址匹配
I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED           : EV1
//从机接受地址匹配
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED              : EV1

//从机发送第二次地址匹配
I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED     : EV1
//从机接收第二次地址匹配
I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED        : EV1

//从机通用呼叫地址匹配
I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED            : EV1

//从机字节接收
I2C_EVENT_SLAVE_BYTE_RECEIVED                         : EV2

(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF)      : EV2
(I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL)    : EV2

//从机字节发送
I2C_EVENT_SLAVE_BYTE_TRANSMITTED                      : EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF)   : EV3
(I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) : EV3

//从机应答
I2C_EVENT_SLAVE_ACK_FAILURE                           : EV3_2

//从机停止位
I2C_EVENT_SLAVE_STOP_DETECTED                         : EV4

//主机模式选择
I2C_EVENT_MASTER_MODE_SELECT                          : EV5

//主机发送模式选择
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED            : EV6 

//主机接收模式选择
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED               : EV6

//主机字节接收
I2C_EVENT_MASTER_BYTE_RECEIVED                        : EV7

//主机字节发送中
I2C_EVENT_MASTER_BYTE_TRANSMITTING                    : EV8

//主机字节发送结束
I2C_EVENT_MASTER_BYTE_TRANSMITTED                     : EV8_2

//主机10位地址模式
I2C_EVENT_MASTER_MODE_ADDRESS10                       : EV9

OLED初始化

void OLED_init(void)
{
	OLED_CMD(0xAE);//--display off                关显示
	
	OLED_CMD(0x00);//---set low column address    设置在哪里开始写GDDRAM在某个地方开始读的内容
	OLED_CMD(0x10);//---set high column address
	OLED_CMD(0x40);//--set display start address  从GDDRAM的某个地方开始读,显示在所设置的开始高低列地址中
	OLED_CMD(0xB0);//--set page address           页地址模式,选择开始地址
	
  OLED_CMD(0x81); // contract control           进入对比度设置模式
	OLED_CMD(0xFF);//--256                        输入对比度数值范围是0x00-0xFF
	
	OLED_CMD(0xA1);//set segment remap            列地址127被映射到SEG0,可以利用该命令实现整体图片正反转(0xA0-0xA1),带显示屏30pin管脚的那边的左边为列地址0
	
	OLED_CMD(0xA6);//--normal / reverse           正相显示(0xA7为反相显示)
	
	OLED_CMD(0xA8);//--set multiplex ratio(16 to 64) 设置多路复用比率
	OLED_CMD(0x3F);//--1/64 duty占空比(最大屏幕利用率)
	
	OLED_CMD(0xC8);//Com scan direction           Com扫描方向,可理解为行地址映射,0xC8为从行地址63到0显示,0xC0为从行地址0到63显示,带显示屏30pin管脚的那边为行地址0
	
	OLED_CMD(0xD3);//-set display offset          设置显示偏移
	OLED_CMD(0x00);//                             行偏移
	
	OLED_CMD(0xD5);//set osc division             设置内部振荡器
	OLED_CMD(0x80);//                             Fosc通过高四位修改,值越大频率越高,低四位通过外部SCL获得频率然后分频获得显示时钟频率(慢,不常用,设置为0)默认为0x80
	
	OLED_CMD(0xD8);//set area color mode off      
	OLED_CMD(0x05);//
	
	OLED_CMD(0xD9);//Set Pre-Charge Period        预充电时间设置
	OLED_CMD(0xF1);//                             
	
	OLED_CMD(0xDA);//set com pin configuartion    设置引脚配置
	OLED_CMD(0x12);//
	
	OLED_CMD(0xDB);//set Vcomh                    设置引脚电压等级
	OLED_CMD(0x30);//
	
	OLED_CMD(0x8D);//set charge pump enable       将电荷泵设置为启用
	OLED_CMD(0x14);//                             0x14为打开使能,0x10为关闭使能
	
	OLED_CMD(0xAF);//--turn on oled panel         开显示
}

STM32使用IIC协议驱动0.96寸OLED屏_第2张图片

上图分别为(起始位-数据-结束位)(起始位-数据-应答位-结束位)两种帧类型,本文采用的是(起始位-数据-结束位)这种类型。若使用(起始位-数据-应答位-结束位),则可以在应答位后面继续写数据。

STM32使用IIC协议驱动0.96寸OLED屏_第3张图片

 

(起始位-数据-应答位-数据-应答位-数据-应答位-……数据-应答位-结束位)

你可能感兴趣的:(STM32,标准库,stm32,单片机,arm)