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”信号,目的是告诉上层模块“我已经写完一组数据,可以继续写下一组了”