一.实现功能:
指定位置在OLED中显示中文,英文,数字,图片BMP
直接上代码
二.IIC代码
//-----------------OLED IIC端口定义----------------
#define OLED_SCLK_Clr() GPIO_ResetBits(GPIOD,GPIO_Pin_6)//SDA IIC接口的时钟信号
#define OLED_SCLK_Set() GPIO_SetBits(GPIOD,GPIO_Pin_6)
#define OLED_SDIN_Clr() GPIO_ResetBits(GPIOD,GPIO_Pin_7)//SCL IIC接口的数据信号
#define OLED_SDIN_Set() GPIO_SetBits(GPIOD,GPIO_Pin_7)
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
开始信号
void IIC_Start()
{
OLED_SCLK_Set() ;
OLED_SDIN_Set();
OLED_SDIN_Clr();
OLED_SCLK_Clr();
}
停止信号
void IIC_Stop()
{
OLED_SCLK_Set() ;
// OLED_SCLK_Clr();
OLED_SDIN_Clr();
OLED_SDIN_Set();
}
等待应答
void IIC_Wait_Ack()
{
OLED_SCLK_Set() ;
OLED_SCLK_Clr();
}
写一个字节
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
OLED_SCLK_Clr();
for(i=0;i<8;i++)
{
m=da;
// OLED_SCLK_Clr();
m=m&0x80;
if(m==0x80)
{OLED_SDIN_Set();}
else OLED_SDIN_Clr();
da=da<<1;
OLED_SCLK_Set();
OLED_SCLK_Clr();
}
}
写命令
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
IIC_Wait_Ack();
Write_IIC_Byte(0x00); //write command
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Command);
IIC_Wait_Ack();
IIC_Stop();
}
写数据
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
IIC_Wait_Ack();
Write_IIC_Byte(0x40); //write data
IIC_Wait_Ack();
Write_IIC_Byte(IIC_Data);
IIC_Wait_Ack();
IIC_Stop();
}
选择写命令还是写指令
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
Write_IIC_Data(dat);
}
else {
Write_IIC_Command(dat);
}
}
OLED操作代码
满屏操作
void fill_picture(unsigned char fill_Data)
{
unsigned char m,n;
for(m=0;m<8;m++)
{
OLED_WR_Byte(0xb0+m,0); //page0-page1从第1页到第8页
OLED_WR_Byte(0x00,0); //low column start address开始地址
OLED_WR_Byte(0x10,0); //high column start address
for(n=0;n<128;n++)//第0列到127
{
OLED_WR_Byte(fill_Data,1);
}
}
}
坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);//设置哪页
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);//设置哪列,高4位地址
OLED_WR_Byte((x&0x0f),OLED_CMD);// 低4位地址
}
开始和关闭显示
//开启OLED显示
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
清屏操作
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
} //更新显示
}
以下是显示一个字符,字符串,中文,图片函数
说明:对于8*16字体,都是从设置的位置开始,先送上8列数据,完之后换页送下八列这样一个字符就完成
显示一个字符(X代表列,Y代表页数)
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
unsigned char c=0,i=0; ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210417174841645.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI0MDkzMDgx,size_16,color_FFFFFF,t_70)
int t=0;
c=chr-' ';//得到偏移后的值
// if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)//一个字符由两页的上八列和下八列组成
{
OLED_Set_Pos(x,y); //设置坐标
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);//一个字符的上八列
OLED_Set_Pos(x,y+1);//换页
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);//一个字符的下八列
}
else {
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c][i],OLED_DATA);
}
显示字符串
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)//Y(0-6),X(0-120)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);//显示完一个字符
x+=8;//列坐标加8开始写入
if(x>120){x=0;y+=2;}//两页写完后下页开始
j++;//下个字符
}
}
显示中文
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)//Y(0-6),X(0-112)
{
u8 t,adder=0;
OLED_Set_Pos(x,y); //设置开始
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);//把数组写入上8列
// adder+=1;
}
OLED_Set_Pos(x,y+1);//换页
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);//把数组写入下8列
// adder+=1;
}
}
显示图片
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
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;
else y=y1/8+1;
for(y=y0;y
初始化
//初始化SSD1306
void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOG, ENABLE); //使能PC,D,G端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //PD3,PD6推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD3,6
GPIO_SetBits(GPIOD,GPIO_Pin_6|GPIO_Pin_7); //PD3,PD6 输出高
//除了像素点作为数据写入显存外与命令有关的设置皆为命令型
OLED_WR_Byte(0xAE,OLED_CMD);//--display off关
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address列起始位置
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address列起始位置
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address 行起始位置
OLED_WR_Byte(0xB0,OLED_CMD);//--set page address从第一页开始
OLED_WR_Byte(0x81,OLED_CMD); // contract control对比控制度
OLED_WR_Byte(0xFF,OLED_CMD);//-- 对比控制度为256
OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction垂直翻转
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset设置向上偏移
OLED_WR_Byte(0x00,OLED_CMD);//偏移0
OLED_WR_Byte(0xD5,OLED_CMD);//set osc division设置分频
OLED_WR_Byte(0x80,OLED_CMD);//
OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
OLED_WR_Byte(0x05,OLED_CMD);//
OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
OLED_WR_Byte(0xF1,OLED_CMD);//
OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
OLED_WR_Byte(0x12,OLED_CMD);//
OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
OLED_WR_Byte(0x30,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
OLED_WR_Byte(0x14,OLED_CMD);//
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel开显示
}