DSP与STM32的SPI通信调试及浮点数据传输调试

来源:互联网 发布:下载伴奏的软件 编辑:程序博客网 时间:2024/05/22 07:50

        硬件环境:DSP为TMS320C6722,STM32为STM32F103ZG,两控制芯片为SPI三线连接,即SPI_SOMI,SPI_SIMO,SPI_CLK三线.

        首先整体简述下传输过程,DSP与STM32为SPI三线连接,无片选信号;DSP有一GPIO引脚连接至STM32外部中断引脚(在此处称为DataReady引脚);SPI虽然为全双工,但是在此项目中只需要DSP传输给STM32的数据,而不关心STM32传输给DSP的数据。STM32作为主机,DSP作为从机。为了节约CPU,从主机均使用SPI的DMA传输。数据传输的整体流程是这样的:DSP准备好数据后,会通过DataReady引脚由低电平变为高电平来触发STM32的外部中断,STM32在外部中断中将DMA开启,然后数据开始传输,STM32传输完成进入DMA传输完成中断,关闭DMA,STM32对收到的数据进行处理。

        下面简述DSP这边需要做的工作:

        熟悉C672x系列的人都知道,DMA在此系列芯片中占有相当大的作用(在C672x中称为dMAX)。DMA在C672x中可以进行数据传输、接收外部中断信号、触发CPU中断等等。

        对SPI及DMA进行配置:先对SPI进行配置,具体流程参考C672x的SPI手册(下面我也会贴出代码);然后对DMA的事件入口及传输入口进行配置。

        

        我没有用TI公司提供的CSL库,一开始是倾向于用CSL库的,但是在调试过程中发现麻烦重重,有些繁琐,而且好多函数不可见,封装在了.lib库里,远不如自己写驱动更简单方便。在main函数中调用上面的驱动函数后,只要STM32一开启DMA,就会有数据进入到C6722的SPI数据寄存器中,C6722就会触发SPI的DMA,传输开始。而且在传输过程中不需要CPU干预。

        还有一个问题需要注意。SPI0的三个引脚SPI_SOMI,SPI_SIMO,SPI_CLK跟C6722的Parallel Flash启动有关,上电时刻三个引脚的状态直接决定Parallel Flash启动能不能成功。刚开始调试时,DSP与STM32均下载好程序后,发现DSP无法启动,后来在DSP的仿真状态下查看CFGPIN0寄存器发现SPI_CLK的引脚状态为1(若想Parallel Flash启动成功,SPI_CLK的引脚状态应该为0)。后来仔细想,在STM32中没放程序的时候DSP启动没问题,所以可能是STM32的SPI驱动程序使得SPI_CLK的引脚状态在DSP捕获其时发生了变化,所以我在STM32调用SPI的驱动程序之前加了个延时,然后就好了,DSP可以正常启动。

        接下来是STM32这方面需要做的工作:

        STM32网上资料较多,而且也用的极其大众化,所以直接贴驱动代码。

         

         DMA的开启工作及传输完成所做的工作在代码中均有体现,不多说了。
        
        下面说下浮点数据的传输。用C6722就是因为其强大的数据处理能力,所以在传输给STM32的数据中自然缺不了浮点数。
        关于浮点数据的存储可以参考下面的链接:http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html
        我们以DSP传送浮点数data=8.25到STM32为例,简述下所要做的工作。
        DSP方面:若所有传送的数据都要放入Uint16  srcData[  ] 数组中,假设data放入数组最初的位置。浮点数在DSP占据32位,所以要存放在 srcData[ 0 ] 和 srcData[ 1 ] 中.
        处理如下:
        Uint16  *temp;
        temp = (Uint16 *)&data;
        srcData[ 0 ] =*temp;
        srcData[ 1 ] =*(temp+1);
        这样就将一个浮点数存入到了srcData[  ] 数组中。
        
        STM32方面:SPI的DMA传输完成后,会将数据存放在uint16_t    dstData[   ]数组中,我们要做的是将浮点数data提取出来。假设data传送过来存放到了dstData[ 0 ]和dstData[ 1 ]  中。处理如下:
        float  data_copy;
        uint16_t  *temp;
        temp = (uint16_t  *)&data_copy;
        *temp=dstData[ 0 ];
        *(temp+1)=dstData[ 1 ];
        这样就将接收到的8.25存放到了 data_copy中。注意,千万不能直接这样做:       
        float  data_copy;
        data_copy=dstData[ 1 ]<<16|dstData[ 0 ];
        我们知道,8.25存储在内存中是0x41040000,若按上面的方法做,因为dstData[  ]为16位无符号整形,所以直接赋给浮点型后data_copy=0x4E820800(以浮点数的方式存储数值大小为无符号整形0x41040000的数据)。因此定义一个指针,指向data_copy的存储地址,这样就不会出错了。       

0 0
原创粉丝点击