本实验讲究实用性,故设计思想为:主机先向从机发送地址,若是向从机写入数据,则向从机发送数据,若是读取从机数据,则向从机发送时钟,然后在时钟下降沿读取数据即可。cs信号上升沿作为SPI通信的结束信号。rom程序只是做测试使用。
每次发送16个时钟信号,前八个是地址和命令,后八个是数据。其中:前8个时钟接受的数据的最高位决定着这次通信是读取数据还是写入数据,最高位为1,则是读取数据,为0则是写入数据。
程序:
/********************************Copyright************************************** **----------------------------File information-------------------------- ** File name :spi_slave_2.v ** CreateDate :2015.004 ** Funtions :spi通信试验。FPGA作为从机,与主机进行通信。先接收主机发来的地址,再根据地址最高位来判断是读数据还是些数据, 然后从机是接收数据还是送出数据。地址最高位为高则是读取数据,否则为写数据.上升沿接收数据,下降沿发送数据 ** Operate on :M5C06N3L114C7 ** Copyright :All rights reserved. ** Version :V1.0 **---------------------------Modify the file information---------------- ** Modified by : ** Modified data : ** Modify Content: *******************************************************************************/ module spi_slave_2 ( clk, rst_n, spi_cs, spi_sck, spi_miso, spi_mosi, spi_over ); input clk; input rst_n; input spi_cs; input spi_sck; input spi_mosi; output reg spi_miso; output spi_over; //-----------------------------// reg spi_cs_2,spi_cs_1; reg spi_sck_2,spi_sck_1; reg spi_mosi_2,spi_mosi_1; wire spi_cs_pos; wire spi_cs_flag; wire spi_sck_neg; wire spi_sck_pos; wire spi_mosi_flag; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin {spi_cs_2,spi_cs_1} <= 2'b11; {spi_sck_2,spi_sck_1} <= 2'b00; {spi_mosi_2,spi_mosi_1} <= 2'b00; end else begin {spi_cs_2,spi_cs_1} <= {spi_cs_1,spi_cs}; {spi_sck_2,spi_sck_1} <= {spi_sck_1,spi_sck}; {spi_mosi_2,spi_mosi_1} <= {spi_mosi_1,spi_mosi}; end end assign spi_cs_pos = ~spi_cs_2 &spi_cs_1; assign spi_cs_flag = spi_cs_2; assign spi_sck_neg = ~spi_sck_1&spi_sck_2; assign spi_sck_pos = ~spi_sck_2&spi_sck_1; assign spi_mosi_flag = spi_mosi_2; assign spi_over = spi_cs_pos; //----------------------------------------// localparam idel = 4'd0; localparam rxd_addr = 4'd1; localparam jude_wr_rd = 4'd2; localparam rxd_data = 4'd3; localparam rxd_over = 4'd4; localparam txd_data = 4'd5; localparam txd_over = 4'd6; localparam end_sta = 4'd7; reg [3: