自己怎么开网站,网站建设为什么必须有服务器,进入深圳市住房和建设局网站,微信网站技术方案Tang Nano 20K: I2C OLED Driver 写在前面的话硬件模块RTL电路和相关资源报告SSD1306 OLED 驱动芯片SSD1306 I2C协议接口OLED 驱动模块RTL综合实现 总结 写在前面的话
之前在逛淘宝的时候偶然发现了Tang Nano 20K#xff0c;十分感慨国产FPGA替代方案的进步之快#xff1b;被… Tang Nano 20K: I2C OLED Driver 写在前面的话硬件模块RTL电路和相关资源报告SSD1306 OLED 驱动芯片SSD1306 I2C协议接口OLED 驱动模块RTL综合实现 总结 写在前面的话
之前在逛淘宝的时候偶然发现了Tang Nano 20K十分感慨国产FPGA替代方案的进步之快被Tang Nano 20K小巧精致的外形和丰富的内在资源震惊到了买来想要体验一下国产FPGA的软件生态。
硬件模块
项目主要设备是高云半导体的Tang Nano 20K开发板和0.96寸四针I2C模块的OLED模块OLED模块采用SSD1306驱动芯片
Tang Nano 20K 0.96寸 I2C 接口OLED
RTL电路和相关资源报告
采用GOWIN FPGA Designer平台查看RTL电路图 采用GOWIN FPGA Designer平台查看资源报告
SSD1306 OLED 驱动芯片
SSD1306是一个单片CMOS OLED/PLED驱动芯片可以驱动有机/聚合发光二极管点阵图形显示系统。由128 segments和64Commons组成。该芯片专为共阴极OLED面板设计。SSD1306中嵌入了对比度控制器、显示RAM和晶振并因此减少了外部器件和功耗。有256级亮度控制。数据/命令的发送有三种接口可选择6800/8000串口I2C接口或SPI接口。适用于多数简介的应用移动电话的屏显MP3播放器和计算器等。
SSD1306 芯片框图
SSD1306中内置128 * 64的GDDRAM是一个为映射静态RAM保存位模式来显示RAM分为8页从PAFE0到PAGE7用于单色128 * 64点阵显示如下图所示 GDDRAM 当一个数据字节写到GDDRAM中所有当前列的同一页的行图像数据都会被被填充比如被列地址指针指向的整列8位都会被填充。数据位D0写到顶行而数据位D7写到底行如下图所示。
SSD1306 I2C协议接口
I2C通讯接口由从机地址为SA0I2C总线数据信号SDAout/D2输出和SDAin/D1输入和I2C总线时钟信号SCLD0组成。数据和时钟信号线都必须接上上拉电阻。RES#用来初始化设备。 I2C数据格式 a. 从机地址位SA0 SSD1306在发送或接受任何信息之前必须识别从机地址。设备将会响应从机地址后面跟随着从机地址位SA0位和读写选择位R/W#位。 SA0位为从机地址提供了一个位的拓展。0111100或0111101都可以做为SSD1306的从机地址。D/C#引脚作为SA0用于从机地址选择。R/W#为用来决定I2C总线接口的操作模式。R/W# 1读模式。R/W# 0 写模式 b. I2C总线数据信号SDA SDA作为主机和从机之间的通讯通道。数据和应答都是通过SDA发送。 c. I2C总线时钟信号SCL 每个数据位的传输任务发生在SCL的单个的时钟周期中。
项目难度⭐ 项目推荐度⭐⭐ 项目推荐天数1~天
FPGA开发环境 前仿 Modelsim SE-64 2019.2 综合 Gowin_V1.9.9Beta-4_Education
项目学习目的 1熟练掌握项目中各文件的工程管理 2熟悉 Verilog HDL仿真、FPGA综合工具及流程 3学习OLED 驱动和I2C的基础原理
OLED 驱动模块RTL
//oled_init 初始化模块
module OLED_Init(input sys_clk ,input rst_n ,input init_req , //初始化请求input write_done , //初始化数据完成信号output init_finish , //初始化完成输出output[23:0] Init_data //初始化的数据
);//WR CMD 0X780X00CMD
//WR Data 0X780X40Data
localparam RST_T 1b0; //低电平复位有效reg[23:0] Init_data_reg;
reg[23:0] Init_data_reg1;reg[4:0] Init_index;reg init_finish_inside;//OLED_WR
reg [10:0] WR_index ; //TX data counter
reg [9:0] WR_addr ; //TX ROM Data addr
wire [7:0] WR_data ; //WR Data//FSM
localparam IDLE 2b01 ;
localparam WR 2b10 ;reg [1:0] CS ;
reg [1:0] NS ;always (posedge sys_clk or negedge rst_n) begin if(~rst_n) beginCS IDLE;end else beginCS NS;end
endalways(*) begin case(CS)IDLE: beginif(Init_index d26 write_done 1b1) beginNS WR;end else beginNS IDLE;end end WR: beginif(rst_n1b0) beginNS IDLE;endelse beginNS WR;endend default: NS IDLE;endcase
end always(*) begin case(CS)IDLE: init_finish_inside 1b0;WR: init_finish_inside 1b1;default: NS IDLE;endcase
endassign Init_data (init_finish_inside1b1)?Init_data_reg1:Init_data_reg;
assign init_finish (write_done 1b1 WR_index d1047) ? 1b1 : 1b0;//完成信号always(posedge sys_clk or negedge rst_n)
beginif(rst_n RST_T)Init_index d0;else if(Init_index d26 write_done 1b1 )Init_index d0;else if(write_done 1b1 init_req 1b1)Init_index Init_index 1b1;elseInit_index Init_index;
end//初始化命令状态
always(*)
begincase(Init_index)d0: Init_data_reg {8h78,8h00,8hAE};d1: Init_data_reg {8h78,8h00,8h00};d2: Init_data_reg {8h78,8h00,8h10};d3: Init_data_reg {8h78,8h00,8h40};d4: Init_data_reg {8h78,8h00,8hB0};d5: Init_data_reg {8h78,8h00,8h81};d6: Init_data_reg {8h78,8h00,8hFF};d7: Init_data_reg {8h78,8h00,8hA1};d8: Init_data_reg {8h78,8h00,8hA6};d9: Init_data_reg {8h78,8h00,8hA8};d10: Init_data_reg {8h78,8h00,8h3F};d11: Init_data_reg {8h78,8h00,8hC8};d12: Init_data_reg {8h78,8h00,8hD3};d13: Init_data_reg {8h78,8h00,8h00};d14: Init_data_reg {8h78,8h00,8hD5};d15: Init_data_reg {8h78,8h00,8h80};d16: Init_data_reg {8h78,8h00,8hD8};d17: Init_data_reg {8h78,8h00,8h05};d18: Init_data_reg {8h78,8h00,8hD9};d19: Init_data_reg {8h78,8h00,8hF1};d20: Init_data_reg {8h78,8h00,8hDA};d21: Init_data_reg {8h78,8h00,8h12};d22: Init_data_reg {8h78,8h00,8hDB};d23: Init_data_reg {8h78,8h00,8h30};d24: Init_data_reg {8h78,8h00,8h8D};d25: Init_data_reg {8h78,8h00,8h14};d26: Init_data_reg {8h78,8h00,8hAF};default:Init_data_reg {8h78,8h00,8hAE};endcase
endalways (posedge sys_clk or negedge rst_n)
beginif(~rst_n)beginWR_index 11d0;end else if(WR_index d1048) beginWR_index 11d0;endelse if(init_finish_inside 1b1 write_done 1b1 init_req 1b1)WR_index WR_index 1b1;elseWR_index WR_index;
endalways (posedge sys_clk or negedge rst_n)
beginif(~rst_n)beginWR_addr 10d0;end elsebeginif ((WR_index 11d2) (WR_index 11d129)) beginWR_addr WR_index - 11d2;endelse if ((WR_index 11d133) (WR_index 11d260)) beginWR_addr WR_index - 11d5;endelse if ((WR_index 11d264) (WR_index 11d391)) beginWR_addr WR_index - 11d8;endelse if ((WR_index 11d395) (WR_index 11d522)) beginWR_addr WR_index - 11d11;endelse if ((WR_index 11d526) (WR_index 11d653)) beginWR_addr WR_index - 11d14;endelse if ((WR_index 11d657) (WR_index 11d784)) beginWR_addr WR_index - 11d17;endelse if ((WR_index 11d788) (WR_index 11d915)) beginWR_addr WR_index - 11d20;endelse if ((WR_index 11d919) (WR_index 11d1046)) beginWR_addr WR_index - 11d23;endend
end//初始化数据发送
always(*) begincase (WR_index)11d0: Init_data_reg1 {8h78,8h00,8hB0};11d1: Init_data_reg1 {8h78,8h00,8h00}; 11d2: Init_data_reg1 {8h78,8h00,8h10};// page 011d131:Init_data_reg1 {8h78,8h00,8hB1};11d132:Init_data_reg1 {8h78,8h00,8h00}; 11d133:Init_data_reg1 {8h78,8h00,8h10};// page 111d262:Init_data_reg1 {8h78,8h00,8hB2};11d263:Init_data_reg1 {8h78,8h00,8h00}; 11d264:Init_data_reg1 {8h78,8h00,8h10};// page 211d393:Init_data_reg1 {8h78,8h00,8hB3};11d394:Init_data_reg1 {8h78,8h00,8h00}; 11d395:Init_data_reg1 {8h78,8h00,8h10};// page 311d524:Init_data_reg1 {8h78,8h00,8hB4};11d525:Init_data_reg1 {8h78,8h00,8h00}; 11d526:Init_data_reg1 {8h78,8h00,8h10};// page 411d655:Init_data_reg1 {8h78,8h00,8hB5};11d656:Init_data_reg1 {8h78,8h00,8h00}; 11d657:Init_data_reg1 {8h78,8h00,8h10};// page 511d786:Init_data_reg1 {8h78,8h00,8hB6};11d787:Init_data_reg1 {8h78,8h00,8h00}; 11d789:Init_data_reg1 {8h78,8h00,8h10};// page 611d917:Init_data_reg1 {8h78,8h00,8hB7};11d918:Init_data_reg1 {8h78,8h00,8h00}; 11d919:Init_data_reg1 {8h78,8h00,8h10};// page 7default : Init_data_reg1 {8h78,8h40,WR_data}; //binary dataendcase
endassign WR_data 8hAA;//Change the instance name and port connections to the signal names
//--------Copy here to design--------Gowin_pROM your_instance_name(.dout (WR_data ), //output [7:0] dout.clk (sys_clk ), //input clk.oce ( ), //input oce.ce (1b1 ), //input ce.reset (~rst_n ), //input reset.ad (WR_addr ) //input [9:0] ad);//--------Copy end-------------------endmodule
综合实现
采用GOWIN完成电路综合并下板实现。 祝大家新年快乐呀
总结
没啥总结的在这里祝愿大家龙年大吉万事如意