问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

基于Verilog 的 SPI 通信

发布网友 发布时间:2022-05-17 03:18

我来回答

2个回答

热心网友 时间:2023-09-26 17:25

http://www.fpga4fun.com/SPI2.html

SPI - A simple implementation
ARM processor
To get an opportunity to test our newly acquired SPI knowledge, we use a Saxo-L board. It has an ARM7 processor (LPC2138) and a Cyclone FPGA (EP1C3), connected by a SPI bus.
The ARM is used as a SPI master, while the FPGA is used as a SPI slave. The Saxo-L ARM processor has actually two SPI interfaces, one called SPI0, and a more advanced one called SPI1/SSP. They are both equally easy to use. We are using SPI1/SSP on Saxo-L, as it is pre-wired on the board.

SPI master - C ARM code
Using SSP is just a matter of initializing a few registers, and then writing/reading data to send/receive automatically.
void main(void)
{
// initialize SSP
SSP0CPSR = 0x02; // SSP max speed
SSP0CR0 = 0x07; // SSP max speed, 8 bits
SSP0CR1 = 0x02; // SSP master mode
PINSEL1 = 0x2A8; // SSP mode for pins P0.17 to P0.20

while(1)
{
// send two bytes
SSP0DR = 0x55; // one nice thing about the SSP is that it has a 8-words deep FIFO
SSP0DR = 0x54; // so here we write the data to be sent without worrying

// now wait until both bytes are sent
while(!(SSP0SR & 0x01));

// now we can read the two bytes received... and do anything with them
int data1 = SSP0DR;
int data2 = SSP0DR;
// ...
}
}

SPI slave - HDL FPGA code
Now for the SPI slave in the FPGA.
Since the SPI bus is typically much slower than the FPGA operating clock speed, we choose to over-sample the SPI bus using the FPGA clock. That makes the slave code slightly more complicated, but has the advantage of having the SPI logic run in the FPGA clock domain, which will make things easier afterwards.
First the mole declaration.
mole SPI_slave(clk, SCK, MOSI, MISO, SSEL, LED);
input clk;

input SCK, SSEL, MOSI;
output MISO;

output LED;

Note that we have "clk" (the FPGA clock) and an LED output... a nice little debug tool. "clk" needs to be faster than the SPI bus. Saxo-L has a default clock of 24MHz, which works fine here.

We sample/synchronize the SPI signals (SCK, SSEL and MOSI) using the FPGA clock and shift registers.
// sync SCK to the FPGA clock using a 3-bits shift register
reg [2:0] SCKr; always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
wire SCK_fallingedge = (SCKr[2:1]==2'b10); // and falling edges

// same thing for SSEL
reg [2:0] SSELr; always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
wire SSEL_active = ~SSELr[1]; // SSEL is active low
wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge

// and for MOSI
reg [1:0] MOSIr; always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
wire MOSI_data = MOSIr[1];

Now receiving data from the SPI bus is easy.
// we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
reg [2:0] bitcnt;

reg byte_received; // high when a byte has been received
reg [7:0] byte_data_received;

always @(posedge clk)
begin
if(~SSEL_active)
bitcnt <= 3'b000;
else
if(SCK_risingedge)
begin
bitcnt <= bitcnt + 3'b001;

// implement a shift-left register (since we receive the data MSB first)
byte_data_received <= {byte_data_received[6:0], MOSI_data};
end
end

always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);

// we use the LSB of the data received to control an LED
reg LED;
always @(posedge clk) if(byte_received) LED <= byte_data_received[0];

Finally the transmission part.
reg [7:0] byte_data_sent;

reg [7:0] cnt;
always @(posedge clk) if(SSEL_startmessage) cnt<=cnt+8'h1; // count the messages

always @(posedge clk)
if(SSEL_active)
begin
if(SSEL_startmessage)
byte_data_sent <= cnt; // first byte sent in a message is the message count
else
if(SCK_fallingedge)
begin
if(bitcnt==3'b000)
byte_data_sent <= 8'h00; // after that, we send 0s
else
byte_data_sent <= {byte_data_sent[6:0], 1'b0};
end
end

assign MISO = byte_data_sent[7]; // send MSB first
// we assume that there is only one slave on the SPI bus
// so we don't bother with a tri-state buffer for MISO
// otherwise we would need to tri-state MISO when SSEL is inactive

endmole

We have established communication between the ARM and the FPGA!
Running the code
As we step through the ARM code, we can see the LED changing state, and the data returned by the FPGA.

Now let's see if we can do useful things with SPI.

热心网友 时间:2023-09-26 17:26

00yaliang@163.com发来帮你看看追问已发,请问多久能提供回复?

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
临沂比较有名的男装品牌 呼伦贝尔市悦动网络科技有限公司怎么样? 呼伦贝尔中汇实业有限公司怎么样? 呼伦贝尔油玉不绝电子商务有限公司怎么样? 如何避免wps卡顿? 属鼠的男人找对象是属什么,属鼠的人和什么属相合 96年鼠的姻缘在哪年 属相相合年份运势提升 2024属鼠找对象属什么最佳 黑客攻击网站能报案吗 黑客攻击报案有用吗 等ps4 出了,是不是ps3 应该就进入全面破解时代了?我是指金手指!! how many types of code exist in most hdls HDL基础编程,报错:parse error, unexpected PROCESS, expecting IF verilog HDL 新手问题 怎样写邮箱和字符才正确谢谢大家,我知道了 爸爸叫李闯,妈妈叫赖盼盼,请问在马年出生的男孩和女孩取什么名字? 姓李,男孩名 蔷薇盛绽txt全集下载 爱上飞轮海之一生挚爱小说txt全集免费下载 奶茶店装修风格有哪些 装修时要注意什么 唐宇的母亲 帮忙取个李希儿的英文名 李希儿的英文名 jquery如何获取浏览器中缓存的用户名 如果林黛玉用了植倩诗会怎样? 玺羊羊纯羊奶粉怎么样? 人力资源管理成考要考那几科 矿床主要特征 为什么htc one m8拍照时候都是暗的 三星s5带不带夜间拍照模式 求解关于verilog HDL在quartus ii里综合的一个问题 Verilog HDL试卷及答案 在verilog hdl的端口声明语句中,用什么关键字声明端口为双口方向 用verilog HDL循环语句来统计8位二进制中含1的数量 怎么使用X-HDL软件?例如下面的一段程序怎么转换为VHDL?详细列出可行的步骤。 8-3优先编码器怎么写verilog代码啊,我总是仿不对 cad复制新建后粘贴怎么显示平面图? 喝薏米红豆粥有什么禁忌?薏米祛湿的表现有哪些?(2) 梦见自己在泥潭里面淹了大半个身子? 梦见自己陷在淤泥里呛死了 梦见牦牛在淤泥里淹死了 小米怎么双开 二哈和他的白猫师尊中天问究竟是什么武器? 苏州柳藤世家家居用品有限公司怎么样? 一般墙面有哪些材料?萌新不懂 武松杀入鸳鸯楼时,第一个杀的是后槽,难道不能饶了他吗? 常用的墙面装修材料都有哪些?各自具有什么特点? 更新完温十系统旧版windows文件系统还要吗 我50G的c盘装了win7 64的系统剩下的磁盘只有十个G的样子 温十系统的新电脑可以缷了装温七吗