首页 > 编程知识 正文

FPGA与DSP通过EMIF通信,spi的线与mcu

时间:2023-05-03 18:47:00 阅读:51364 作者:4714

基于typo ra-copy-images-to : typo ra _ picture FPGA与MCU通信的SPI协议设计1. SPI总线协议介绍和硬件设计1.1 SPI总线协议介绍和硬件设计SPI总线(串行外围接口)

PIN定义NSS从选择线(低电平有效) SCK串行时钟线MOSI主输出/从输入线MISO主输入/从输出线既有具有中断信号INT的SPI接口芯片,也有只能作为从装置使用的sppi接口芯片

SPI特点:

允许同时发送和接收串行数据并向主或从设备提供时钟(频率可调;发送中断结束标志保护)写入冲突保护;总线竞争保护;SPI总线操作方案;SP0 )广泛使用) 1.2 STM8硬件

STM8优势:

集成16Mhz晶体振荡器,支持3.3V级别,并可与FPGA直接连接,支持串行最小TSSOP20封装,减少硬件设计和PCB空间,减少本实验MCU型号: STM8S103F3P6

FPGA--------跳线连接-----MCU

STM8核心板设计:

STM8原理图:

[外部链接图像的导出失败。 源站可能有防盗链机制。 建议保存图像并直接上传。 (img-UpSp7vXS-1627885304808 ) d 3360 (Intel FPGA (typo ra _ picture _ we chat图像_202107301708] )

为支持STM8引脚的SPI引脚pa3SPI _ NSS PC 5s pi _ sck PC6SPI _ mos IPC7SPI _ misostm 8的SPI接口NSS芯片选择了两种模式:

软件模式:支持多种设备,您可能希望根据需要选择软件模式并输出NSS . (为了支持今后更多的从站,这里选择PD2作为SPI_NSS。 )

硬件模式:只能通过PA3输出,并且只能支持一个设备。

为了便于在调试过程中查看,还设计了4位led指示灯。

1.3 SPI总线协议时序分析分析STM8的4种SPI时序:

STM8具有SPI硬核,调用SPI模块非常有用,但FPGA需要自行设计所有逻辑电路。

对于FPGA----MCU系统来说,要确定一个主站和一个从站,由于c语言线程控制的优势,FPGA作为并行运算,具有硬件加速的特点。

因此,一般以MCU为主机,以FPGA为从机。

[外部链接图像的导出失败。 源站可能有防盗链机制。 建议保存图像并直接上传。 (img-XXQlQEl6-1627885304810 ) d 3360 (英特尔FPGA (typo ra _ picture _ SPI协议设计-主从SPI通信框图. )

考虑以STM8为主机时的SPI时序图。

STM8主函数

void main () }

unsigned char i=0,rxd_char=0; //i=0; rxd_char=0; CLK_Configuration (; //时钟配置SPI_Init (; //SPI初始化LED_Init (; //LED初始化while(1) {for ) I=0; i=0xff; I ) ) {//0至255个循环rxd_char=SPI_sendbyte(I; //接收字符串=SPI发送的字符串led_data(rxd_char ); //LED检查函数delay_ms(500; //延迟500ms}} }

参数01CPOLSCK空闲时为低电平,活动时从低到高8个时钟SCK空闲时为高电平,活动时从高到低8个时钟CPHA的下降沿采样通过数组组合,CPHA

[导出外链图像失败。 源站可能有防盗链机制。 建议保存图像并直接上传。 (img-0ThdrTP5-1627885304811 ) d 3360 (英特尔FPGA (typo ra _ picture )图9 CPOL=CPHA=0

时间图分析:

)1) CS低电平有效

(2)主机MOSI在CS启用后开始输出。 从站在CLK的上升沿稳定地捕获

)3) MISO在CS有效后,在SCK启动时稳态捕获。

2. SPI总线协议的通信为2.1 STM8的SPI总线收发设计SPI接口初始化/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *。 //MSB为先,SPI数据的发送频率为

