概述
IIC和OLED
- 什么是oled
- oled的特点
- oled的接线
- oled的显存
- OLED的指令
- OLED 取模软件使用
- IIC协议的简述
- IIC的总线架构
- 硬件IIC的特点
- IIC的总线协议
- IIC通信
- STM32的 iic特性及架构
- 代码
什么是oled
OLED即有机发光管(Organic Light-Emitting Diode,OLED)。OLED显示技术具有自发光、广视角、几乎无穷高的对比度、较低功耗、极高反应速度、可用于绕曲性面板、使用温度范围广、构造及制程简单等有点,被认为是下一代的平面显示屏新兴应用技术。
OLED显示和传统的LCD显示不同,其可以自发光,所以不需要背光灯,这使得OLED显示屏相对于LCD显示屏尺寸更薄,同时显示效果更优。
常用的oled 一般都是 0.96寸 128*64个像素点的 简单了解就行了
oled的特点
1 模块尺寸:23.7 *23.8mm
2 电源电压:3.3-5.5V
3 驱动芯片:SSD1306
4 测试平台:提供 k60/k10,9s12XS128,51,stm32,stm8等单片机。
oled的接线
oled的显存
SSD1306 把像素为 128*64 我们按列行式规则来说 有128列 64行 64行又分成了8列 一列有8行 这玩意很多说法 确实要好好体会
OLED的指令
==序号0 命令 0x81 设置亮度 == 值越大就越亮 值为最后一位 A[6:0]
==序号1 命令 0xAE/0xAF 关与不关显示 ==
==序号2 命令 0x8d 关闭电荷泵 == 这个名词不需要纠结来由 用就完事了
==序号3 命令 0xb0-0xb7 设置页地址 == 对应 0-7 页
==序号4 命令 0x00-0x0F 设置列的低四位 ==
==序号4 命令 0x10-0x1F 设置列的高四位 ==
OLED 取模软件使用
配置注意
注意 图一 的参数
IIC协议的简述
IIC通讯协议是飞利浦公司开发的 引脚少 硬件实现简单,不需要UASRT CAN的 外部收发设备。
半双工的通信方式
IIC的总线架构
他是支持多设备的总线 。总线就是多个设备共用信号线 可连接多个iic通信设备
支持多个通信主机及通信从机
一个 iic只有 两个线路 1是 SCL SCL 就是时钟 ,用于数据收发同步
2 是SDA 表示数据 也就是数据线
硬件IIC的特点
硬件iic 对应芯片的外设 引脚是固定的 使用的iic管教也是固定的
软件 iic 引脚灵活 一般用于控制管教状态及模拟iic通信波形
明显的区别
硬件iic通信速度快 软件iic的引脚灵活
区分
硬件iic 用法 复杂 软件IIC 流程更清楚
硬件iic 速度更快
软件iic 接口 灵活
IIC的总线协议
提醒 : 下面开始最重要的内容 很重要
IIC协议层 定义了 通信的起始信号 停止信号 数据有效性 响应 仲裁 时钟同步和地址广播等等
1 IIC 的基本读写过程
主机写数据到从机
S:相当于是一个起始地址
从机地址 起始信号产生以后 ,所有的从机就接下来广播地址信号 。
IIC 总线 ,每个设备地址都是唯一的 。当主机的广播地址和某个从机地址相同时,
设备就被选中了 ,没被选中的就忽略数据信号。
我举个例子
刚好今天第一节是数字课 老师说开始点名了 结果你被选中 而你就是 从机
你站的位置就是从机地址 老师就是主机 老师站的位置就是主机地址 而其他同学老师就忽略了
选择传输方向 :0:表示从主机传输数据到从机 1:相反
应答信号 :只有从机应答了 主机才能继续发送数据
你被选中了 却一句都不回答 老师也没办法。
IIC通信
1 空闲状态
SCL SDA 同时处于 高电平 就是空闲状态 输出场效应管处在截止状态
释放总线 用上拉电阻把两条信号线 初始化电平拉高
2开始信号
SCL 处于 高电平期间 SDA 是1 --0的跳变; 注意不是一个电平信号
3 停止信号
SCL 处于 高电平期间 SDA 是0--1的跳变; 注意不是一个电平信号
开始和停止信号 都由主机产生
4应答信号
发送器每发送一个字节 在第九个脉冲前释放总线 也就是 结束传输
最后到接收器反馈一个应答信号 ,应答信号 为低电平 就可以认为是有效应答位
表示接收器成功接收该字节了 相反就是没有成功。
对于ack应答位要求
接收在第九个脉冲之前必须释放总线 马上把数据总线拉低
确保 该时钟的高电平期间为稳定低电平。
5 数据有效性
数据在SCL的上升沿来之前就需要准备好 并且在下降压之前 数据一定要稳定
6 数据传输
在SCL时钟的配合下 SDA 传输数据 。数据位的输出时边沿触发
边沿触发无非 两种 :0---1 (上升沿触发) 1-0 (下降沿触发)
STM32的 iic特性及架构
1)硬件实现 协议
只要配置好该外设 他就会自动根据协议产生通讯信号 ,收发数据并缓存起来
这种硬件iic协议减轻了 CPU工作 设计比较简单。
STM32 IIC 支持 100KBIT/S 400KBITS/S 的速率 支持 7位 10位设备地址。
2 时钟控制逻辑
SCL 的时钟线 由iic接口根据 CCR控制寄存器控制 控制参数的主要位的时钟频率
选择 标志模式 或 快速模式 分别对应 100/400kbits/s 的速率
时钟占空比
标准:T(low)/T(high)=2
快速 :T(low)/T(high)=16/9 =2.0111
其实都差不多
计算 时钟频率
标准模式
Thigh=CCR*Tpck1 , Tlow=CCR*Tpclk1
标准模式 Tlow/Thigh=2
Thigh=CCR*Tpck1 , Tlow=2*CCR*Tpclk1
快速模式 Tlow/Thigh=16/9
Thigh=9*CCR*Tpck1 , Tlow=16*CCR*Tpclk1
3 数据控制逻辑
IIC 的SDA 信号 主要连接到 数据移位寄存器上,数据移位寄存器来源和目标主要是
数据寄存器(DR)地址寄存器 (OAR) PEC寄存器 以及SDA数据线
当向外发送数据时候,数据移位寄存器以“数据寄存器”为数据来源 把数据一个字节一个字节通过SDA 发送出去。
而相反的话 就是把接收到的数据存到“数据寄存器”里面。
大概的简介
控制产生起始信号(s)当发生起始信号之后 产生EV5事件 并对SR1寄存器的SB1位置 1
表示完成起始信号了
发生设备地址 并等待 应答信号 ,如果有应答信号产生 ,则会产生时间EV6和EV8 并且对应的寄存器位ADDR=1 表示已经发送了,TEX:接收 也就是 主机停止发送数据了 从机停止接收。
代码
1)结构体
typedef struct
{
uint32_t I2C_ClockSpeed;//设置SCL 频率
uint16_t I2C_Mode; //工作模式
uint16_t I2C_DutyCycle;//占空比
uint16_t I2C_OwnAddress1;//IIC设备地址
uint16_t I2C_Ack; //应答使能
uint16_t I2C_AcknowledgedAddress; //地址长度 7或10
}I2C_InitTypeDef;
结构体参数配置注意事项
uint32_t I2C_ClockSpeed;//设置SCL 频率
在调用初始化函数时 函数会根据我们输入的参数 经过运算把 时钟因子写入 IIC 的CCR
寄存器 而我们 写入的参数不得高于 400khz
uint16_t I2C_Mode; //工作模式
iic不需要 在此处 区分 主从模式
结构体参数 配置
void oled_Structconfig(void)
{
GPIO_InitTypeDef GPIO_I2CInitStruct;
I2C_InitTypeDef I2C_InitStruct;
//RCC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
//GPIO
GPIO_I2CInitStruct.GPIO_Mode =GPIO_Mode_AF_OD;//复用上拉
GPIO_I2CInitStruct.GPIO_Pin =GPIO_Pin_6|GPIO_Pin_7;
GPIO_I2CInitStruct.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_I2CInitStruct);
I2C_DeInit(I2C1);//初始化 IIC
I2C_InitStruct.I2C_Ack =I2C_Ack_Enable;//使能应答
I2C_InitStruct.I2C_AcknowledgedAddress =I2C_AcknowledgedAddress_7bit;//7位地址
I2C_InitStruct.I2C_ClockSpeed =400000;//速率
I2C_InitStruct.I2C_Mode =I2C_Mode_I2C;//主机模式
I2C_InitStruct.I2C_DutyCycle =I2C_DutyCycle_2;//占空比 Tlow/Thigh=2
I2C_InitStruct.I2C_OwnAddress1 =0x30;//设备地址
I2C_Init(I2C1,&I2C_InitStruct);
I2C_Cmd(I2C1, ENABLE);
}
写入一个字节
void Write_databyte(uint16_t addr,uint16_t data)
{
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)); //等待是否繁忙
I2C_GenerateSTART(I2C1,ENABLE);//起始位
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//判断是否完成 起始信号
I2C_Send7bitAddress(I2C1,0X78,I2C_Direction_Transmitter);
// 发送方向 和 oeld地址 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
//判断是否发送完成
I2C_SendData(I2C1, addr);//发送寄存器地址
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));//等待是否发送完成
I2C_SendData(I2C1, data);//发送数据
while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTING));//等待是否发送完成
I2C_GenerateSTOP(I2C1,ENABLE);//停止发送
}
写命令
void WriteCmd(unsigned char cmoodcmd)
{
Write_databyte(0x00,cmoodcmd);
}
写数据
void WriteDATA(unsigned char ic2data)
{
Write_databyte(0x40,ic2data);
}
起始坐标
void Starting_point(unsigned char x,unsigned char y)
{
WriteCmd(0xb0+y);//YµÄ×ø±ê
WriteCmd((x&0xf0)>>4|0x10); //1111 0000 ->0000 1111|0X10=0001 1111
WriteCmd((x&0x0f)|0x01);//0000 1111 | 0000 0001 =0000 1111
}
全屏填充
void oled_fill(unsigned char Flii_data)
{
unsigned char m,n;
for(m=0;m<9;m++)
{
WriteCmd(0xb0+m);
WriteCmd(0x00);
WriteCmd(0x10);
for(n=0;n<128;n++)
{
WriteDATA(Flii_data);
}
}
}
清屏
void oled_Clear(void)
{
oled_fill(0x00);
}
屏幕全亮
void OLED_CN(void)
{
WriteCmd(0X8D);//设置电荷泵
WriteCmd(0X14);//开电荷泵
WriteCmd(0XAF);//开显示
}
屏幕全灭
void OLED_OFF(void)
{
WriteCmd(0X8D);//设置电荷泵
WriteCmd(0X10);//开电荷泵
WriteCmd(0XAE);//开显示
}
oled 初始化
void oled_init(void)
{
delay_ms(1000);
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
delay_ms(3);
}
显示字符
void OLED_showstr(unsigned char x,unsigned char y,unsigned char ch[],unsigned temp)
{
unsigned char c=0;
unsigned char i=0;
unsigned char j=0;
switch(temp)
{
case 1:
{
while( ch[j] != '