资讯详情

[单片机框架][drivers层][oled][SSD1306] oled的使用说明

IIC接口引脚分布

SSD1306在I2C总线模式下的接口分布

数据/命令引脚
[D7:D3] D2 D1 D0
共阴 SDA_OUT SDA_IN SCL
控制引脚
E R/W# CS# D/C# RES#
共阴 共阴 共阴 SA0 RES#

IIC通信接口由总线的数据信号SDA(SDA_OUT和SDA_IN)时钟信号和总线SCL组成。 上拉电阻必须连接数据和时钟信号。

SA0 从机地址引脚, RES#为设备初始化引脚。

1.SDA 数据信号线

SDA它是主机和机间数据收发和响应的通道。需要注意的是,SDA引脚的ITO 电阻和上拉电阻有潜在的分压,

结果就是,SDA在线响应信号可能无法达到有效的低电平。

SDAOUT和SDAIN数据信号线连接在一起SDA引出,SDAIN必须将引脚连接起来充当SDA。SDAOUT可能会断开引脚。

当SDAOUT当引脚断开时,I2C总线中的响应信号将被忽略。

2.SCL 时钟信号线

信息在IIC总线中的传输遵循时钟信号SCL。 数据位的每次传输都是在SCL在单个时钟周期内进行。

3.SA0 丛机地址位

在IIC在总线发送或接收任何信息之前,SSD必须先识别从机地址。 设备将响应字节格式如下:

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
0 1 1 1 1 0 SA0 R/W#

”D/C#“作为SA0用于选择地址。SA0位为从机地址提供扩展位。 “0111100”或“0111101”均可作为SSD从机地址1306。 “R/W#用于确定IIC总线接口的操作模式。 R/W#=一、读取模式。 R/W#=0,为写入模式。

  1. 每次接到命令字节或数据字节后,从机都会产生响应信号。

  2. 当需要写入时,数据通信通过停止条件结束。停止条件是在SCL在高电平保持期间捕获SDA上升沿。

