参考博客:SSD1306驱动理解_夏沫的杂物间-CSDN博客_ssd1306驱动

IIC学习:  I2C 协议分析和学习_Car12-CSDN博客

SSD1306 IIC读写时序

1、 第一个字节(Slave Address )发送的是地址 和 读写属性(一般只会写数据);SA0(D/C引脚就是SA0)决定了从机的地址; 0x78

2、第二个字节(control byte )决定了第三个字节是命令还是数据

a) Co = 0 代表后边全是数据

b) D/C = 0 代表后边是数据(0x00);D/C = 0 代表后边是命令;(0x40)

//发送一个字节
//向SSD1306写入一个字节。
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat,u8 mode)
{I2C_Start();Send_Byte(0x78);//发送地址和写指令I2C_WaitAck();if(mode){Send_Byte(0x40);//发命令}else{Send_Byte(0x00);//发数据}I2C_WaitAck();Send_Byte(dat);I2C_WaitAck();I2C_Stop();
}

第一次初始化流程

第二个初始化流程

1、地址设置命令(0x00-0x0F),高4位强制为0
(1)页地址模式下设置列起始地址低4位

(2)页地址模式下设置列起始地址高4位(0x10-ox1F),高4位强制为1

(3)设置内存地址寻址模式(Set Memory Addressing Mode)(20h)

带有参数:02 表示页寻址模式

通常在页地址模式下访问GDDRAM, 需要如下步骤来定义起始RAM访问指针指向:

  • 通过命令(B0h-B7h)设置目标显示位置页起始地址
  • 通过命令(00h-0Fh)设置列起始地址低位
  • 通过命令(10h-1Fh)设置列起始地址高位
