0.96OLED STM32 SPI驱动(一)

闲来无聊,翻出了一个OLED,本来想串流做个小显示器用,感觉难度太大。将就变成了下面这 个样子,姑且叫火柴人大乱斗之OLED。

火柴人之OLED

分两步走,先驱动OLED能显示一副图片,本篇讲述此内容。

第二步显示动画,放在下一篇中讲。

一、硬件连接、引脚确定。

查资料得到此OLED为SPI通信,SCL对应连接MCU SPI的SCK,SDA对应连接MCU SPI的MOSI,RST为OLED复位引脚,D/C为写入命令/数据选择引脚。片选默认已经帮我们选好了,所以不需要设置。

此次选择的控制板为STM32F103C8T6最小系统,选择SPI1为驱动引脚,GPIOA2连接D/C,GPIOB4连接OLED复位RST引脚。

二、STM32CUBEMX配置

主要是SPI部分的设置,我们只需要发数据给OLED,不需要从OLED读取数据,所以Mode可以选择Transmit Only Master。另外 SPI的波特率不能太高,设置为低于20MBits/s,其它的默认即可。IDE我选择STM32CUBEIDE,最后生成代码。

三、驱动代码移植

从网上找到OLED的驱动代码,加入工程中。此驱动代码还不能使用,需要修改几个地方,具体如下。

修改OLED_WR_Byte函数,此函数作用为向OLED发送命令或数据。

/*
函数功能: 向SSD1106写入一个字节
函数参数: dat:要写入的数据/命令
          cmd:数据/命令标志  0表示命令  1表示数据
*/
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
{
	   if(cmd==0)//	写命令
	   {
		HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_RESET);
		HAL_SPI_Transmit(&hspi1, &dat, 1, 0xffff);
	   	//HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_SET);
	   }
	   else if(cmd==1)//写数据
	   {
		HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_SET);
		HAL_SPI_Transmit(&hspi1, &dat, 1, 0xffff);
		//HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_RESET);
	   }
}

修改OLED_Init函数以正确Reset OLED。

/*********************OLED初始化************************************/
void OLED_Init(void)
{
	HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, GPIO_PIN_RESET);
	HAL_Delay(50);
	HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, GPIO_PIN_SET);
	HAL_Delay(500);								//初始化之前的延时很重要!
	OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
	OLED_WR_Byte(0x00,OLED_CMD);//设置低列地址
	OLED_WR_Byte(0x10,OLED_CMD);//设置高列地址
	OLED_WR_Byte(0x40,OLED_CMD);//设置起始行地址,集映射RAM显示起始行(0x00~0x3F)
	OLED_WR_Byte(0x81,OLED_CMD);//设置对比度控制寄存器
	OLED_WR_Byte(0xCF,OLED_CMD);//设置SEG输出电流亮度
	OLED_WR_Byte(0xA1,OLED_CMD);//段重定义设置,bit0:0,0->0;1,0->127; 0xa0左右反置 0xa1正常
	OLED_WR_Byte(0xC8,OLED_CMD);//设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数   0xc0上下反置 0xc8正常
	OLED_WR_Byte(0xA6,OLED_CMD);//设置正常显示(设置显示方式;bit0:1,反相显示;0,正常显示	)
	OLED_WR_Byte(0xA8,OLED_CMD);//设置驱动路数 设置多路复用比(1比64)
	OLED_WR_Byte(0x3F,OLED_CMD);//1/64 duty(默认0X3F(1/64))
	OLED_WR_Byte(0xD3,OLED_CMD);//设置显示偏移位移映射RAM计数器(0x00~0x3F)
	OLED_WR_Byte(0x00,OLED_CMD);//-not offset
	OLED_WR_Byte(0xD5,OLED_CMD);//设置显示时钟分频比/振荡器频率
	OLED_WR_Byte(0x80,OLED_CMD);//设置分频比,设置时钟为100帧/秒
	OLED_WR_Byte(0xD9,OLED_CMD);//设置预充电周期
	OLED_WR_Byte(0xF1,OLED_CMD);//设置预充15个时钟,放电1个时钟([3:0],PHASE 1;[7:4],PHASE 2;)
	OLED_WR_Byte(0xDA,OLED_CMD);//设置COM硬件引脚配置
	OLED_WR_Byte(0x12,OLED_CMD);//[5:4]配置
	OLED_WR_Byte(0xDB,OLED_CMD);//设置VCOMH 电压倍率
	OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM 释放电压([6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;)
	OLED_WR_Byte(0x20,OLED_CMD);//设置页面寻址模式(0x00/0x01/0x02)
	OLED_WR_Byte(0x02,OLED_CMD);//[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
	OLED_WR_Byte(0x8D,OLED_CMD);//设置充电泵启用/禁用
	OLED_WR_Byte(0x14,OLED_CMD);//设置(0x10禁用,0x14启用)
	OLED_WR_Byte(0xA4,OLED_CMD);// 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) (0xa4/0xa5)
	OLED_WR_Byte(0xA6,OLED_CMD);// 设置显示方式;bit0:1,反相显示;0,正常显示 (0xa6/a7) 
	OLED_WR_Byte(0xAF,OLED_CMD);//开启显示	
	OLED_Clear();
	OLED_SetCursorAddrese(0,0);
}

运行示例代码,显示一些字符,成功完成。

四、OLED之图片显示

 SEG0~SEG127表示横坐标从0~127,COM1~COM63为纵坐标0~63。

纵坐标分为PAGE0~PAGE7共8个PAGE,每次一个PAGE从左至右显示完毕,再显示下一个PAGE。

代码下载

更多文章请移步公众号:VeryARM 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值