8618|4

86

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

STM32的SPI1DMA通道读取SPIflash,有若干细节问题处理及讨论 [复制链接]

程序实现结果:
     用stm32的一个SPI,用DMA方式读取spi flsh中的内容,然后将读到的数据用usart1 dma发到PC上,baud:115200;

选用的FLASH:W25X40  4M bit

电路接法:
     stm32的spi1的四只引脚分别与flash的四只引脚一一对就就好

程序:
    见附件

以下为这两天的调试过程:(可以略过)
     刚开始自己把它想得似乎过于简单点了,以为只要用spi占用dma通道进行读取就行,实际上做起来问题来了?我要读取flash中的某个地址开始的一段数据,得先把命令和地址发过去给flash呀,不光是发,发了还要收呀,难道要用两个spi?spi1负责发送命令,spi2负责接收数据?纠结了会,正当要开始按这种思路开始的时候,思路终于来了。。。。

我的思路:
    用SPI1-tx发送命令,同时用SPI1-rx接收数据;

程序中的几个细节处理:
    1>定义一个地址和命令的发送数组: Flash_Add_Table[4],用来配置spi1-tx dma的reg地址;存放的是要发送的命令和地址信息,每次发送前将里面的内容更新,如:它的值为:0x0b 0x00 0x00 0x00,那么它代表的意思就是命令0x0b,开始地址为0x000000;(0x0b为flash的快速读取命令,地址宽度为3字节);
     注意这里只定义数组大小为4,哪怕是读取几千个字节它也是4,因为读取的时候只有前面命令字节和地址信息才有用,之后的信息是没用的,哪怕它越界;
    2>定义一个接收数据数组:Usart_TX_Buf[FLASH_BUF_TOTAL_NUM],用来配置spi1-rx dma的reg地址,这里的FLASH_BUF_TOTAL_NUM包括了发命令时收到的数据(前5字节)、真正要读取的数据(N字节)、CRC值(1字节),详细情况看程序;
    3>每次接收完成后复位CRC的值,要不然会出错;
        SPI_CalculateCRC( SPI1,  DISABLE);
        SPI_CalculateCRC( SPI1,  ENABLE);
    4>spi作主机模式,NSS脚得注意了,这种读数据的场合NSS得用软件管理了,NSS脚用GPIO用来驱动flash上的片选信息;
     
     
    讨论点:
    1>本想用一个数据实现上述1,2功能,但始终只能正确接收一次,下午搞了好几个小时也没搞成,后来才换成2个数据来实现,原因:rx-dma tx-dma同一时间抢占一个地址延时??
     
    2>程序的内容是循环读0x000000开始的4K内容,刚开始只有第一次是正常,随后的就是接收到的数前面多了一个字节,spi-rx dma传完后还有字节,什么原因还没找到,应急就在每次rx-dma启动前加了下面语句:
        if(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)!=RESET)
        {
            temp5=SPI1->DR;
        }
      这个地方还待改善;
    3>接收一次后发现SPI1_SR的CRCERR被置位了?我对过数据了,接收到的数据和flash中的数据是一样的,为什么会报CRC检验错误?怎么理解这个问题

手册中写道:
SPI带CRC的DMA功能  
当使能SPI使用CRC检验并且启用DMA模式时,在通信结束时,CRC字节的发送和接收是自动完成的。  
数据和CRC传输结束时,SPI_SR寄存器的CRCERR标志为’1’表示在传输期间发生错误。  

CRCERR:CRC错误标志 (CRC error flag)  位4  
0:收到的CRC值和SPI_RXCRCR寄存器中的值匹配;  
1:收到的CRC值和SPI_RXCRCR寄存器中的值不匹配。  
该位由硬件置位,由软件写’0’而复位。

既然是自动完成的,为什么报错?

USART-DMA测试.rar (1.28 MB)

此帖出自stm32/stm8论坛

最新回复

                                 TO,3楼janeslee 按你这种思路,我回头好好试试; 这样是简单多了,谢谢啦!!!  详情 回复 发表于 2010-12-16 12:40
点赞 关注
 

回复
举报

63

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
                                 CRC检验功能是通过计算数据流的CRC,再与发送方送来的CRC数值比较来检验数据的正确性;请问你的SPI Flash中存储了CRC数值并回送给STM32了吗?如果没有,当然会有CRCERR。
此帖出自stm32/stm8论坛
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
搞那么复杂,启动DMA之前先用SPI_SendByte这种方式把命令和地址发过去,然后根据读还是写分别启动DMA RX和DMA TX,DMA RX之前把SPI设置为SPI_Direction_2Lines_RxOnly,还要读一次SPIx->DR,以清除RXNE标志,避免DMA接收到的数据前面多一个无效字节。

等待FlashReady之前,一定要等到DMA传输完毕(即检查SPI_I2S_FLAG_TXE和SPI_I2S_FLAG_BSY标志),以免过早释放CS。另外完全不需要CRC检查。
此帖出自stm32/stm8论坛
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

4
 
谢谢版主~~

关于CRC,我的理解是这样:
如果我设定dma传输数据为10,发送方在发送完10byte后,是紧接着再发1byte的crc;
如果设定接收10byte,接收完第10byte后,会继续接收1byte作crc校验值,然后将这个值与通过硬件计算前10byte所生成的crc值(RXCRCR值)作比较,如果不同则出错;
不知这样理解是否正确?
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

5
 
TO,3楼janeslee
按你这种思路,我回头好好试试;
这样是简单多了,谢谢啦!!!
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表