0.96寸OLED(二)SPI+DMA刷新OLED

SPI+DMA刷新OLED


原理简介

OLED屏幕有三种刷新方式分别为页地址模式, 水平地址模式和垂直地址模式,。市面上厂家提供的历程为页刷新,这种刷新方式需要用户自己手动进行行列的切换,这种操作方式我个人感觉比较麻烦。三种刷新方式的具体方式可以参考厂家的文档。我这里参考了另一个人的博客,具体连接如下。
https://blog.csdn.net/gengyuchao/article/details/86608037
页地址
页地址模式
在这里插入图片描述
水平寻址模式
在这里插入图片描述
垂直寻址模式

可以发现如果我们采用水平地址寻址或者垂直地址寻址的话,只需要源源不断的发送数据就可以了,再结合DMA的话可以实现自动快速刷新,减轻处理器的负担。非常NICE!缺点就是必须整个刷一帧屏幕全屏幕,但是我们数据全部走DMA,所以还是划得来这个性价比的。


一、修改缓存区大小

uint8_t OLED_GRAM[128][8];//原大小为144 8,我也不知道为啥中景园这么写

把缓存区的大小修改为一帧的数量大小,128 64的分辨率,算下来正好128 8字节

二、修改SSD1306的指令

	    OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
	    OLED_WR_Byte(0x01,OLED_CMD);//
        OLED_WR_Byte(0x21,OLED_CMD);//设置列地址
        OLED_WR_Byte(0x00,OLED_CMD);
        OLED_WR_Byte(0x7f,OLED_CMD);   
        OLED_WR_Byte(0x22,OLED_CMD);//设置页地址
        OLED_WR_Byte(0x00,OLED_CMD);
        OLED_WR_Byte(0x07,OLED_CMD);

  修改为垂直地址寻址模式,设置列行的起始和结束地址。

三、替换原来的刷新函数

//更新显存到OLED	
void OLED_Refresh(void)
{
//    OLED_WR_Byte(0xb0,OLED_CMD); //设置行起始地址
//    OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
//    OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
    HAL_SPI_Transmit_DMA(&hspi1, (uint8_t *)OLED_GRAM, 128*8);
}

当然也可以修改DMA为循环模式,使得数据自动刷新。

    //hdma_spi1_tx.Init.Mode =DMA_NORMAL;
    hdma_spi1_tx.Init.Mode = DMA_CIRCULAR;//切换为循环模式

这样一来这个刷新函数甚至都不需要调用了,只要修改缓存区,数据自动发送,屏幕就跟着刷新了。

验证结果

  OLED_Refresh();//循环模式DMA要先开一次
  OLED_ShowPicture(0,0,128,64,BMP1,1);
  //之后就不要调用DMA函数了,自动就会刷新
  //只需要调用画图函数,OLED刷新函数不用调用了,舒服多了。

在这里插入图片描述

我这个图片显示有问题不清晰,是因为我的这块0.96OLED屏幕坏了,导致隔一行有一行没有的。后续我会整理好代码后发出来。

  • 13
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值