void OLED_Init(void)
{OLED_Config();OLED_SCK(HIGH); // 空闲态时,SCLK处于高电平OLED_CS(HIGH);  // 关闭选择输入/* 从上电到下面开始初始化要有足够的时间,即等待 RC复位完毕 */OLED_RST(LOW); // 复位(低电平有效)OLED_Delay_ms(100);OLED_RST(HIGH);OLED_Delay_ms(30);/*//官方的驱动流程OLED_Write_Cmd(0xA8); // 设置多路传输比率 -- set multiplex ratio (16 to 63)OLED_Write_Cmd(0x3F); // \ 1 / 64 dutyOLED_Write_Cmd(0xD3); // 设置显示偏移 -- set display offset (0x00~0x3F)OLED_Write_Cmd(0x00); // \ not offset 偏移值是 0OLED_Write_Cmd(0x40); // 设置设置屏幕(GDDRAM)起始行 -- Set Display Start Line (0x40~0x7F)/配置显示方向OLED_Write_Cmd(0xA1); // 设置段重映射 -- Set SEG / Column Mapping     0xA0左右反置(复位值) 0xA1正常(重映射值)OLED_Write_Cmd(0xC8); // 设置行输出扫描方向 -- Set COM / Row Scan Direction   0xc0上下反置(复位值) 0xC8正常(重映射值)OLED_Write_Cmd(0xDA); // 设置列引脚硬件配置 -- set com pins hardware configurationOLED_Write_Cmd(0x12); // \ Sequential COM pin configuration,Enable COM Left/Right remapOLED_Write_Cmd(0x81); // 设置对比度 -- set contrast control register (0x00~0x100)OLED_Write_Cmd(0xCF); // \ Set SEG Output Current Brightness//根据RAM 内容显示OLED_Write_Cmd(0xA4); //  全局显示开启(黑屏/亮屏)  (0xA4 根据RAM 内容显示 / 0xA5 每个oled都点亮 全部显示)//正常显示方式(不是反现)OLED_Write_Cmd(0xA6); // 设置显示方式(正常/反显) -- set normal display (0xA6 / 0xA7)//设置显示时钟分频因子/振荡器频率OLED_Write_Cmd(0xD5); // 设置显示时钟分频因子/振荡器频率 -- set display clock divide ratio/oscillator frequencyOLED_Write_Cmd(0x80); // A[3:0] 分频因子, A[7:4] 震荡频率设置 Set Clock as 100 Frames/SecOLED_Write_Cmd(0x8D); // 电荷泵设置 -- set Charge Pump enable / disable (0x14 / 0x10)OLED_Write_Cmd(0x14); // \ 启用电荷泵 Enable charge pump during display onOLED_Write_Cmd(0xAF); // 打开OLED -- turn on oled panel : OXAE 关闭OLED 休眠模式 0xaf 打开oled//官方的驱动流程*/OLED_Write_Cmd(0xAE); // 关闭OLED -- turn off oled panelOLED_Write_Cmd(0xD5); // 设置显示时钟分频因子/振荡器频率 -- set display clock divide ratio/oscillator frequencyOLED_Write_Cmd(0x80); // A[3:0] 分频因子, A[7:4] 震荡频率设置 Set Clock as 100 Frames/SecOLED_Write_Cmd(0x20); // 设置内存寻址模式 -- Set Memory Addressing Mode (0x00 / 0x01 / 0x02)OLED_Write_Cmd(0x02); // \ Page Addressing 设置为页寻址模式OLED_Write_Cmd(0xA8); // 设置多路传输比率 -- set multiplex ratio (16 to 63)OLED_Write_Cmd(0x3F); // \ 1 / 64 dutyOLED_Write_Cmd(0xDA); // 设置列引脚硬件配置 -- set com pins hardware configurationOLED_Write_Cmd(0x12); // \ Sequential COM pin configuration,Enable COM Left/Right remap/* ----- 方向显示配置 ----- */OLED_Write_Cmd(0xA1); // 设置段重映射 -- Set SEG / Column Mapping     0xA0左右反置(复位值) 0xA1正常(重映射值)OLED_Write_Cmd(0xC8); // 设置行输出扫描方向 -- Set COM / Row Scan Direction   0xc0上下反置(复位值) 0xC8正常(重映射值)/* ----- END ----- */OLED_Write_Cmd(0x40); // 设置设置屏幕(GDDRAM)起始行 -- Set Display Start Line (0x40~0x7F)OLED_Write_Cmd(0xD3); // 设置显示偏移 -- set display offset (0x00~0x3F)OLED_Write_Cmd(0x00); // \ not offset 偏移值是 0OLED_Write_Cmd(0x81); // 设置对比度 -- set contrast control register (0x00~0x100)OLED_Write_Cmd(0xCF); // \ Set SEG Output Current BrightnessOLED_Write_Cmd(0xD9); // 设置预充电期间的持续时间 -- set pre-charge periodOLED_Write_Cmd(0xF1); // \ Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_Write_Cmd(0xDB); // 调整VCOMH调节器的输出 -- set vcomh (0x00 / 0x20 / 0x30)OLED_Write_Cmd(0x20); // \ Set VCOM Deselect LevelOLED_Write_Cmd(0x8D); // 电荷泵设置 -- set Charge Pump enable / disable (0x14 / 0x10)OLED_Write_Cmd(0x14); // \ 启用电荷泵 Enable charge pump during display onOLED_Write_Cmd(0xA4); //  全局显示开启(黑屏/亮屏)  (0xA4 根据RAM 内容显示 / 0xA5 每个oled都点亮 全部显示)OLED_Write_Cmd(0xA6); // 设置显示方式(正常/反显) -- set normal display (0xA6 / 0xA7)OLED_Write_Cmd(0xAF); // 打开OLED -- turn on oled panel : OXAE 关闭OLED 休眠模式 0xaf 打开oledOLED_Fill(0x00);      // 初始清屏OLED_Coord(0, 0);     // 设置原点坐标(0, 0)
}

代码

/************************************************************************************
*  Copyright (c), 2014, HelTec Automatic Technology co.,LTD.
*            All rights reserved.
*
* Http:    www.heltec.cn
* Email:   cn.heltec@gmail.com
* WebShop: heltec.taobao.com
*
* File name: OLED_I2C.c
* Project  : HelTec.uvprij
* Processor: STM32F103C8T6
* Compiler : MDK fo ARM
*
* Author : 小林
* Version: 1.00
* Date   : 2014.4.8
* Email  : hello14blog@gmail.com
* Modification: none
*
* Description:128*64点阵的OLED显示屏驱动文件,仅适用于惠特自动化(heltec.taobao.com)的SD1306驱动IIC通信方式显示屏
*
* Others: none;
*
* Function List:
*   1. void I2C_Configuration(void) -- 配置CPU的硬件I2C
* 2. void I2C_WriteByte(uint8_t addr,uint8_t data) -- 向寄存器地址写一个byte的数据
* 3. void WriteCmd(unsigned char I2C_Command) -- 写命令
* 4. void WriteDat(unsigned char I2C_Data) -- 写数据
* 5. void OLED_Init(void) -- OLED屏初始化
* 6. void OLED_SetPos(unsigned char x, unsigned char y) -- 设置起始点坐标
* 7. void OLED_Fill(unsigned char fill_Data) -- 全屏填充
* 8. void OLED_CLS(void) -- 清屏
* 9. void OLED_ON(void) -- 唤醒
* 10. void OLED_OFF(void) -- 睡眠
* 11. void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize) -- 显示字符串(字体大小有6*8和8*16两种)
* 12. void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N) -- 显示中文(中文需要先取模,然后放到codetab.h中)
* 13. void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]) -- BMP图片
*
* History: none;
*
*************************************************************************************/#include "OLED_I2C.h"
#include "delay.h"
#include "codetab.h"void I2C_Configuration(void)
{I2C_InitTypeDef  I2C_InitStructure;GPIO_InitTypeDef  GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);/*STM32F103C8T6芯片的硬件I2C: PB6 -- SCL; PB7 -- SDA */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;//I2C必须开漏输出GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_DeInit(I2C1);//使用I2C1I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x30;//主机的I2C地址,随便写的I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 400000;//400KI2C_Cmd(I2C1, ENABLE);I2C_Init(I2C1, &I2C_InitStructure);
}void I2C_WriteByte(uint8_t addr,uint8_t data)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 默认0x78while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, addr);//寄存器地址while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, data);//发送数据while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线
}void WriteCmd(unsigned char I2C_Command)//写命令
{I2C_WriteByte(0x00, I2C_Command);
}void WriteDat(unsigned char I2C_Data)//写数据
{I2C_WriteByte(0x40, I2C_Data);
}void OLED_Init(void)
{DelayMs(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
}void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{ WriteCmd(0xb0+y);WriteCmd(((x&0xf0)>>4)|0x10);WriteCmd((x&0x0f)|0x01);
}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 address 列地址的低4位WriteCmd(0x10);       //high column start address 列地址的高4位for(n=0;n<128;n++){WriteDat(fill_Data);}}
}void OLED_CLS(void)//清屏
{OLED_Fill(0x00);
}//--------------------------------------------------------------
// Prototype      : void OLED_ON(void)
// Calls          :
// Parameters     : none
// Description    : 将OLED从休眠中唤醒
//--------------------------------------------------------------
void OLED_ON(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X14);  //开启电荷泵WriteCmd(0XAF);  //OLED唤醒
}//--------------------------------------------------------------
// Prototype      : void OLED_OFF(void)
// Calls          :
// Parameters     : none
// Description    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
//--------------------------------------------------------------
void OLED_OFF(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X10);  //关闭电荷泵WriteCmd(0XAE);  //OLED休眠
}//--------------------------------------------------------------
/*
Prototype      : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
Calls          :
Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7);
ch[] -- 要显示的字符串;
TextSize -- 字符大小(1:6*8 ; 2:8*16)
Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
//--------------------------------------------------------------
*/
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;}
}//--------------------------------------------------------------
// Prototype      : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls          :
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
// Description    : 显示codetab.h中的汉字,16*16点阵
//--------------------------------------------------------------
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{unsigned char wm=0;unsigned int  adder=32*N;OLED_SetPos(x , y);for(wm = 0;wm < 16;wm++){WriteDat(F16x16[adder]);adder += 1;}OLED_SetPos(x,y + 1);for(wm = 0;wm < 16;wm++){WriteDat(F16x16[adder]);adder += 1;}
}//--------------------------------------------------------------
// Prototype      : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls          :
// Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7);
//                  x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description    : 显示BMP位图
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{unsigned int j=0;unsigned char x,y;if(y1%8==0)y = y1/8;elsey = y1/8 + 1;for(y=y0;y<y1;y++){OLED_SetPos(x0,y);for(x=x0;x<x1;x++){WriteDat(BMP[j++]);}}
}
#ifndef __OLED_I2C_H
#define __OLED_I2C_H#include "stm32f10x.h"#define OLED_ADDRESS    0x78 //通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78void I2C_Configuration(void);
void I2C_WriteByte(uint8_t addr,uint8_t data);
void WriteCmd(unsigned char I2C_Command);
void WriteDat(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 char y, unsigned char ch[], unsigned char TextSize);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);#endif

