一、 简介:
- 尺寸:0.96寸
- 控制芯片:SSD1306
- 管脚数量:4
- 引脚间距:2.54mm
- 分辨率:128*64,可以显示汉字、ASCII、图案,对比度高
- 可视角度:>160度
- 无需背光(OLED屏的特点)
- 供电:3V-5V
二、IIC底层
1.IIC电路连接:
GND---地
VCC---3.3V或5V
SCL---接单片机IO,作为IIC的SCL引脚
SDA---接单片机IO,作为IIC的SDA引脚
2.将模块连接好后编写(拷贝)IIC底层协议
根据自己定义的SCL和SDA在iic.h中修改宏
/*iic.h*/
#include "main.h"
#include "delay.h"
/*----------------------PIN DEFINE----------------------------*/
#define SCL GPIOC
#define SCL_PIN GPIO_PIN_0
#define SDA GPIOC
#define SDA_PIN GPIO_PIN_1
#define SCL_Clock_Enable __HAL_RCC_GPIOC_CLK_ENABLE
#define SDA_Clock_Enable __HAL_RCC_GPIOC_CLK_ENABLE
/*------------------------FUNCTION DEFINE--------------------------*/
#define SCL_W(X) do{X ? HAL_GPIO_WritePin(SCL,SCL_PIN,GPIO_PIN_SET):\
HAL_GPIO_WritePin(SCL,SCL_PIN,GPIO_PIN_RESET);}while(0)
#define SDA_W(X) do{X ? HAL_GPIO_WritePin(SDA,SDA_PIN,GPIO_PIN_SET):\
HAL_GPIO_WritePin(SDA,SDA_PIN,GPIO_PIN_RESET);}while(0)
#define SDA_R() HAL_GPIO_ReadPin(SDA,SDA_PIN)
#define delay() delay_us(5) //延时函数宏替换
#define Device_address 0x78
/*SDA,SCL引脚初始化*/
void IIC_Init(void);
void IIC_Start(void);
void IIC_SendByte(uint8_t byt);
uint8_t IIC_ReadByte(void);
uint8_t IIC_ReadACK(void);
void IIC_SendACK(uint8_t ack);
void IIC_Stop(void);
/*iic.c*/
#include "iic.h"
/*SDA,SCL引脚初始化*/
void IIC_Init(void)
{
GPIO_InitTypeDef gpio_init = {0};
SCL_Clock_Enable();
SDA_Clock_Enable();
gpio_init.Pin = SCL_PIN;
gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init.Pull = GPIO_NOPULL;
gpio_init.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(SCL,&gpio_init);
gpio_init.Pin = SDA_PIN;
gpio_init.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SDA,&gpio_init);
HAL_GPIO_WritePin(SCL,SCL_PIN,GPIO_PIN_SET);
HAL_GPIO_WritePin(SDA,SDA_PIN,GPIO_PIN_SET);
}
/*配置SDA引脚模式*/
void IIC_SDAMode_Set(uint32_t Mode)
{
GPIO_InitTypeDef gpio_init = {0};
gpio_init.Pin = SDA_PIN;
gpio_init.Mode = Mode;
if(Mode == GPIO_MODE_INPUT)
gpio_init.Pull = GPIO_PULLUP;
else
gpio_init.Pull = GPIO_NOPULL;
gpio_init.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(SDA,&gpio_init);
}
void IIC_Start(void)
{
IIC_SDAMode_Set(GPIO_MODE_OUTPUT_PP);
SDA_W(1);
SCL_W(1);
delay();
SDA_W(0);
delay();
SCL_W(0); //将时钟线拉低,告诉挂载在总线的其他设备总线在忙
delay();
}
void IIC_SendByte(uint8_t byt)
{
IIC_SDAMode_Set(GPIO_MODE_OUTPUT_PP);
SCL_W(0);
int i;
for(i = 7;i >= 0;i--)
{
if(byt & (1<<i))
SDA_W(1);
else
SDA_W(0);
delay();
SCL_W(1);
delay();
SCL_W(0);
delay();
}
}
uint8_t IIC_ReadByte(void)
{
int i;
uint8_t byte = 0;
IIC_SDAMode_Set(GPIO_MODE_INPUT);
for(i = 0;i < 8;i++)
{
SCL_W(1);
delay();
if(SDA_R())
byte |= 1<<(7-i);
delay();
SCL_W(0);
delay();
}
return byte;
}
uint8_t IIC_ReadACK(void)
{
uint8_t ack = 0;
IIC_SDAMode_Set(GPIO_MODE_INPUT);
SCL_W(1);
delay();
ack = SDA_R();
SCL_W(0);
return ack;
}
void IIC_SendACK(uint8_t ack)
{
IIC_SDAMode_Set(GPIO_MODE_OUTPUT_PP);
SCL_W(0);
SDA_W(ack);
delay();
SCL_W(1);
delay();
SCL_W(0);
}
void IIC_Stop(void)
{
IIC_SDAMode_Set(GPIO_MODE_OUTPUT_PP);
SDA_W(0);
delay();
SCL_W(1);
delay();
SDA_W(1);
}
三、SSD1306芯片
1.简介
SSD1306是一款带控制器的用于OLED点阵图形显示系统的单片CMOS OLED/PLED驱动器。它由128个SEG(列输出)和64个COM(行输出)组成。该芯片专为共阴极OLED面板设计。
SSD1306内置对比度控制器、显示RAM(GDDRAM)和振荡器,以此减少了外部元件的数量和功耗。该芯片有256级亮度控制。数据或命令由通用微控制器通过硬件选择的6800/8000系通用并行接口、I2C接口或串行外围接口发送。该芯片适用于许多小型便携式应用,如手机副显示屏、MP3播放器和计算器等。
2.了解SSD1306基本指令指令(具体参考文档)
四、0.96OLED代码
1、编写向OLED发送数据和发送命令函数
#define OLED_ADDRESS 0X78 //器件地址
#define OLED_CMD 0X00 //命令地址
#define OLED_DAT 0X40 //数据地址
/*向OLED发送写指令命令*/
void OLED_Write_Cmd(uint8_t cmd)
{
IIC_Start();
IIC_SendByte(OLED_ADDRESS);
IIC_ReadACK();
IIC_SendByte(OLED_CMD);
IIC_ReadACK();
IIC_SendByte(cmd);
IIC_ReadACK();
IIC_Stop();
}
/*向OLED发送写数据命令*/
void OLED_Write_DAT(uint8_t dat)
{
IIC_Start();
IIC_SendByte(OLED_ADDRESS);
IIC_ReadACK();
IIC_SendByte(OLED_DAT);
IIC_ReadACK();
IIC_SendByte(dat);
IIC_ReadACK();
IIC_Stop();
}
2.首先初始化OLED
/*初始化设置*/
void OLED_Init(void)
{
delay_ms(200);
OLED_Write_Cmd(0XA8); //设置分辨率
OLED_Write_Cmd(0X3F); //0X3F: 128 * 64 0X1F: 128 * 32
OLED_Write_Cmd(0XAE); //关闭显示
OLED_Write_Cmd(0XD3); //设置偏移
OLED_Write_Cmd(0X00);
OLED_Write_Cmd(0X40); //设置显示开始
OLED_Write_Cmd(0XA1); // 设置段重映射
OLED_Write_Cmd(0Xc8); //设置扫描方向 左->右
OLED_Write_Cmd(0XDA); //设置“COM引脚硬件配置
OLED_Write_Cmd(0X12); //128*64 0X02:128*32
OLED_Write_Cmd(0X81); //设置对比度
OLED_Write_Cmd(0XFF);
OLED_Write_Cmd(0XD9); //设置预充电时间
OLED_Write_Cmd(0XF1);
OLED_Write_Cmd(0XDB); //设置取消选择级别
OLED_Write_Cmd(0X20);
OLED_Write_Cmd(0XA4); //设置整个打开
OLED_Write_Cmd(0XA6); //设置反转和正常显示
OLED_Write_Cmd(0X8D); //电泵设置
OLED_Write_Cmd(0X14); //开启电荷泵
OLED_Write_Cmd(0XAF); //打开显示
OLED_Clear();
}
3.编写显示字符函数
/*向OLED中写入的字的起始位置
x:显示的横坐标(页)
y:显示字符的纵坐标(列)
*/
void OLED_SetPos(uint8_t x,uint8_t y)
{
OLED_Write_Cmd(0xb0+y); //写入页地址
OLED_Write_Cmd(0x10+(x>>4&0x0f)); //写入列地址高位
OLED_Write_Cmd((x & 0x0f)|0x01); //写入列地址低位
}
/*写入16*16字符或者汉字
x:显示的横坐标(页)
y:显示字符的纵坐标(列)
ch:取模后的汉字和字符数组
n: 显示ch数组中的第几个字符(从0开始)
*/
void OLED_Show_char(uint8_t x,uint8_t y,uint8_t *ch,uint8_t n)
{
uint8_t num;
uint16_t address = n*32; //定位字符的首地址在数组的位置
OLED_SetPos(x,y); //发送要写入的页地址和列地址起始位置 8行为一页,
for(num = 0; num < 16; num++) //写第一页
{
OLED_Write_DAT(ch[address++]); //向OLED发送数据
}
OLED_SetPos(x,y+1); //页地址+1
for(num = 0; num < 16; num++)//写第二页
{
OLED_Write_DAT(ch[address++]);
}
}
/*写入8*8字符或者汉字
x:显示的横坐标(页)
y:显示字符的纵坐标(列)
ch:取模后的汉字和字符数组
n: 显示ch数组中的第几个字符(从0开始)
*/
void OLED_Show_char8x8(uint8_t x,uint8_t y,uint8_t *ch,uint8_t n)
{
uint8_t num;
uint16_t address = n*8;
OLED_SetPos(x,y);
for(num = 0; num < 8; num++)
{
OLED_Write_DAT(ch[address++]);
}
}
/*
显示图片128*64
bmp:保存图片的模
*/
void OLED_Show_Bmp(uint8_t *bmp)
{
uint16_t address = 0;
for(uint8_t i = 0; i < 8;i++)
{
OLED_SetPos(0,i);
for(uint8_t j = 0; j < 128;j++)
OLED_Write_DAT(bmp[address++]);
}
}
4.其他函数
/*清除屏幕内容*/
void OLED_Clear(void)
{
uint8_t i,n;
for(i = 0;i < 8;i++) //128 * 64 一个单元16*8 一行8个字,循环清空8行
{
OLED_Write_Cmd(0xb0|i); //配置0~7页的那一页
OLED_Write_Cmd(0x00); //设置操作的低位(列)
OLED_Write_Cmd(0x10); //设置操作的高位(列)
for(n = 0;n < 128;n++)
OLED_Write_DAT(0x00); //0xff:白屏,0x00:黑屏
}
}
/*oled开启显示*/
void OLED_Display_ON(void)
{
OLED_Write_Cmd(0X8D); //开启电荷泵
OLED_Write_Cmd(0x14);
OLED_Write_Cmd(0XAF); //打开显示
}
/*oled关闭显示*/
void OLED_Display_OFF(void)
{
OLED_Write_Cmd(0X8D); //开启电荷泵
OLED_Write_Cmd(0x14);
OLED_Write_Cmd(0XAE); //关闭显示
}
oled.h
#ifndef _OLED_H_
#define _OLED_H_
#include "main.h"
#include "iic.h"
#define OLED_ADDRESS 0X78
#define OLED_CMD 0X00
#define OLED_DAT 0X40
void OLED_Init(void);
void OLED_Display_OFF(void);
void OLED_Display_ON(void);
void OLED_Clear(void);
void OLED_Show_Char(uint8_t x,uint8_t y,uint8_t g,uint8_t k,uint8_t *dat);
void OLED_Show_char(uint8_t x,uint8_t y,uint8_t *ch,uint8_t n);
void OLED_Show_Num(uint8_t x,uint8_t y,uint8_t num);
void OLED_Show_char8x8(uint8_t x,uint8_t y,uint8_t *ch,uint8_t n);
void OLED_Show_Bmp(uint8_t *bmp);
#endif
五、字符取模
oled
六、图片取模
OLED_图片_BMP格式_再取模图片