用户工具

站点工具


基于spi总线的arm与fpga通信实验

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
基于spi总线的arm与fpga通信实验 [2019/12/21 11:27]
zhangzheng
基于spi总线的arm与fpga通信实验 [2022/03/22 10:29] (当前版本)
sean
行 1: 行 1:
-[[http://www.cnblogs.com/xiaomagee/p/7594868.html]]+|  **银杏科技有限公司旗下技术文档发布平台** ​ |||| 
 +|技术支持电话|**0379-69926675-801**||| 
 +|技术支持邮件|Gingko@vip.163.com||| 
 +^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ 
 +|  V1.0  |  2020-07-02 ​ |  gingko ​ |  初次建立 ​ |  
 + 
 +===== 实验十三:SPI通信实验——基于SPI总线的ARM与FPGA通信 ===== 
 +==== 一、 实验目的与意义 ==== 
 + 
 +  - 掌握SPI通信协议及实现方法。 
 +  - 掌握QuartusII的使用方法。 
 +==== 二、 实验设备及平台 ==== 
 + 
 +  - iCore4 双核心板[[https://item.taobao.com/item.htm?​spm=a1z10.1-c-s.w4004-22598974120.15.5923532fsFrHiE&​id=551864196684|点击购买]]。 
 +  - Blaster(或相同功能)仿真器[[https:​//item.taobao.com/​item.htm?​id=554869837940|点击购买]]。 
 +  - JLINK(或相同功能)仿真器。 
 +  - Micro USB线缆。 
 +  - Keil MDK 开发平台。 
 +  - Quartus开发平台。 
 +  - 电脑一台。 
 +==== 三、 实验原理 ==== 
 +=== 1.SPI简介 === 
 +  * SPI是串行外设接口(Serial PeripheralInterface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议。SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选)。 
 +  * SPI硬件接口: 
 +    * MISO  :主设备数据输入,从设备数据输出 
 +    * MOSI  :主设备数据输出,从设备数据输入 
 +    * SCLK :时钟信号,由主设备产生 
 +    * CS :从设备片选信号,由主设备控制 
 +=== 2.SPI功能说明 === 
 + 
 +  * SPI时钟极性和相位:​ 
 +    * CPOL决定时钟空闲时的稳定电平,对主/​从都有效 
 +    * CPOL=0:空闲时低电平 
 +    * CPOL=1:空闲时高电平 
 +    * CPHA决定数据采样时刻 
 +    * CPHA=0:第一个时钟延开始采样MSBit 
 +    * CPHA=1:第二个时钟延开始采样MSBit 
 +  * SPI总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果 CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。SPI主模块和与之通信的外设备时钟相位和极性应该一致。如图13-1所示 
 +  
 +{{ :​icore4:​icore4_fpga_13_1.png?​direct |图13-1}} 
 +=== 3.SPI通信指令表 === 
 + 
 +|指令名称 |字节1 |字节2 |字节3 |字节4| 
 +|器件ID |01h|  
 +|写数据长度| 02h| A15~A8| A7~A0|  
 +|写数据 | ​ 04h| A15~A8 |A7~A0| 数据(直至写完所有数据)| 
 +|读数据长度| 05h| A15~A8| A7~A0|  
 +|读数据 | ​ 07h|A15~A8 |A7~A0| 数据(直至读完所有数据)| 
 +|读错误信息| 08h| 
 + 
 +  * ARM与FPGA通信采用的是半双工式通信,FPGA通过识别指令完成与ARM的交互。 
 +  * 器件ID指令为01h,接下来为两字节的伪指令,第四字节仍为伪指令读取ID标志。  
 +  * 写数据长度指令02h,接下来两个字节为写数据的长度,先发高字节,后发低字节,接下来为一个字节的伪指令00h。 
 +  * 写数据指令为04h,接下来为两字节的地址指令,后为要写入的数据,数据写入完毕以伪指令00h结束数据传输。 
 +  * 读数据长度指令05h,接下来两个字节为写数据的长度,先发高字节,后发低字节,接下来为一个字节的伪指令00h。 
 +  * 读数据指令为07h,接下来为两字节的地址指令,其后为伪指令00h开始读取数据进行数据传输,第五字节以后为要读取的数据。 
 +  * 读错误信息指令08h,FPGA接收数据是否出错,先发送两个字节的伪指令,第四字节仍为伪指令读取错误标志信息。 
 +=== 4、本实验实现方式 === 
 +  * 通过FPGA建立的SPI模块对外提供的SCLK、CS、MOSI、MISO接口与STM32的SPI相连接,Commix串口精灵与STM32通过串口连接,实现三者之间的通信。本实验中,Commix串口精灵向STM32发送数据,STM32的RXD端口接收数据,然后,通过TXD端口把数据发送至FPGA,STM32起到一个桥梁作用。程序运行后,FPGA定时向STM32发送数据,经过STM32发送至串口精灵显示出来。下图为实验原理图。 
 +{{ :​icore4:​icore4_fpga_13_2.png?​direct&​700 |实验原理图}}  
 +==== 四、 代码讲解 ==== 
 +  * 本实验基于ARM+FPGA构架,通过ARM首先发送查询ID指令,然后依次通过指令设置写数据的长度、写数据地址、读数据的长度、读数据的地址,然后对比写入数据和读出数据是否一致判断数据是否写入成功,从而基于SPI总线实现ARM与FPGA之间的通信。 
 +  * 实现ARM与FPGA通信,对FPGA而言,其关键就在于SPI时序的模拟,实现SPI数据的接收与发送,实现数据与传输信号之间的串并转换。FPGA首先接收ARM指令,然后解析指令,存储相应的信息与数据,并根据指令需求将相应的指令数据放到SIMO总线上,等待ARM读取,从而实现两者之间的数据交互。SPI时序的硬件语言描述如下: 
 +<code verilog>​ 
 +////////////////​按字节接收SPI发送过来的数据//////////////​ 
 +///////​接收模块///////​  
 +reg[3:​0]i;​ 
 +reg[7:​0]data_in;​ 
 +reg [39:​0]temp_data,​data;​ 
 + 
 +always@(posedge spi_clk or negedge rst_n) 
 + if(!rst_n) 
 +     begin 
 + i <= 4'​d0;​ 
 + temp_data <= 40'​d0;​ 
 + data <= 40'​d0;​ 
 + data_in <= 8'​d0;​ 
 +     end 
 + else case(i) ​  //​从高位开始接收数据,每8个spi_clk时钟接收一个Byte 
 + 4'​d0:​ 
 +     begin 
 + i <= i + 1'​d1;​ 
 + data_in <= {data_in[6:​0],​spi_mosi};​ 
 + temp_data <= {temp_data[31:​0],​data_in};​ 
 + if(data_in == 8'​d13) 
 +     begin 
 +         data <= temp_data;​ 
 +     end 
 + else  
 +     begin 
 + data <= data; 
 +     end 
 + end 
 + 4'​d1,​4'​d2,​4'​d3,​4'​d4,​4'​d5,​4'​d6:​ 
 + begin 
 +     i <= i + 1'​d1;​ 
 +     data_in <= {data_in[6:​0],​spi_mosi};​ 
 + end 
 + 4'​d7:​begin 
 +     i <= 4'​d0;​ 
 +     data_in <= {data_in[6:​0],​spi_mosi};​ 
 + end 
 + default: i <= 4'​d0;​ 
 + endcase 
 + 
 +/​*对比接收数据*/​ 
 +reg [2:​0]led;​  
 + 
 +always@(posedge clk_25m or negedge rst_n) 
 + if(!rst_n) 
 +     begin 
 + led <= 3'​b101;​ 
 +     end 
 + else if (data == ledr) 
 + led <= 3'​b011; ​                 //​红灯亮 
 + else if (data == ledg) 
 + led <= 3'​b101;​ //​绿灯亮 
 + else if (data == ledb) 
 + led <= 3'​b110;​ //​蓝灯亮 
 +  
 +assign {led_red,​led_green,​led_blue} = led; 
 + 
 +//​--------------------------delay----------------------------//​ 
 + reg spi_clk_r;​ 
 + always@(posedge clk_25m or negedge rst_n) 
 + if(!rst_n) 
 +     begin 
 + spi_clk_r <= 1'​d1;​ 
 +     end 
 + else  
 + spi_clk_r <= spi_clk;  
 + 
 +//​--------------------------spi_miso----------------------------//​ 
 +/​*发送模块*/​ 
 +reg [39:​0]data_out;​ 
 +reg [5:0]j; 
 +reg spi_out; 
 +always@(negedge spi_clk_r or negedge rst_n) 
 + if(!rst_n) 
 + begin 
 +     data_out <= hello; 
 +     spi_out <= 1'​d0;​ 
 +     j <= 6'​d0;​ 
 + end 
 + else case(j) ​ //​连续40个spi_clk_r时钟发送“hello”字符串 
 + 6'​d0:​ 
 +     begin 
 + {spi_out,​data_out[39:​1]} <= data_out; 
 + j <= j + 1'​d1;​ 
 +     end 
 + 6'​d39:​ 
 +     begin 
 + {spi_out,​data_out[39:​1]} <= data_out; 
 + data_out <= hello; 
 + j <= 6'​d0;​ 
 +     end 
 + default:​ 
 +     begin 
 + {spi_out,​data_out[39:​1]} <= data_out; 
 + j <= j + 1'​d1;​ 
 +     end 
 + endcase 
 +</​code>​ 
 +==== 五、 实验步骤 ==== 
 + 
 +1、把仿真器与iCore4的SWD调试口连接(直接相连或者通过转换器相连)。\\  
 +2、将USB-Blaster与iCore4的JTAG调试口相连。\\  
 +3、将跳线帽插在USB_UART。\\  
 +4、把iCore4(USB_UART)通过Micro USB线与计算机相连,为iCore4供电。如图13-2所示:\\  
 +图13-2 
 +5、打开串口精灵,找到对应口打开,如下图。\\  
 +{{ :​icore4:​icore4_fpga_13_3.png?​direct |图13-3}} 
 +6、打开KeilMDK开发环境,并打开实验工程。\\  
 +7、将ARM程序下载至iCore4。\\  
 +8、打开QuartusII开发环境,并打开实验工程。\\  
 +9、将FPGA程序下载至iCore4\\  
 +10、输入串口命令,观察实验现象。\\  
 +==== 六、 实验现象 ==== 
 +  * 在Commix上发送命令后,对应的ARM和FPGA的LED灯亮,同时接收显示:hello 
 + 
 +|串口命令发送格式 |ARM_LED现象 |FPGA_LED灯现象| 
 +|LEDR\CR\LF |红灯亮 |红灯亮| 
 +|LEDG\CR\LF |绿灯亮 |绿灯亮| 
 +|LEDB\CR\LF |蓝灯亮 |蓝灯亮| 
 + 
基于spi总线的arm与fpga通信实验.1576898873.txt.gz · 最后更改: 2019/12/21 11:27 由 zhangzheng