ssd1306 OLED 初始化流程相关推荐

  1. QUALCOMM MDM9X15 LCD初始化流程

    先来看一下 board-9615.c 文件 MACHINE_START(MSM9615_CDP, "QCT MSM9615 CDP") .map_io = msm9615_map_ ...

  2. 【51单片机快速入门指南】4.2: SSD1306 OLED屏(0.96寸、1.3寸)的I2C控制详解

    目录 硬知识 SSD1306简介 I2C 接口 从机地址位(SA0) I2C 总线写数据 命令解码器 晶振电路和显示时间发生器 复位 图形显示数据RAM (GDDRAM) 命令表 基本命令表 部分指令 ...

  3. ESP32开发之旅——ssd1306 OLED屏的使用

    ESP32开发之旅--ssd1306 OLED屏的使用 前言 在本文中,您将学会ssd1306 OLED屏在ESP32中的使用,本文提供了简单的示例供学习参考. 需要注意的是,本文中的ESP32是使用 ...

  4. STM32—4线SPI驱动SSD1306 OLED

    文章目录 一.OLED简介 二.驱动SSD1306所需知识 1.引脚介绍 2.通信时序 3.显存GRAM 4.字库 5.SSD1306基本命令 三.代码讲解 1.相关引脚配置 2.模拟SPI通信 3. ...

  5. 0.91寸 SSD1306 OLED介绍(一) --- 整体介绍/IIC时序介绍

    在介绍0.91寸 SSD1306之前先附上模块链接:点击购买SSD1306 OLED显示模块 1. SSD1306 OLED介绍 OLED,即有机发光二极管(Organic Light-Emittin ...

  6. F411-WeAct(二)IIC 驱动SSD1306 OLED(0.96寸)

    F411-WeAct(二)IIC 驱动SSD1306 OLED(0.96寸) 硬件资源介绍 F411-WeAct开发板 OLED STM32初始化 初始化时钟 外设初始化 正式开始 下载源代码 硬件资 ...

  7. Linux内核网络栈1.2.13-网卡设备的初始化流程

    参考资料 <<linux内核网络栈源代码情景分析>> 网卡设备的初始化 本文主要描述一下网卡设备的整个初始化的过程,该过程主要就是根据设备的硬件信息来获取与传输网络数据,注册相 ...

  8. 开机流程简介--init 处理系统初始化流程 (/etc/rc.d/rc.sysinit)

    init 处理系统初始化流程 (/etc/rc.d/rc.sysinit) 还记得上面提到 /etc/inittab 里头有这一句' si::sysinit:/etc/rc.d/rc.sysinit ...

  9. 关于Flutter初始化流程,我必须告诉你的是...

    作者:闲鱼技术-然道 1. 引言 最近在做性能优化的时候发现,在混合栈开发中,第一次启动Flutter页面的耗时总会是第二次启动Flutter页面耗时的两倍左右,这样给人感觉很不好.分析发现第一次启动 ...

最新文章

  1. 左神讲算法——二分法及其拓展
  2. 找出文件1中有而文件2中没有的数据
  3. UVA1455 - Kingdom(并查集 + 线段树)
  4. cnblogs反对按钮点击测试
  5. python 学习之FAQ:find 与 find_all 使用
  6. list(列表) python
  7. SAP Commerce Cloud OCC User Role
  8. Unity3D在C#编程中的一些命名空间的引用及说明
  9. jzoj4230-淬炼神体【0/1分数规划】
  10. 【HDU - 1302】The Snail (模拟,水题)
  11. 【JNI知识一】--JNI接口函数与指针
  12. webuploader横向按钮样式
  13. 苹果开发者账号添加受信任电话号
  14. 华为篇-嵌入式公司待遇盘点-第二期
  15. java建立_java建立一个类
  16. 【产业互联网周报】云厂商加速布局政企市场:华为云发布七款新产品;腾讯政务战略升级;钉钉发布数字区县解决方案...
  17. 为何C语言如此强大?到底可以做什么?
  18. lol无限乱斗服务器,LOL2019新模式无限乱斗怎么玩 LOL无限乱斗玩法攻略
  19. Android4.4深入浅出之SurfaceFlinger与Client通信框架(一)
  20. 【USB笔记】 USB2.0 包格式 握手包Handshake Packets

热门文章

  1. 布朗的计算机排名,布朗大学计算机工程硕士排名第26(2020年TFE Times排名)
  2. 算法提高 理财计划(java)
  3. series、dataframe转为tensor格式数据
  4. R语言switch语句报错Error: duplicate ‘switch‘ defaults
  5. docker删除mongo数据库库_Docker 搭建MongoDB环境
  6. 可行性研究和软件项目计划主要完成什么工作?_软件生命周期
  7. java java 检查型异常_如何整合Java中的有效性检查和异常抛出?
  8. oracle 游标的替代,Oracle中replace函数和translate函数以及简单的游标
  9. react.js从入门到精通(六)——路由的使用
  10. maven 打包失败 提示找不到jar的问题