目录

银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-07-02 gingko 初次建立

实验十三:SPI通信实验——基于SPI总线的ARM与FPGA通信

一、 实验目的与意义

  1. 掌握SPI通信协议及实现方法。
  2. 掌握QuartusII的使用方法。

二、 实验设备及平台

  1. iCore4 双核心板点击购买
  2. Blaster(或相同功能)仿真器点击购买
  3. JLINK(或相同功能)仿真器。
  4. Micro USB线缆。
  5. Keil MDK 开发平台。
  6. Quartus开发平台。
  7. 电脑一台。

三、 实验原理

1.SPI简介

2.SPI功能说明

图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
读数据 07hA15~A8 A7~A0 数据(直至读完所有数据)
读错误信息 08h

4、本实验实现方式

实验原理图

四、 代码讲解

////////////////按字节接收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

五、 实验步骤

1、把仿真器与iCore4的SWD调试口连接(直接相连或者通过转换器相连)。
2、将USB-Blaster与iCore4的JTAG调试口相连。
3、将跳线帽插在USB_UART。
4、把iCore4(USB_UART)通过Micro USB线与计算机相连,为iCore4供电。如图13-2所示:
图13-2 5、打开串口精灵,找到对应口打开,如下图。
图13-3 6、打开KeilMDK开发环境,并打开实验工程。
7、将ARM程序下载至iCore4。
8、打开QuartusII开发环境,并打开实验工程。
9、将FPGA程序下载至iCore4
10、输入串口命令,观察实验现象。

六、 实验现象

串口命令发送格式 ARM_LED现象 FPGA_LED灯现象
LEDR\CR\LF 红灯亮 红灯亮
LEDG\CR\LF 绿灯亮 绿灯亮
LEDB\CR\LF 蓝灯亮 蓝灯亮