IIC是常用的协议之一,它通过不同的地址来区分设备,并且端口需要是开漏模式,并且需要接上拉电阻
要使用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 开显示
}
上图分别为(起始位-数据-结束位)和(起始位-数据-应答位-结束位)两种帧类型,本文采用的是(起始位-数据-结束位)这种类型。若使用(起始位-数据-应答位-结束位),则可以在应答位后面继续写数据。
IIC通信时每个字节位宽为8位,数据先传送最高位,后传送最低位
文章来源:https://www.toymoban.com/news/detail-436453.html
即(起始位-数据-应答位-数据-应答位-数据-应答位-……数据-应答位-结束位)文章来源地址https://www.toymoban.com/news/detail-436453.html
到了这里,关于STM32使用IIC协议驱动0.96寸OLED屏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!