FPGA驱动OLED动态显示(Verilog代码)——SPI写操作
1、OLED驱动芯片使用SSD1306;
2、OLED原理链接:OLED原理
3、只进行写操作,不需要读;
4、源码:
/*--------------------------------------------------------------*\
Filename : spi_write.v
Author : Cwang
Description :
Revision History : 2017-10-16
Revision 1.0
Email : wangcp@hitrobotgroup.com
Company : Micro nano institute
Copyright(c) 2017,Micro nano institute,All right resered
\*---------------------------------------------------------------*/
/*
spi_out: 3 2 1 0
CS DC SCL(D0) SDA(D1)
*/
module spi_write(
clk_1m,
rst_n,
spi_write_start,
spi_data,
spi_write_done,
spi_out
);
input clk_1m;
input rst_n;
input spi_write_start;
input [9:0] spi_data;
output spi_write_done;
output [3:0]spi_out;
parameter TIME5US = 4'd9;
reg [3:0] count;
always @(posedge clk_1m or negedge rst_n)
begin
if(!rst_n)
count <= 4'd0;
else
if(count == TIME5US)
count <= 4'd0;
else
if(spi_write_start)
count <= count + 1'b1;
else
count <= 4'd0;
end
reg [4:0] i;
reg scl;
reg sda;
reg done;
always @(posedge clk_1m or negedge rst_n)
begin
if(!rst_n)
begin
i <= 5'd0;
scl <= 1'b1;
sda <= 1'b0;
done <= 1'b0;
end
else
begin
if(spi_write_start)
case(i)
5'd0,5'd2,5'd4,5'd6,5'd8,5'd10,5'd12,5'd14:
begin
if(count == TIME5US)
begin
scl <= 1'b0; //scl下降沿设置数据
sda <= spi_data[7 - (i>>1) ];
i <= i + 1'b1;
end
end
5'd1,5'd3,5'd5,5'd7,5'd9,5'd11,5'd13,5'd15:
begin
if(count == TIME5US)
begin
scl <= 1'b1; //scl上升沿锁存数据
i <= i + 1'b1;
end
end
5'd16:
begin
done <= 1'b1;
i <= i + 1'b1;
end
5'd17:
begin
done <= 1'b0;
i <= 5'd0;
end
endcase
end
end
assign spi_write_done = done;
assign spi_out = {spi_data[9],spi_data[8],scl,sda};
endmodule
注释:
1、spi_out:bit3=cs;bit2=RES,=0表示写命令,=1表示写数据;bit1=SCL;bit0=SDA;
2、在C语言中实现SPI操作是用的for语句,但在Verilog中是不建议使用for的,因此借助reg i 实现C语言中的顺序操作,用i <= i+1'b1 看起来跟C中for(i=0;i<=n;i++)的顺序操作差不多,其本质上是一段状态机;.
3、每写完一组8bit数据,就会产生一个时钟周期的高脉冲“done”信号,目的是告诉上层模块“我已经写完一组数据,可以继续写下一组了”