/******************************************************************************** * @file oled_core.c * @author jianqiang.xue * @Version V1.0.0 * @Date 2021-08-07 * @brief 参考:https://www.cnblogs.com/Gimiracle/p/13520991.html * 笔记: * 得到回应后,发送一个控制字节,由Co位和D/C由00000和尾部组成。 * D7 D6 D5 D4 D3 D2 D1 D0 * Co D/C# 0 0 0 0 0 0 * a)Co如果位于0,则后续字节为数据。 * D7 D6 D5 D4 D3 D2 D1 D0 * Co D/C# 0 0 0 0 0 0 * a)Co如果位于0,则后续字节为数据。D/C#确定下一个数据字节作为命令或数据。 * b)D/C#位置设置为0,后续数据字节定义为命令。 D/C#位置设置为1 ,后续数据字节定义为数据并存储在中GDDRAM上。 * 每次数据写入后,GDDRAM自动增加一个列地址指针。 ********************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include <stdint.h> #include <stdbool.h> #include <string.h>  #include "bsp_i2c.h" /* Private includes ----------------------------------------------------------*/ #include "oled_core.h" #include "SSD1306.h" #include "os_api.h" /* Private define ------------------------------------------------------------*/ #define FUNC_CMD 0x00 #define FUNC_DATA 0x40 /* Private typedef -----------------------------------------------------------*/ static const oled_cfg_t g_oled_info = { 
          .i2c_bus = I2C_BUS0, .dev_addr = 0x78, .x_max = 128, .y_max = 64, }; /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ static bool g_oled_state = false; static const uint8_t g_cmd_oled_init_cfg[] = { 
          FUNC_CMD, /*命令类*/ 0xAE, /*关闭oled面板*/ 0x00, /*设置低列地址*/ 0x10, /*设置高列地址*/ 0x40, /*设置起始行地址*/ 0x81, /*对比度设置,可设置亮度*/ 0XFF, /*对比度值0-255*/ 0XA1, /*设置分段/列映射 0xa0左右反置 0xa1正常*/ 0XC8, /*设置COM/行扫描方向 0xc0上下反置 0xc8正常*/ 0XA6, /*设置正常显示 0xa7逆显示*/ 0XA8, /*设置多路复用比率(1到64)*/ 0X3F, /*1/64负荷*/ 0XD3, /*设置显示偏移移位映射RAM计数器*/ 0x00, /*RAM计数器值:0x00~0x3F*/ 0XD5, /*设置显示分时比/振荡器频率*/ 0X80, /*设置分频比,将时钟设置为100帧/秒(默认值)*/ 0XD9, /*设置 预充电周期*/ 0XF1, /*预充电设为15时钟,放电设为1时钟*/ 0XDA, /*设置com引脚硬件配置*/ 0X12, /*默认值*/ 0XDB, /*设置 共通电位 (高)*/ 0X40, /*设置VCOM取消选择级别*/ 0X20, /*设置页面寻址模式(0x00/0x01/0x02)*/ 0X02, /*默认值*/ 0X8D, /*设置预充电 启用/禁用*/ 0X14, /*set(0x10) disable*/ 0XA4, /*A4h,X0 =0b:恢复 RAM内容的显示(RESET)*/ 0XA6, /*A6h, X[0]=0b:正常显示(RESET)*/ }; static const uint8_t g_cmd_oled_open_display[] = { 
          FUNC_CMD, /*命令类*/ 0X8D, /*设置 共通电位 (高)*/ 0X14, 0XAF /*显示开,正常模式 */ }; static const uint8_t g_cmd_oled_close_display[] = { 
          FUNC_CMD, /*命令类*/ 0X8D, /*设置 共通电位 (高)*/ 0X14, 0XAE /*显示关 (睡眠模式)*/ }; static const uint8_t g_cmd_oled_null[129] = { 
         FUNC_DATA, 0}; static uint8_t g_oled_data_buff[128] = { 
         0}; /* Public function prototypes -----------------------------------------------*/ /** * @brief oled初始化 * @note 由于单片机上电初始化比OLED快,所以必须加上延迟,等待OLED上复位完成,约100-200ms * @retval None */ uint8_t oled_init(void) { 
          return bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, (uint8_t *)g_cmd_oled_init_cfg, sizeof(g_cmd_oled_init_cfg)); } /** * @brief 得到当前状态 * @note NULL * @retval 0--空闲 1--忙 */ bool oled_get_state(void) { 
          return g_oled_state; } uint8_t oled_get_x_max(void) { 
          return g_oled_info.x_max; } uint8_t oled_get_y_max(void) { 
          return g_oled_info.y_max; } void oled_cls(void) { 
          if (g_oled_state) { 
          return; } g_oled_state = true; uint8_t data[] = { 
         FUNC_CMD, 0xb0, 0x00, 0x10}; for (uint8_t i = 0; i < g_oled_info.y_max / 8; i++) { 
          data[1] = 0xb0 + i; bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, data, sizeof(data)); bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, (uint8_t *)g_cmd_oled_null, sizeof(g_cmd_oled_null)); } g_oled_state = false; } void oled_clear(uint8_t x, uint8_t y, uint8_t x1, uint8_t y1) { 
          if (g_oled_state) { 
          return; } g_oled_state = true; uint8_t data[] = { 
         FUNC_CMD, 0xb0, 0x00, 0x10}; for (uint8_t i = y; i < y1; i++) { 
          data[1] = 0xb0 + i; data[2] = (x & 0x0F); data[3] = ((x & 0xF0) >> 4) | 0x10; bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, data, sizeof(data)); bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, (uint8_t *)g_cmd_oled_null, x1-x); } g_oled_state = false; } uint8_t oled_open_display(void) { 
          return bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, (uint8_t *)g_cmd_oled_open_display, sizeof(g_cmd_oled_open_display)); } uint8_t oled_close_display(void) { 
          return bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, (uint8_t *)g_cmd_oled_close_display, sizeof(g_cmd_oled_close_display)); } uint8_t oled_set_pos(uint8_t x, uint8_t y) { 
          uint8_t data[] = { 
         FUNC_CMD, 0xb0, 0x00, 0x00}; data[1] += y; data[2] = ((x & 0xF0) >> 4) | 0x10; data[3] = (x & 0x0F); return bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, data, sizeof(data)); } uint8_t oled_write_data(uint8_t *data, uint16_t len) { 
          if (g_oled_state) { 
          return OS_EVENT_TIMEOUT; } g_oled_state = false; memset(g_oled_data_buff, 0, len + 1); g_oled_data_buff[0] = FUNC_DATA; memcpy(g_oled_data_buff + 1, data, len); return bsp_i2c_write_nbyte(g_oled_info.i2c_bus, g_oled_info.dev_addr, g_oled_data_buff, len+1); } /* Private function prototypes -----------------------------------------------*/ 
#ifndef __OLED_CORE_H
#define __OLED_CORE_H

#include <stdint.h>
#include <stdbool.h>
#include "bsp_i2c.h"

typedef struct
{ 
        
    bsp_i2c_bus_t i2c_bus;
    uint8_t dev_addr;      // 8bit addr
    uint8_t x_max;
    uint8_t y_max;
}oled_cfg_t;

uint8_t oled_init(void);
uint8_t oled_uninit(void);

bool oled_get_state(void);
uint8_t oled_get_x_max(void);
uint8_t oled_get_y_max(void);

uint8_t oled_open_display(void);
uint8_t oled_close_display(void);

void oled_cls(void);
void oled_clear(uint8_t x, uint8_t y, uint8_t x1, uint8_t y1);

uint8_t oled_set_pos(uint8_t x, uint8_t y);
uint8_t oled_write_data(uint8_t *data, uint16_t len);

#endif

标签: d5d电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台