一. spi总线协议
spi(serial peripheral interface)接口,中文为串行外设接口。它只需要3根线或4根线即可完成通信工作(这里讨论4根线的情况)。
这4根通信线分别为ncs/nss(片选信号)、sck/sclk(串行同步时钟)、mosi/sdo(主机输出从机输入,master output slave input)、miso/sdi(主机输入从机输出)。
spi通信有四种方式,由cpol(时钟极性)、cpha(时钟相位)的4种组合决定的。cpol决定总线空闲时,sck是高电平还是低电平(cpol=,0,无数据传输时,sck=0;cpol=1,无数据传输时,sck=1)。cpha决定在数据开始传输时,sck第几个跳变沿采集数据(cpha=0,开始传输时,在第一个跳变沿采集数据,第二个跳变沿改变发送数据(即改变miso或者mosi线上电平);cpha=1,开始传输是,在第一个跳变沿改变发送的数据,在第二个跳变沿采集数据)(见图1)。
图1
确立可靠通信前,必须保证主从机处于同一种的传输方式,这里为方便起见,专门以cpol=0,cpha=0的传输方式进行讨论。需要注意的是:在cpol=0,cpha=0的情况下,主从机都在sck上跳沿对数据进行采集,sck下跳沿改变总线电平(见图2)。
图2
这里在使用fpga实现spi模块时,做一个规定:
1. 使用cpol=0,、cpha=0的传输方式;
2. 传输时,以最高位先输出,最后输出最低位;
3. fpga实现的spi模块作从机,sck由外部主机提供;
4. 通信数据长度为8位。
二. fpga的spi从机实现
实现spi从机,可以分为两个模块:一个是spi接收模块,另一个则是spi发送模块。
1. 首先确定模块的输出输入管脚
由标题一可以知道,spi通信脚有4根线,我们还是用到时钟总线和模块复位脚,因此模块管脚可以定义为
module myspi(nrst, clk, ncs, mosi, miso, sck);input clk, nrst;input ncs, mosi, sck;output miso; 2. sck跳变沿检测
原理十分简单:使用寄存器记录sck状态,由状态判断sck是否出现跳变沿。
reg[2:0] sck_edge;
always @ (posedge clk or negedge nrst)
begin
if(~nrst)
begin
sck_edge <= 3'b000;
end
else
begin
sck_edge <= {sck_edge[1:0], sck};
end
end
wire sck_riseedge, sck_falledge;
assign sck_riseedge = (sck_edge[2:1] == 2'b01); //检测到sck由0变成1,则认为发现上跳沿
assign sck_falledge = (sck_edge[2:1] == 2'b10); //检测到sck由1变成0,则认为发现下跳沿
3. spi接收部分
spi接收部分使用有限状态机:
状态1:等待sck上跳沿,并将mosi的数据移入移位寄存器byte_received,接收位数寄存器bit_received_cnt记录接收到的数据位数,接收到8位数据后转入状态2;
状态2:保存移位寄存器byte_received数据到接收缓存器rec_data,接收标志位/接收缓存器非空标志位rec_flag置高4个clk时钟周期后转入状态3;
状态3:清除rec_flag并转入状态1。
reg[7:0] byte_received;reg[3:0] bit_received_cnt;reg rec_flag;reg[1:0] rec_status; //spi接收部分状态机reg[7:0] rec_data;reg[2:0] rec_flag_width; //spi接收完成标志位脉冲宽度寄存器always @ (posedge clk or negedge nrst) //每次sck都会接收数据,spi的顶端模块状态机决定是否取用beginif(~nrst)beginbyte_received <= 8'h00;bit_received_cnt <= 4'h0;rec_flag <= 1'b0;rec_status <= 2'b00;rec_flag_width <= 3'b000;endelsebeginif(~ncs)begincase (rec_status)2'b00: beginif(sck_riseedge)beginbyte_received <= {byte_received[6:0], mosi};if(bit_received_cnt == 4'h7)beginbit_received_cnt <= 4'b0000;rec_status <= 2'b01;endelsebeginbit_received_cnt <= bit_received_cnt+1;endendend2'b01: beginrec_data <= byte_received;rec_flag <= 1'b1;if(rec_flag_width==3'b100) beginrec_flag_width <= 3'b000;rec_status <= 2'b11;endelse beginrec_flag_width <= rec_flag_width+1;endend2'b11: beginrec_flag <= 1'b0;rec_status <= 2'b00;endendcaseendendend 这里,使用rec_flag的原因是通知另一个模块处理接收数据(后面将会提到),rec_data若在下一次数据传输完成前不做处理则会丢失。
4. spi发送部分
spi从机一般在解析主机发送的命令后,主动发出主机所需数据,所以,spi发送部分,需要其他模块的触发,并将数据送往miso管脚。
spi发送部分也离不开状态机:
状态1:等待发送触发标志位send_flag置高,一旦标志位send_flag置高,发送移位寄存器byte_sended存储外部触发模块的数据send_data,miso管脚输出发送数据最高位send_data[7],置位正在发送标志位sending_flag,转入状态2;
状态2:等待sck上跳沿,即等待主机接收数据最高位后进入状态3;(其实这个状态可有可无的状态)
状态3:在sck下跳沿,将发送移位寄存器byte_sended最高位移入miso管脚,当发送移位寄存器被移空,清除正在发送标志位sending_flag,进入状态4;
状态4:置低miso管脚,转入状态1。
reg miso;reg sending_flag; //正在发送标志位reg[7:0] byte_sended; //发送移位寄存器reg[3:0] bit_sended_cnt; //spi发送位计数器reg[1:0] send_status; //spi发送部分状态机always @ (posedge clk or negedge nrst)beginif(~nrst)beginbyte_sended <= 8'h00;bit_sended_cnt <= 4'b0000;send_status <= 2'b00;sending_flag <= 1'b0;endelsebeginif(~ncs)begincase (send_status)2'b00: beginif(send_flag)begin //锁存发送数据send_status <= 2'b01; //2'b01;byte_sended <= send_data;sending_flag <= 1'b1;miso <= send_data[7];endend2'b01: begin //发送数据移入移位寄存器if(sck_riseedge) begin//miso <= byte_sended[7];//byte_sended <= {byte_sended[6:0], 1'b0};send_status <= 2'b11;endend2'b11: begin //根据sck下降沿改变数据miso <= byte_sended[7];if(sck_falledge) ///---------------------------------------这里多移了一位begin//miso <= byte_sended[7];byte_sended <= {byte_sended[6:0], 1'b0};if(bit_sended_cnt == 4'b0111)beginsend_status <= 2'b10;bit_sended_cnt <= 4'b0000;sending_flag <= 1'b0;endelsebeginbit_sended_cnt <= bit_sended_cnt+1;endendend2'b10: begin //数据发送完毕send_status <= 2'b00;//sending_flag <= 1'b0;miso <= 1'b0;endendcaseendendend 经过实测,sck频率低于clk频率8倍以上,通信可靠稳定,测试芯片为xc3s50-tq144,平台为ise,clk为25mhz。
cmos传输门芯片型号有哪些
航智携手奥地利AVL:助力电动汽车电池产业发展
扬尘在线监测设备/建筑工地扬尘在线监测设备有哪些?
洲明携智慧交通解决方案惊艳亮相CEIC-2021
一加6T确认出厂将预装安卓9.0系统
SPI通信的四种方式 FPGA的SPI从机实现方案
基于CompactPCI电路板分析
什么样的测试工程师才算合格
关于虚拟现实革命的10个事实
《回到大婚那一天》收官,随幻科技如何用技术赋能“微短剧”生态
飞睿科技雷达感应模块,低功耗雷达模组
IBM Storage Ceph:现代数据湖仓的理想技术底座
安立知发布蓝牙低功耗测试方案
小寻儿童电话手表A3开售 支持小米小爱同学首发价169元
激光测距传感器的测量方法有哪些?
用运放驱动简单实用功率放大器,NE5532驱动功率放大电路
电压跟随器电路的电路连接形式是怎样的
上海增强现实技术与应用论坛暨2018EasyAR开发者大会开放报名! ... ...
迄今最大模型?OpenAI发布参数量高达15亿的通用语言模型GPT-2
中国联通:7部多场景化白皮书,共同开启万物智联时代