一. 简介

这是FPGA之旅设计的第九例啦!!!本例将介绍如何使用FPGA驱动OLED屏幕,并在接下来的几例中,配合其它模块,进行一些有趣的综合实验。由于使用的OLED屏是IIC接口的,对IIC接口不是很清楚的,可以参考第五例的设计,同时使用第五例写好的IIC模块,驱动OLED屏。Let’s do it!

二. 0.96寸OLED屏介绍

这里就只介绍最常用的0.96寸屏,其它的一样。OLED共支持8080并口、SPI和IIC三种接口,同样也只介绍IIC接口的用法。0.96寸OLED屏幕的分辨率为128×64,内部有一块GRAM用来存储显示的数据。

(一).OLED的存储区域

这块存储区域分为8个page,每个page下面共有128bit,如下图所示

这就难免会有些疑问了,128×8,不应该是128×64嘛? 8个page,为什么是64行呢?数据写入的呢?

每一个page包括8行,所以说8个page共有64行。IIC每次发送数据的时候,是发送一个byte的,也就是8bit,这8bit数据会存储到某一列的八行中,例如图中SEG0区域,是第一列的头八行。这样GRAM的存储区域就弄懂了。

(二).OLED的数据存储模式

当我们向OLED的GRAM发送显示数据的过程中,OLED内部共有三种处理模式。

模式一: 当我们指定了一个page和某一列的时候,每写一个数据,列会自动加一,当写到page的最后一列的时候,列数,会自动跳转到第零列,需要手动的切换page。

模式二:与模式一不同的时候,当写达到page的最后一列的时候,列数跳转到第零列的同时,page数也会加一。

模式三: 与前两个模式不同,模式三,是一列一列的写,每写完一个数据,page数加一,当加到最后一个page的时候,列数加一,page跳转到第一个page。

在实际的使用中,具体使用那一种模式,可以根据自己的子模软件或者项目来,怎么方便怎么来!

了解了上面两个部分后,基本就可以编写驱动程序啦,不要问为什么,(#.#),初始化OLED就是配置一些列命令的过程,而这些寄存器和配置的值一般都是copy现成的。然后了解一下关键的一两个命令就可以啦。想要深入的了解OLED的功能的话,可以阅读对应的芯片手册哦!在后面的例程中也会介绍部分功能强大的命令。

三. OLED关键命令介绍

  • 0xAE/0xAF: 对应着开启OLED显示和关闭OLED显示
  • 0x20-0x22: 对应着上面的三种OLED数据存储模式,默认为0x22,模式一
  • 0x00-0x0F: 设置列地址的低四位,默认为0x00,
  • 0x10-0x1F: 设置列地址的高四位,默认为0x10,
  • 0xB0-0xB7: 设置page,第四位表示page。

暂时差不多只需要了解上面的这些寄存器。

四. IIC驱动OLED数据格式

驱动OLED分为写数据和写命令(读暂时不考虑)。写命令就是配置的过程,写数据就是写入GRAM中进行显示的过程。

IIC数据格式 :OLED地址 + 命令 / 数据 + 值。

OLED地址,就是IIC协议中的从机地址,我这里是0x78。

命令/数据中,0x00表示接下来的值代表命令,0x40表示接下的值表示数据,存入GRMA。

,具体的命令或者数据

也就是说每一次IIC需要传输24bit,3个字节的数据,和第五例的IIC模块完美对应,那事情就好办啦!

五. OLED初始化

直接copy某例程提供的配置参数,共需要配置26个命令,第一个是上面介绍的0xAE命令,关闭OLED显示。最后一个也是介绍的0xAF命令,开启OLED显示,没有配置模式,直接使用的默认的模式一,配置完成后,可以看到OLED屏被点亮,内容是杂乱的。

always@(*)
begincase(Init_index)'d0:      Init_data_reg <= {8'h78,8'h00,8'hAE};  //OLED地址 + 命令  +  值。**'d1:     Init_data_reg <= {8'h78,8'h00,8'h00};'d2:       Init_data_reg <= {8'h78,8'h00,8'h10};'d3:       Init_data_reg <= {8'h78,8'h00,8'h40};'d4:       Init_data_reg <= {8'h78,8'h00,8'hB0};'d5:       Init_data_reg <= {8'h78,8'h00,8'h81};'d6:       Init_data_reg <= {8'h78,8'h00,8'hFF};'d7:       Init_data_reg <= {8'h78,8'h00,8'hA1};'d8:       Init_data_reg <= {8'h78,8'h00,8'hA6};'d9:       Init_data_reg <= {8'h78,8'h00,8'hA8};'d10:      Init_data_reg <= {8'h78,8'h00,8'h3F};'d11:      Init_data_reg <= {8'h78,8'h00,8'hC8};'d12:      Init_data_reg <= {8'h78,8'h00,8'hD3};'d13:      Init_data_reg <= {8'h78,8'h00,8'h00};'d14:      Init_data_reg <= {8'h78,8'h00,8'hD5};'d15:      Init_data_reg <= {8'h78,8'h00,8'h80};'d16:      Init_data_reg <= {8'h78,8'h00,8'hD8};'d17:      Init_data_reg <= {8'h78,8'h00,8'h05};'d18:      Init_data_reg <= {8'h78,8'h00,8'hD9};'d19:      Init_data_reg <= {8'h78,8'h00,8'hF1};'d20:      Init_data_reg <= {8'h78,8'h00,8'hDA};'d21:      Init_data_reg <= {8'h78,8'h00,8'h12};'d22:      Init_data_reg <= {8'h78,8'h00,8'hDB};'d23:      Init_data_reg <= {8'h78,8'h00,8'h30};'d24:      Init_data_reg <= {8'h78,8'h00,8'h8D};'d25:      Init_data_reg <= {8'h78,8'h00,8'h14};'d26:      Init_data_reg <= {8'h78,8'h00,8'hAF};default:Init_data_reg <= {8'h78,8'h00,8'hAE};endcase
end