8MHz SPI_CR2 = (0<<7) | (0<<5) | (0<<4) | (0<<2) | (1<<1) | (1<<0);//全双工, 使能软件主模式 SPI_ICR = (0<<7) | (0<<6) | (0<<5) | (0<<4);//禁止所有中断 SPI_CR1 |= (1<<6); //开启SPI模块 PD_DDR_DDR2 = 1;//PD2 设置为输出引脚-----输出数据 PD_CR1_C12 = 1;//设置推挽输出 PD_CR1_C12 = 1;//设置输出频率 1 为10Mhz SPI_CS_HIGH();//CS信号高位( 关闭 slave )} SPI 收发函数的实现 /*****************SPI 发送,接收函数****************/unsigned char SPI_SendByte(unsigned char byte){ SPI_CS_LOW();//CS信号置0,开始 while( !(SPI_SR & 0x02) );//等待 发送寄存器 为空 SPI_DR = byte; //将发送的数据写到 ---> 数据寄存器 while( !(SPI_SR & 0x01) );//等待 接收寄存器 满 SPI_CS_HIGH();//CS 信号置1,结束 return SPI_DR;//读 数据寄存器} STM8 主函数 /******************STM8 主函数******************/void main(){ unsigned char i=0, rxd_char=0; CLK_Configuration(); //时钟配置SPI_Init();//SPI初始化LED_Init();//LED初始化 while(1){ for(i=0; i<=0xff; i++){//0 ~ 255循环 rxd_char = SPI_SendByte(i); //接收字符串 = SPI发送的字符串 LED_Data(rxd_char);//LED校验函数 Delay_ms(500);//延时500ms}} 2.2 边沿检测电路的FPGA实现 边沿检测电路: 检测输入信号 或 PFGA内部逻辑信号的跳变 ( 实现上升沿或下降沿的检测, 捕获得到边沿使能, 来作为时序逻辑的触发信号 )

通过边沿检测实现使能时钟, 提高FPGA时序逻辑稳定性.

边沿检测电路的实现: Trigger_rTrigger边沿检测低高上升沿高低下降沿

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BqrmW48t-1627885304814)(D:intelFPGAtypora_picture一级寄存实现的----捕获电路.png)]

一级的 D触发器寄存 在比较时, 当前时刻从外部输入的信号, 与前一时刻的信号不在同一时钟域( FPGA整体逻辑电路的 时钟域 )

二级D触发器作为信号的寄存 ----- 同步时钟设计, 以提高系统可靠性.

边沿检测电路的Verilog HDL 实现电路 //---------------------------------------------// MCU ----(data sync)----> FPGAregspi_sck_r0, spi_sck_rl;//spi dafault 1;always @(posedge clk or negedge rst_n) begin if(!rst_n) begin spi_sck_r0 <= 0; spi_sck_r1 <= 0;//data transfer clock end else begin spi_sck_r0 <= spi_sck; spi_sck_r1 <= spi_sck_r0; end endwire mcu_read_flag = ( ~spi_sck_r1 & spi_sck_r0 )? 1'b1 : 1'b0;//posedge of sck

上一级信号是 : 2级D触发器输出的信号 ----- spi_sck_r1

当前信号是 : D触发器输出的信号 ----- spi_sck_r0

通过两个信号的对比, 可检测出 spi_sck 上升沿 还是 下降沿, 并且输出-------读取使能信号 mcu_read_flag

总结 : 边沿检测, 使能输出.

2.3 SPI通信的数据接收模块设计 spi 数据接收模块的verilog HDL 实现

新建 : 06_MCU2FPGA_SPI_Test 文件夹

建立 : MCU2FPGA_SPI_Test 工程, 移植全局时钟管理模块( system_index ), LED显示模块( led_index 相关 )

(1) 新建 spi_receiver.v, 信号列表如下

`timescale 1ns / 1ns//-------------------------------------------//module spi_receiver(//global clock inputclk,//时钟 inputrst_n,//复位 //mcu spi interface inputspi_cs,//片选 inputspi_sck,//数据传输时钟 inputspi_mosi, inputspi_miso, //user interface outputregrxd_flag,//外部输出的rxd_data 的外部使能信号 outputreg[7:0]rxd_data//mcu发送的 串转并 后的 spi数据);

(2) spi总线接口的--------数据同步模块设计

SPI的数据由MCU输入,与FPGA不在同一个时钟域,同时MCU输入的数据相对于FPGA而言速率很低

采用 2级D触发器寄存输出同步。

代码:

//-------------------------------------------////MCU -----> FPGAregspi_cs_r0,spi_cs_r1;regspi_sck_r0,spi_sck_r1;regspi_mosi_r0,spi_mosi_r1;always @(posedge clk or negedge rst_n) begin if(!rst_n) begin spi_cs_r0 <= 1,spi_cs_r1 <= 1;//片选使能 spi_sck_r0 <= 0,spi_sck_r1 <= 0;//数据传输时钟 spi_mosi_r0 <= 0,spi_mosi_r1 <= 0;//mosi end else begin spi_cs_r0 <= spi_cs,spi_cs_r1 <= spi_cs_r0;//片选使能 spi_sck_r0 <= spi_sck, spi_sck_r1 <= spi_sck_r0; //数据传输时钟 spi_mosi_r0 <= spi_mosi,spi_mosi_r1 <= spi_mosi_r0; //mosi end endwiremcu_cs = spi_cs_r1;wiremcu_data = spi_mosi_r1;wiremcu_read_flag = (~spi_sck_r1 & spi_sck_r0) ? 1'b1 : 1'b0;//sck上升沿wiremcu_read_done = (~spi_cs_r1 & spi_cs_r0) ? 1'b1 : 1'b0;//cs上升沿

wire 输出的4个信号说明如表:

信号说明mcu_cs2级D触发器同步后的 spi_cs 信号mcu_data2级D触发器同步后的 spi_mosi 信号mcu_read_flagspi_sck同步边沿检测后的上升沿使能信号mcu_read_done8位spi数据传输完毕信号

(3) 8位spi数据接收

spi通信协议非常简单,数据的接口可以不用状态机来实现。

设计中主要根据 mcu_read_flag 信号来捕获 SPI 数据,

verilog HDL 代码如下:

//------------------------------------//sample signal, receive datareg [3:0] rxd_cnt;reg [7:0] rxd_data_r;always @(posedge clk or posedge rst_n) beginif (!rst) begin// resetrxd_cnt <= 0;rxd_data_r <= 0;end //-------------else if (mcu_cs == 1'b0) beginif(mcu_read_flag) begin //sck上升沿rxd_data_r[[3'd7 - rxd_cnt[2:0]] <= mcu_data;rxd_cnt <= rxd_cnt + 1'b1;//计数器加1,0-7-8endelse beginrxd_cnt <= rxd_cnt;rxd_data_r <= rxd_data_r;endend //------------- else beginrxd_cnt <= 0;rxd_data_r <= rxd_data_r; endend

设计电路时,首先判断 mcu_cs 是否有效,当 mcu_cs 无效,即 mcu_cs = 1, FPGA挂起,

否则根据使能信号 mcu_read_flag 来捕获 8位数据。8位数据的捕获根据 rxt_cnt 的计数来实现。

当mcu_read_flag 无效时,数据保持不变。

(4) 捕获完成后使能信号的输出

如 矩阵键盘检测电路 一样,在捕获到外部数据后, 为了便于后端模块的响应,人为输出一个读取完成后的触发信号,作为rxd_data 读取的激励。

当 mcu_cs 从有效到无效时,即完成一次 SPI 数据通信( 捕获到 mcu_read_down 有效 )。

//------------------------------------//output_spi_receive_data_and_receive_flagalways @(posedge clk or negedge rst_n) beginif (!rst) begin// resetrxd_flag <= 0;rxd_data <= 0;end else if (mcu_read_done) begin //mcu_read_done有效时读取 串转并 后的数据rxd_data_r rxd_flag <= 1'b1;//同步输出了并行数据捕获的 rxd_flag, 这2个信号同步输出,作为外部信号的激励。rxd_data <= rxd_data_r;endelse beginrxd_flag <= 0;rxd_data <= rxd_data;endend modelsim仿真(未完待续。。。) 2.4 SPI通信的数据发送模块设计

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。