stm32与FPGA通信代码实现方案spi

2019-09-16来源: eefocus关键字:stm32  FPGA  通信代码实  spi

/*------------以下是FPGA与微控制器通信SPI模块的编程思路-分析-------------*/


模块结构框图

Spi_scl是SPI通信时钟,由主机自行产生,跟一般意义的时钟不一样,上升沿32发数据,下降沿32接收数据


主要由SPI信号缓存模块,SPI时钟边沿检测,命令接收+数据接收,发送几部分构成:

 

Spi_sdo:MISO发给32处理


dout:[31:0]:这个数据通过dcm的选择发给其他从机


Cmd_done:从器件地址接收完毕标志,高电平有效


Data_done:FPGA数据收发完成标志,高电平有效


rst:FPGA复位


clk:FPGA时钟


Spi_sdi:MOSI


Spi_cs_data:低电平时开启SPI接收数据(接收数据片选信号)


Spi_cs_cmd:使能FPGA接收其他从器件地址的信号,低电平有效


Spi_scl:32提供的通信时钟


din[31:0]:FPGA并行数据接收端口,接收外界待测频率信号


程序分析:


程序一:SPI信号两级缓存部分程序设计


(为避免产生毛刺和方便信号边沿检测,SPI通信中spi_scl(通信时钟),spi_cs_cmd(低,FPGA从器件地址接收片选),spi_cs_data(低,FP接收数据片选)这三个信号需要进行两级缓存)



这里只写spi_scl的二级缓存示例,其他两个方法一样


搞个always@(posedge clk )如同步复位的话就先清零spi_scl_reg1,else只是clk上升沿的话就让spi_scl_reg1<=spi_scl,这是一级缓存


在搞个always@(posedge clk)如同步复位的话就先清零spi_scl_reg,else只是clk上升沿的话就让spi_scl_reg<=spi_scl_reg1,这是二级缓存



程序二:SPI通信时钟边沿检测模块设计


//为什么要边沿检测,在SPI主从机通信中FPGA在sclk上升沿接收数据,在sclk下降沿进行数据发送//


第一部分:sclk上升沿检测模块:存储在scl_up_flag中


搞个always@(posedge clk )如同步复位的话就先清零spi_scl_flag,else只是clk上升沿的话就再判断if(spi_scl_reg1==1&&spi_scl_reg==0)//scl一级缓存为1且scl二级缓存为零,  就令scl_up_flag<=1,标志这时sc刚刚有过上升沿现在还在高电平状态,   else令scl_up_flag <= 0;


第二部分:sclk下降沿检测模块:存储在scl_down_flag中


搞个always@(posedge clk )如同步复位的话就先清零spi_down_flag,else只是clk上升沿的话就再判断if(spi_scl_reg1==0&&spi_scl_reg==1)//scl一级缓存为0且scl二级缓存为1,  就令scl_down_flag<=1,标志这时scl刚刚有过下降沿现在还在低电平状态,   else令scl_down_flag <= 0;


注意(这里的up和down信号个高电平会维持一个clk周期,称为高脉冲)


程序三:SPI通信接收模块设计

//这里只分析接收数据的方法,接收地址的方法不赘述地址为宽我们用8wei//


//手先需要spi_cs_data使能信号低电平有效,同时等到spi_scl上升沿时,接收模块将spi_sdi传入的串行数据经移位寄存器dout转成并行数据(注意没个上升沿只能传一位串行数据),经过数据位宽个spi_clk时钟后(我们用的是32位)数据片选使能才会拉高//


还是搞个always@(posedge clk )如同步复位的话就先清零spi_down_flag,else只是clk上升沿的话就再判断if(spi_cs_data_reg1==0&&spi_cs_data_reg==1)//scl一级缓存为0且scl二级缓存为1, 说明数据片选信号有效,允许接收数据,这是在判断有没有if(scl_up_flag)通信时钟为高电平,刚有过上升沿,现在开始用移位寄存器dout接收spi_sdi的串行数据第一个数,


dout[31:0] <={dout[30:0],spi_sdi} //  dout左移让输入数据先占据最低位,依此。。。


再搞个else,如果以上三条件有一个不满足的话就让dout保持原值。


//再产生数据接收结束标志,搞个data_done触发器,当数据片选信号拉高之后表明数据串转并完毕,这时再让相应的接收完成标志寄存器data_done <= 1//


 


判断刚刚有过数据片选上升沿的语句:if(spi_cs_data_reg1 = = 1&& spi_cs_data_reg = = 0)


数据接收一开始也是先判断刚刚有过下降沿if(spi_data_reg1== 0&&spi_data_reg== 1),这个时候是给dout<=0,如果不是这样就dout保持,


 


程序四:SPI通信数据发送模块设计


//刚刚说了spi_cs_data为低时数据接收,发送的方法跟接收是对称的,所以在spi_cs_data为高的期间,一旦spi_scl的下降沿到来,就要将刚刚接收的数据存入数据发送寄存器进行din_reg中,仍然是等到spi_cs_data低电平期间一旦spi_scl下降沿到来时就将din_reg中并行数据转换成串行数据并经过spi_sdo端口输出给stm32,有事经过位宽个通信时钟后数据发送完毕,spi_cs_data拉高,//


 