六. 向GRAM中写入数据

初始化后,就可以显示内容啦,仅仅只需要配置page和起始列三个命令,然后写入数据即可,配置页和列地址,只有在模式一有效,也就是上电默认的模式

这样就可以显示数据啦,亲测可用哦!

'd0:show_data_reg <= {8'h78,8'h00,8'hb0 + show_pag};        //配置页
'd1:show_data_reg <= {8'h78,8'h00,8'h00 +start_x[3:0]};     //配置列的低四位
'd2:show_data_reg <= {8'h78,8'h00,8'h10 + start_x[6:4]};    //配置列的高四位,128列只需要配置高三位即可。
'd3:show_data_reg <= {8'h78,8'h40, data};                    //向配置的地址中,写入显示的数据

其实驱动OLED也没有那么复杂嘛。

七. 上板验证

先来编写个简单的模块,用来初始化OLED。下载程序后,我的OLED是亮起来了,你的呢!

//OLED顶层模块
module OLED_Top(input           sys_clk,input           rst_n,//OLED IICoutput      OLED_SCL,inout          OLED_SDA
);
localparam  OLED_INIT = 'd0;          //初始化
localparam  OLED_IDLE = 'd1;          //空闲
reg[4:0]    state , next_state;
wire            init_finish;
wire[23:0]  Init_data;
wire            init_req;
wire            IICWriteDone;
assign init_req = (state == OLED_INIT) ? 1'b1 : 1'b0;
always@(posedge sys_clk or negedge rst_n)
beginif(rst_n == 1'b0)state <= OLED_INIT;elsestate <= next_state;
end
always@(*)
begincase(state)OLED_INIT:if(init_finish == 1'b1)next_state <= OLED_IDLE;elsenext_state <= OLED_INIT;OLED_IDLE:next_state <= OLED_IDLE;default: next_state <= OLED_INIT;endcase
end
OLED_Init OLED_Init(.sys_clk                (sys_clk),.rst_n                (rst_n),.init_req           (init_req),             //初始化请求.write_done          (IICWriteDone),         //一组初始化数据完成信号.init_finish       (init_finish),          //初始化完成输出.Init_data         (Init_data)//初始化的数据
);
IIC_Driver IIC_DriverHP_OLED(.sys_clk               (sys_clk),           /*系统时钟*/.rst_n             (rst_n),             /*系统复位*/.IICSCL                (OLED_SCL),            /*IIC 时钟输出*/.IICSDA              (OLED_SDA),             /*IIC 数据线*/.IICSlave            ({Init_data[15:8],Init_data[23:16]}),           /*从机 8bit的寄存器地址 + 8bit的从机地址*/.IICWriteReq      (init_req),       /*IIC写寄存器请求*/.IICWriteDone        (IICWriteDone),      /*IIC写寄存器完成*/.IICWriteData     (Init_data[7:0]),       /*IIC发送数据  8bit的数据*/.IICReadReq         (1'b0),        /*IIC读寄存器请求*/.IICReadDone           (),       /*IIC读寄存器完成*/.IICReadData         ()    /*IIC读取数据*/
);
endmodule

FPGA驱动OLED就结束啦!

gzh回复 FPGA之旅设计99例之第九例 获取工程文件

FPGA之旅设计99例之第九例-----驱动0.96寸OLED屏相关推荐

  1. FPGA驱动0.96寸OLED(SSD1306)

    目录 一.七针0.96寸OLED驱动原理 二.SSD1306驱动时序 1.GDDRAM内部结构: (1)页寻址 (2)水平寻址 (3)垂直寻址 2.初始化 3.清屏 4.发送数据 三.子模块源码 1. ...

  2. FPGA之旅设计99例之第二十一例----VGA串口SDRAM显示图片

    一. 简介 本例将接着上一例实现的sdram控制器进行封装.上例中只是实现了一个基本的控制器,在实际使用中,通常读写时钟是两个不同频率的,所以并不能满足要求. 在本例中,将对读写接口进行封装,将读写接 ...

  3. FPGA之旅设计99例之第二十例---SDRAM存储器实现

    一. 简介 本例将介绍SDRAM的使用.SDRAM是一个存储器件,存储容量大,存储速度比较快,速度可达100M,特别适合用来当中视频或者音频中的存储器件. 在采集到OV5640传输过来的图像数据的时候 ...

  4. FPGA之旅设计99例之第二例-----按键

    一.简介 这是FPGA之旅的第二个设计实例了,按键在项目中的作用是非常大的,使用的很频繁,本例将带大家设计一个实用的按键模块. 欢迎关注微信公众号 FPGA之旅 哦 可以在上面联系,有什么问题的话 二 ...

  5. 基于点灯科技的温湿度传感器设计:STM32C8T6+DHT11+0.96寸oled显示屏+ESP8266

    基于点灯科技的温湿度传感器设计,课程设计自取. 保证可以做出来,接线有手进行,小学生来了都会. 耗时一个礼拜,移植网上各种资料,最终形成了这样一个简洁的版本 并且,oled的显示由单片机控制,设计ap ...

  6. 基于FPGA的LSTM加速器设计(MNIST数据集为例)

    摘要 本文以MNIST手写数字识别任务为例,使用FPGA搭建了一个LSTM网络加速器,并选取MNIST数据集中的10张图片,通过vivado软件进行仿真验证.实验结果表明,本文设计的基于FPGA的LS ...

  7. FPGA中计数器设计探索

    FPGA中计数器设计探索,以计数器为32位为例: 第一种方式,直接定义32位计数器. reg [31:0]count; quartus ii 下的编译,资源消耗情况. 85C模型下的时钟频率. 0C模 ...

  8. FPGA-Xilinx 7系列FPGA DDR3硬件设计规则

    Xilinx 7系列FPGA DDR3硬件设计规则 引言:本文我们介绍Xilinx 7系列FPGA DDR3硬件设计规则及约束,包括Bank选择.管脚位置约束.管脚分配.端接.I/O标准和走线长度. ...

  9. Altera FPGA/CPLD设计 基础篇+高级篇(附随书光盘)

    获取方法: 微信公众号:OpenFPGA   后台回复 Altera设计 基础篇介绍 <Altera FPGA/CPLD设计(基础篇)>是王诚.蔡海宁.吴继华编著的一本图书.该书可作为高等 ...

  10. 《FPGA至简设计原理与应用》学习笔记1 —— FPGA基础

    课程资源 视频:https://www.bilibili.com/video/BV14K4y1u7kH/ 资料:https://www.aliyundrive.com/s/E9H7Mc5hqhu 第1 ...

最新文章

  1. 2012年度IT博客大赛50强报道:高俊峰
  2. 想开网店?向你推荐最好的开源电子商务平台
  3. SpringMVC的数据响应-回写数据-返回对象或集合2(应用)
  4. Storm,Trident,Spark Streaming,Samza和Flink主流流处理框架比较
  5. 管理表空间和数据文件——维护表空间——设置默认表空间和删除表空间和删除数据文件盒临时文件...
  6. Mysql 5.5 编译参数
  7. 10分钟学会python函数式编程
  8. 【Elasticsearch】改进布尔查询的搜索相关性
  9. wifi定位算法 java_几种室内定位技术方案对比,室内定位种类的优缺点一目了然...
  10. vue 改变组件data_为什么vue组件中data必须用函数表达?
  11. Windows2003远程桌面无用户限制
  12. mysql主主同步机制+keepalived实现MySQL高可用
  13. Github上十大C#开源项目排行榜
  14. 【Transformers】第 1 章:从Bag-of-Words到Transformer
  15. 协调端到端的供应链管理——SCM
  16. php调用API支付接口 可个人使用,无需营业执照(使用第三方接口,调用的天工接口。)...
  17. Why you should not shrink your data files
  18. 2008 r2 server sql 中文版补丁_Microsoft SQL Server 2008 r2 sp2补丁 64位 官方免费版
  19. 产品生命周期和项目生命周期
  20. 高等数学笔记:定积分相关公式

热门文章

  1. 推荐 10 个实用但偏执的 Java 编程技巧
  2. 哈哈哈……~好敷衍的第一篇博客标题~
  3. 1.list倒叙输出
  4. 交换机与路由器技术:静态路由配置和路由器上配置DHCP、虚拟局域网VLAN
  5. oracle数据库中TDS,某高校开发了一个学生信息管理系统TDS,里面使用了Oracle数据库。则TDS被称为...
  6. 水质检测 — TDS模块
  7. BZOJ4049 : [Cerc2014] Mountainous landscape
  8. HanLP-命名实体识别总结
  9. LeetCode-自除数
  10. 金融贷款逾期的模型实现