STM32模拟IIC驱动OLED屏 原理+源码
处理器和芯片间的通信可以形象的比喻成两个人讲话:1、你说的别人得能听懂:双方约定信号的协议。2、你的语速别人得能接受:双方满足时序要求。
一、IIC总线的信号类型
1、开始信号:处理器让SCL时钟保持高电平,然后让SDA数据信号由高变低就表示一个开始信号。同时IIC总线上的设备检测到这个开始信号它就知道处理器要发送数据了。
2、停止信号:处理器让SCL时钟保持高电平,然后让SDA数据信号由低变高就表示一个停止信号。同时IIC总线上的设备检测到这个停止信号它就知道处理器已经结束了数据传输,我们就可以各忙各个的了,如休眠等。
二、IIC数据传输过程
、
1、在数据传输时,SDA的数据在SCL为高电平时,必须保持稳定,SCL高电平器件完成数据的传输。在SCL低电平器件,可以任意改变SDA的数据。数据写入过程是从最好为开始,高位在前,低位在后,即MSB。
2、响应信号(ACK):接收器在接收到8位数据后,在第9个时钟周期,拉低SDA电平。即接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据。CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。
三、数据写入的过程
首先发送一个开始信号,接着发送从机地址,OLED的从机地址前7位为地址,最后一位表示读(1)或者写(0)。应答ACK信号表示有这个从设备存在。在接收到应答信号后,发送控制位,来区分之后所发送的数据是控制命令还是显示相关的数据。在发送控制位后,等待应答信号。然后发送相应的控制命令或者数据。最后发送停止信号,表示数据传输完成。
基本的时序就是以上内容,接下来是源码:
#include "stm32f10x.h"#include "iic.h"
#include "delay.h"
#include "codetab.h"/**
** 初始化IIC接口
**/
void IIC_Init(void)
{GPIO_InitTypeDef GPIO_InitStructer;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructer.GPIO_Pin=GPIO_Pin_6 | GPIO_Pin_7; //6--SCL 7--SDAGPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructer.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructer);
}/**
** 设置SDA为输出
**/
void SDA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructer;GPIO_InitStructer.GPIO_Pin= GPIO_Pin_7;GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructer.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructer);
}/**
** 设置SDA为输入
**/
void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStructer;GPIO_InitStructer.GPIO_Pin= GPIO_Pin_7;GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructer.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOB, &GPIO_InitStructer);
}//开始信号
void IIC_Start(void)
{SDA_OUT();IIC_SDA=1;IIC_SCL=1;delay_us(2);IIC_SDA=0;delay_us(2);IIC_SCL=0;delay_us(2);
}void IIC_Stop(void)
{IIC_SCL=1;IIC_SDA=0;delay_us(2);IIC_SDA=1;delay_us(2);
}/*
* 返回1--应答出错
* 放回0--应答正确
*/
u8 IIC_Wait_Ask(void)
{int count=0;SDA_IN();IIC_SCL=1;delay_us(2);while(READ_SDA){count++;if(count>250){IIC_Stop();return 1;} }IIC_SCL=0;delay_us(2);return 0;
}//写一个字节
void IIC_WriteByte(u8 data)
{u8 i;SDA_OUT();for(i=0;i<8;i++){IIC_SCL=0;delay_us(2);if(data & 0x80) //MSB,从高位开始一位一位传输IIC_SDA=1;elseIIC_SDA=0;IIC_SCL=1;delay_us(2);IIC_SCL=0;data<<=1;}
}u8 IIC_ReadByte(void)
{u8 data,i;IIC_SDA=1;delay_us(2);for(i=0;i<8;i++){data<<=1;IIC_SCL=0;delay_us(2);IIC_SCL=1;delay_us(2);if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7))data=data | 0x01;else data=data & 0xFE;}IIC_SCL=0;delay_us(2);return data;}void WriteCmd(u8 command)
{IIC_Start();IIC_WriteByte(0x78);//OLED地址IIC_Wait_Ask();IIC_WriteByte(0x00);//寄存器地址IIC_Wait_Ask();IIC_WriteByte(command);IIC_Wait_Ask();IIC_Stop();
}void WriteDat(u8 data)
{IIC_Start();IIC_WriteByte(0x78);//OLED地址IIC_Wait_Ask();IIC_WriteByte(0x40);//寄存器地址IIC_Wait_Ask();IIC_WriteByte(data);IIC_Wait_Ask();IIC_Stop();
}void OLED_Init(void)
{delay_ms(100); //这里的延时很重要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
}/*** @brief OLED_ON,将OLED从休眠中唤醒* @param 无* @retval 无*/
void OLED_ON(void)
{WriteCmd(0X8D); //设置电荷泵WriteCmd(0X14); //开启电荷泵WriteCmd(0XAF); //OLED唤醒
}/*** @brief OLED_SetPos,设置光标* @param x,光标x位置* y,光标y位置* @retval 无*/
void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{ WriteCmd(0xb0+y);WriteCmd(((x&0xf0)>>4)|0x10);WriteCmd((x&0x0f)|0x01);
}/*** @brief OLED_Fill,填充整个屏幕* @param fill_Data:要填充的数据* @retval 无*/
void OLED_Fill(unsigned char fill_Data)//全屏填充
{unsigned char m,n;for(m=0;m<8;m++){WriteCmd(0xb0+m); //page0-page1WriteCmd(0x00); //low column start addressWriteCmd(0x10); //high column start addressfor(n=0;n<128;n++){WriteDat(fill_Data);}}
}void OLED_CLS(void)//清屏
{OLED_Fill(0x00);
}/*** @brief OLED_ShowStr,显示codetab.h中的ASCII字符,有6*8和8*16可选择* @param x,y : 起始点坐标(x:0~127, y:0~7);* ch[] :- 要显示的字符串; * TextSize : 字符大小(1:6*8 ; 2:8*16)* @retval 无*/
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{unsigned char c = 0,i = 0,j = 0;switch(TextSize){case 1:{while(ch[j] != '\0'){c = ch[j] - 32;if(x > 126){x = 0;y++;}OLED_SetPos(x,y);for(i=0;i<6;i++)WriteDat(F6x8[c][i]);x += 6;j++;}}break;case 2:{while(ch[j] != '\0'){c = ch[j] - 32;if(x > 120){x = 0;y++;}OLED_SetPos(x,y);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i]);OLED_SetPos(x,y+1);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i+8]);x += 8;j++;}}break;}
}
STM32模拟IIC驱动OLED屏 原理+源码相关推荐
- 12. STM32——硬件IIC驱动OLED屏幕显示
STM32--硬件IIC驱动OLED屏幕显示 OLED屏幕 OLED屏幕特点 OLED屏幕接线说明 OLED屏幕显存 OLED屏幕原理 OLED屏幕常用指令 OLED屏幕字模软件的使用 写命令 写数据 ...
- 15. STM32——软件IIC驱动OLED屏幕显示字符、字符串、数字、汉字
STM32--软件IIC驱动OLED屏幕显示 OLED屏幕 写命令 写内容 对OLED写入一个字节 设置光标 启动OLED 关闭OLED 全屏填充(清屏) 显示字符 显示字符串 获取次方 显示数字 显 ...
- STM32模拟IIC驱动sht30温湿度传感器
最近有在使用sht30这个传感器,相比于新手常用的dht11传感器,sht30更精确,自己花了半小时调好了 所以拿出来分享给大家. sht30外观 驱动不是自己写的, 是采用CSDN上的一位朋友的 , ...
- 【GD32F310开发板试用】模拟IIC控制oled屏实验
1.用GD32模拟IIC时序,第一步是端口的定义和配置可以很方便的移植IIC程序,核心代码如下: #define IIC_SCL_PIN GPIO_PIN_6 #define IIC_SCL_GPIO ...
- STM32模拟IIC协议驱动AD7991/AD7995/AD7999芯片
STM32模拟IIC协议驱动AD7991/AD7995/AD7999芯片 AD7991/AD7995/AD7999是12位/10位/8位 4通道模拟输入的AD转换芯片 通信方式采用的是:I2C 芯片供 ...
- IIC 驱动OLED
IIC总线可以驱动很多器件,比较常见的有OLED.EEPROM存储器(AT24C02).温度传感器(LM75A).温湿度传感器(DHT11)等.有关IIC总线协议的基本原理可以看我之前的文章介绍.这一 ...
- esp32 spi 驱动 oled 屏显示来自 PC 的画面
esp32 spi 驱动 oled 屏显示来自 PC 的画面 实验代码 gayhub 实验源码 设备及运行环境 装有python的电脑 Python 3.8.2 (tags/v3.8.2:7b3ab5 ...
- STM32硬件SPI驱动OLED
文章目录 一.OLED相关 1.OLED简介 2.0.96寸的OLED模块概述 3.模块引脚说明 4.汉字点阵编码原理 二.硬件SPI 1.SPI简介 2.SPI的引脚映射关系 三.SPI驱动的OLE ...
- 【嵌入式】STM32基于SPI通信协议OLED屏显示
STM32基于SPI通信协议OLED屏显示 一.SPI协议和OLED介绍 1.SPI协议介绍 物理层 协议层 2.OLED显示屏介绍 二.显示个人学号姓名实验 1.题目要求 2.代码部分 1.完整代码 ...
最新文章
- 在商业中,如何与人工智能建立共生关系?
- 试着用React写项目-利用react-router解决跳转路由等问题(二)
- Python+BI可视化分析2000W数据之后,告诉你这届毕业生有多难
- 代码提示(支持3.X和4.X)—ArcGIS API forJavaScript
- 用setTimeout代替setInterval
- 《Java从入门到放弃》JavaSE入门篇:变量
- java闰年的计算方法_java中对 闰年的计算 以及月份天数
- 聊一聊我在腾讯的外包同事
- 2020ICPC南京 F Fireworks(概率,三分)
- UPX3.95程序压缩命令及使用方法
- 企查查、天眼查、启信宝的产品调研分析
- 换新电脑后怎么重装系统win7,win7安装教程
- C#的AES加密解密(ECB)
- 黑白电影变为彩色电影?这个方法分享给你
- java 字符串按小数点分割【问题剖析】
- bzoj3398 [Usaco2009 Feb]Bullcow 牡牛和牝牛
- sr550服务器服务器系统安装,sr550服务器阵列配置
- html 设置min height,HTML min-height用法总结
- 一篇重新带你认识:C语言
- 装了linux装不上win,在windos server 2008系统下装LINUX系统怎么装不上呢?
热门文章
- 【Paddle打比赛】全球人工智能技术创新大赛-商品标题实体识别竞赛_副本
- 牛客练习赛94F题解
- katana(武士刀)setuid提权
- 直接计算法弱磁控制策略 额定转速以下采用最大转矩电流比控制
- 当清晨的第一缕阳光洒在我的头发上, 我知道,一个崭新的太阳升起来了
- 全球及中国磷酸燃料电池行业销售状况及供需前景分析报告2022-2028年版
- 戴尔霄龙服务器销售商,搭载AMD EPYC“霄龙”处理器:DELL 戴尔 发布 EMC PowerEdge R7415 、R7425 和 R6415 服务器...
- 网站统计中的数据收集原理及实现(js埋点实现)
- Volo.Abp 整合 WebApiClient 从请求中获取 Headers 信息
- 计算机组成原理分部实验,计算机组成原理实验指导书.doc