先发送最高位,if(scl_down_flag)


Spi_sdo <= din_reg[31]


din_reg[31:0]={din_reg[30:0],1’b0}//左移


//注意都别忘了当不满足条件时让spi_sdo和din_reg[31:0]都保持前面都是这样的,这是一个默认的规则,还有那个复位也是//


这里在spi_cs_data拉高之后让din_reg[31:0]获取下一轮din[31:0]中接收的数据,else还是保持,切记!!


 


总结:din[31:0]中的数据是FPGA其他模块传来的,外界传来的信号加上测频部分的可能有好几路31位的数据,先通到一个mux8_to1用sel(sel值由32发送过来)选择哪路进入到din[31:0]中,然后这个数据可以进入din_reg中再通过spi_sdo发送到stm32,32收到这个数据信号后就可以进行各种处理,如显示在屏幕上等。然后32那边发送过来的数据或命令进入spi_sdi口,这个串行数据可以通过移位寄存器一个个移入dout[31:0]中从而传给FPGA其他模块

关键字:stm32  FPGA  通信代码实  spi 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic474555.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:两块STM32之间的SPI通信
下一篇:STM32之SPIFLASH W24Q64的结构

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

4*4键盘程序代码 基于STM32
这是自己写的扫描第一行按键的程序代码。PE的位8~位11设置为下拉输入。PE的位12~位15设置为推挽输出其中PE的位11是4*4键盘的第一列,PE的为键盘的第一行。先将第一行设置为高电平,检测列中是否有高电平u8 KEY_Scan(u8 mode){                staticu8 key_up=1;//按键按松开标志         if(mode)key_up=1;  //支持连按        &nbs
发表于 2019-10-09
stm32中ADC初始化程序
void  Adc_Init(void){ uint32_t tmpreg1 = 0;ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1 , ENABLE );  //使能ADC1通道时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时钟不能超过14M/* PC0 作为模
发表于 2019-10-09
STM32F0 ADC学习
开始时候使用的是stdlib的库,最近发现cube库用的越来越广泛了,遂开始使用cube库来完成ADC的多通道采集实验。ADC 的driver 在STM32F0XX_HAL_DRIVER当中,有stm32f0xx_hal_adc.c文件中,我们可以在stm32f0xx_hal_conf.h中开启 宏定义 ADC 模块。ADC有三种工作模式,polling interruptDMA我这里使用了polling的方式来获取多通道的数据。首先是要声明两个参数设置的结构体ADC_HandleTypeDef             AdcHandle
发表于 2019-10-09
怎样用STM32 ADC测量电压(中断方式)
ADC 概述ADC是模数转换的缩写,是将连续的模拟信号转换为离散的数字信号,在通信,自动控制等多个领域有着广泛的应用,利用各种传感器,能将现实世界中的模拟量转换为机器能够识别的数字量,机器有了ADC,就像人有了各种感官,能够感知周围的世界并做出反应。STM32F10x  ADC特点l 12位逐次逼近型的模拟数字转换器。l 最多带3个ADC控制器l 最多支持18个通道,可最多测量16个外部和2个内部信号源。l 支持单次和连续转换模式l  转换结束,注入转换结束,和发生模拟看门狗事件时产生中断。l  通道0到通道n的自动扫描模式l  自动校准l  采样间隔可以按通道编程l&nbs
发表于 2019-10-09
怎样用STM32 ADC测量电压(中断方式)
STM32_ADC单通道单次采集
数位于在adc.c文件下面;调用这个接口就可以采集电压值。函数使用单通道单次,软件触发采样电压值,这里采样8次(更加自己情况可以选择多次),算平均,最后得出电压值(1000倍值)。五、主函数应用该函数位于在main.c文件下面;主要就是采集电压,通过串口打印出来(1000倍值)。 六、揭晓ADC123_IN2上面的问题有自己想明白了的吗?其实很简单的,ADC123_IN2顾名思义,它就是包含了ADC1、ADC2、ADC3的IN2的意思。也就是说,你们使用ADC2的通道2也是这个“ADC123_IN2”通道。方便大家学习,我把两个工程都上传至360云盘,不行的朋友可以亲自下载代码试试。对比的软件工程下载地址:https
发表于 2019-10-09
STM32_ADC单通道单次采集
STM32的ADC基本配置
(1)模/数转换工作于单通道还是多通道模式(2)工作于单次还是连续模式。(3)外部触发转换还是软件使能转换。(4)数据对齐方式,右对齐还是左对齐。(5)A/D转换的通道数目。(6)设置A/D通道的转换顺序及采样时间。其中转换时间为T.conv=采样时间+12.5个周期(7)⑥使能DMA启动传输⑦使能ADC⑧校准ADC,ADC的校准用到以下代码:/*重置ADC1的校准寄存器关/ADC_ ResetCal ibration( ADC1);/*获取ADC重置校准寄存器的状态*/while(ADC_ GetResetCal ibrat ionStatus(ADC1));ADC_ StartCal ibration(ADC1);/*开始校准
发表于 2019-10-09
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved