STM32利用库函数驱动OLED

使用的1.3寸OLED是I2C接口的对外有四个引脚,分别是VCC、GND、SCL、SDL。
首先看一下运行的效果图:
在这里插入图片描述
成功在小屏幕上显示“你好”。
首先,我们需要配置好STM32的I2C外设,和GPIO的模式。
PB6—>SCL
PB7—>SDA
GPIO口配置为开漏输出模式。

void GPIO_Config()
{
	GPIO_InitTypeDef GPIO_STRUCT;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_STRUCT.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_STRUCT.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_STRUCT.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_STRUCT);	
}


void IIC_Config()
{
	I2C_InitTypeDef I2C_STRUCT;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
	
	
	I2C_DeInit(I2C1);
	I2C_STRUCT.I2C_Mode = I2C_Mode_I2C;
	I2C_STRUCT.I2C_DutyCycle = I2C_DutyCycle_2;
	I2C_STRUCT.I2C_OwnAddress1 = 0x90;
	I2C_STRUCT.I2C_Ack = I2C_Ack_Enable;
	I2C_STRUCT.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_STRUCT.I2C_ClockSpeed =400000 ;
	
	I2C_Init(I2C1,&I2C_STRUCT);
	I2C_Cmd(I2C1,ENABLE);
	
}```
I2C的配置:
I2C_Mode:配置I2C的工作模式为I2C。
I2C_DutyCycle:配置时钟线的占空比,这里配置占空比为2:1.
I2C_OwnAddress1:peizhi STM32的I2C设备自己的地址。
I2C_Ack:接收应答,每接收到一个字节就返回一个应答。
I2C_AcknowledgedAddress:选择I2C的寻址模式,这个根据连接的设备来进行选择。
I2C_ClockSpeed:设置I2C的传输速率,最大不得高于400kHz。
配置好以后使能I2C外设。

配置完成以后我们就要使用I2C来驱动OLED进行显示了。
第一步我们需要构建一个发送的最小单元,什么意思呢?就是定义一个函数,这个函数主要用来进行命令和数据的发送。为什么要这个样子呢?因为I2C在通信时过程比较繁琐,如果每次发送数据或者命令都要来配置一下的话,代码量会大大增加,并且程序的结构性也会被破坏,不利于阅读。

void WriteByte(uint8_t addr,uint8_t data)
{
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1,ENABLE);

while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1,0x78,I2C_Direction_Transmitter);

while(!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);

}’’’

这个就是发送的最小单元,在这里面接收两个参数,一个是地址,一个是数据。
内部实现的流程如下:
1、利用while循环判断I2C总线是否处于繁忙状态。
2、产生一个开始信号
3,、等待I2C_EVENT_MASTER_MODE_SELECT
4、发送目标设备的地址,也就是OLED屏幕的地址。
5,、等待事件I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
6、发送地址
7、等待事件I2C_EVENT_MASTER_BYTE_TRANSMITTED
8、发送数据
9、等待事件I2C_EVENT_MASTER_BYTE_TRANSMITTED
10、产生一个停止信号。

到此我们的最小发送单元配置完成。当我们再次发送命令和数据时不需要再这么复杂的敲写代码,直接调用该函数即可。
以下为发送命令和发送数据的封装函数:

void Write_Cmd(unsigned char command)
{
	WriteByte(0x00,command);
}

void Write_Dat(unsigned char data)
{
	WriteByte(0x40,data);
}

工欲善其事必先利其器,上面我们已经将如何发送数据写好了,下面我们就直接使用上面的函数来进行初始化等就可以了。
OLED屏幕的初始化:

void OLED_Init(void)
{
	int i = 10000;
	while(i--);//这个延时是必要的,没有使用定时器,就简单的写了个延时
	
	Write_Cmd(0xae);//开显示
	Write_Cmd(0x20);//设置内存寻址模式
	Write_Cmd(0x10);//00水平寻址01垂直10页面寻址
	Write_Cmd(0xb0);//为页面寻址模式设置页面开始地址0-7
	Write_Cmd(0xc8);//设置COM输出扫描方向
	Write_Cmd(0x00);//设置低列地址
	Write_Cmd(0x10);//设置高列地址
	Write_Cmd(0x40);//设置起始行地址
	Write_Cmd(0x81);//以下的使用的就去查找手册看一下吧!
	Write_Cmd(0xff);
	Write_Cmd(0xa1);
	Write_Cmd(0xa6);
	Write_Cmd(0xa8);
	Write_Cmd(0x3f);
	Write_Cmd(0xa4);
	Write_Cmd(0xd3);
	Write_Cmd(0x00);
	Write_Cmd(0xd5);
	Write_Cmd(0xf0);
	Write_Cmd(0xd9);
	Write_Cmd(0x22);
	Write_Cmd(0xda);
	Write_Cmd(0x12);
	Write_Cmd(0xdb);
	Write_Cmd(0x20);
	Write_Cmd(0x8d);
	Write_Cmd(0x14);
	Write_Cmd(0xaf);
}

初始完成,我们先来看一下OLED的屏幕的各个像素地址:
OLED的分别率是128x64.即是有128X64个像素点。所有的像素按照行分为8页,按列分为8段,每段里面有8行16列。
在这里插入图片描述
在这里插入图片描述
通常像素原点为左上角的(0,0)像素点,我们设置图像时,通常按照坐标来进行设置,但是我们设置的像素坐标需要转换为对应的地址。

void OLED_SetPos(unsigned char x,unsigned char y)
{
	Write_Cmd(0xb0+y);
	Write_Cmd(((x&0xf0)>>4)|0x10);
	Write_Cmd((x&0x0f)|0x01);
}

剩余的代码如下:

void OLED_Fill(unsigned char fill_data)
{
	unsigned char m,n;
	for(m = 0;m < 8;m++)
	{
		Write_Cmd(0xb0+m);
		Write_Cmd(0x00);
		Write_Cmd(0x10);
		for(n = 0;n < 130;n++)
		{
			Write_Dat(fill_data);
		}
				
	}
		
}

void OLED_CLS(void)
{
	OLED_Fill(0x00);
}


void OLED_ON(void)
{
	Write_Cmd(0x8d);
	Write_Cmd(0x14);
	Write_Cmd(0xaf);
}

void OLED_OFF(void)
{
	Write_Cmd(0x8d);
	Write_Cmd(0x10);
	Write_Cmd(0xae);
}

其中Write_Dat(0xf0);在屏幕上的像素分布如下:

0
0
0
0
1
1
1
1

所以在利用取模工具时,需要注意高低位的情况。

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值