OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8989|回复: 8

STM32H7 在原子例程上把DMA-串口发送 改成DMA-SPI2发送,只能发送一次,再启动发送没有现象了。求大佬帮我,不甚感激

[复制链接]

16

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2014-7-14
在线时间
40 小时
发表于 2019-2-17 22:26:45 | 显示全部楼层 |阅读模式
10金钱
本帖最后由 在路上(起航) 于 2019-2-18 13:46 编辑

HAL库用的是V1.3版本
下面是DMA初始化
[mw_shl_code=applescript,true]void SPI2_DMA_Config(DMA_Stream_TypeDef *DMA_Streamx)
{
        if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
        {
        __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能        
        }else
        {
        __HAL_RCC_DMA1_CLK_ENABLE();//DMA1时钟使能
        }
   

    //Tx DMA配置
    SPI2TxDMA1_Handler.Instance=DMA_Streamx;                            //数据流选择
        SPI2TxDMA1_Handler.Init.Request=DMA_REQUEST_SPI2_TX;                                //SPI2发送DMA
    SPI2TxDMA1_Handler.Init.Direction=DMA_MEMORY_TO_PERIPH;             //存储器到外设
    SPI2TxDMA1_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
    SPI2TxDMA1_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
    SPI2TxDMA1_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
    SPI2TxDMA1_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
    SPI2TxDMA1_Handler.Init.Mode=DMA_NORMAL;                            //外设流控模式
    SPI2TxDMA1_Handler.Init.Priority=DMA_PRIORITY_HIGH;                 //中等优先级
    SPI2TxDMA1_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    SPI2TxDMA1_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
    SPI2TxDMA1_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
    SPI2TxDMA1_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输


    HAL_DMA_DeInit(&SPI2TxDMA1_Handler);   
    HAL_DMA_Init(&SPI2TxDMA1_Handler);
   
    __HAL_LINKDMA(&SPI2_Handler,hdmatx,SPI2TxDMA1_Handler);    //将DMA与USART1联系起来(发送DMA)
   

} [/mw_shl_code]

下面是初始化SPI2
[mw_shl_code=applescript,true]void SPI2_Init(void)
{
    SPI2_Handler.Instance=SPI2;                      //SP2
    SPI2_Handler.Init.Mode=SPI_MODE_MASTER;          //设置SPI工作模式,设置为主模式
    SPI2_Handler.Init.Direction=SPI_DIRECTION_2LINES_TXONLY;//设置SPI单向或者双向的数据模式:SPI设置为双线模式
    SPI2_Handler.Init.DataSize=SPI_DATASIZE_8BIT;    //设置SPI的数据大小:SPI发送接收8位帧结构
    SPI2_Handler.Init.CLKPolarity=SPI_POLARITY_LOW; //串行同步时钟的空闲状态为高电平
    SPI2_Handler.Init.CLKPhase=SPI_PHASE_1EDGE;      //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
    SPI2_Handler.Init.NSS=SPI_NSS_SOFT;              //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
    SPI2_Handler.Init.NSSPMode=SPI_NSS_PULSE_DISABLE;//NSS信号脉冲失能
    SPI2_Handler.Init.MasterKeepIOState=SPI_MASTER_KEEP_IO_STATE_ENABLE;  //SPI主模式IO状态保持使能
    SPI2_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4;//定义波特率预分频的值:波特率预分频值为256
    SPI2_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;     //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    SPI2_Handler.Init.TIMode=SPI_TIMODE_DISABLE;     //关闭TI模式
    SPI2_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
    SPI2_Handler.Init.CRCPolynomial=7;               //CRC值计算的多项式
    HAL_SPI_Init(&SPI2_Handler);
   
    __HAL_SPI_ENABLE(&SPI2_Handler);                 //使能SPI2
//    SPI2_ReadWriteByte(0Xff);                        //启动传输
}[/mw_shl_code]

下面是循环调用,100MS调用一次
[mw_shl_code=applescript,true]HAL_SPI_DMAStop(&SPI2_Handler);      //传输完成以后关闭串口DMA
        HAL_SPI_Transmit_DMA(&SPI2_Handler, showBuff, 36); //开启DMA传输[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

我也遇到了这样的问题,经过几天的加班调试,终于解决了,确实是HAL库的问题。我用的是SPI1+DMA1,发送通道是stream1,接收通道是stream2。每次只发送得了一次,下次再从相同入口HAL_SPI_Receive_DMA( )进入就无法再接收或者发送了。然后就进入状态: hspi->Lock = LOCKED; hspi->State = HAL_SPI_STATE_BUSY_RX;(不一定是这个状态,但肯定不是ready状态) hspi->hdmarx->Lock = HAL_LOCKED; hspi->hdmatx->Lock = HA ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-8-3
在线时间
2 小时
发表于 2019-2-17 22:26:46 | 显示全部楼层
我也遇到了这样的问题,经过几天的加班调试,终于解决了,确实是HAL库的问题。我用的是SPI1+DMA1,发送通道是stream1,接收通道是stream2。每次只发送得了一次,下次再从相同入口HAL_SPI_Receive_DMA( )进入就无法再接收或者发送了。然后就进入状态:
                hspi->Lock = LOCKED;
                hspi->State = HAL_SPI_STATE_BUSY_RX;(不一定是这个状态,但肯定不是ready状态)
                hspi->hdmarx->Lock  = HAL_LOCKED;
                hspi->hdmatx->Lock  = HAL_UNLOCKED;
                hspi->hdmarx->State = HAL_SPI_STATE_BUSY_RX;(不一定是这个状态,但肯定不是ready状态)
                hspi->hdmatx->State = HAL_SPI_STATE_BUSY_RX;(不一定是这个状态,但肯定不是ready状态)
      一旦发送完第一次后,就将进入如上状态,这些状态是由HAL库自动维护的,我没有去修改。
     看过HAL库的都知道,里面很多接口都有Lock和unlock个功能,一旦处于lock状态,就别想进行其他操作了。SPI无法操作、DMA Rx、DMA Tx也是,那么自然只能发送一次了。
      我不想去改HAL库,这些状态维护还是要花点功夫的。我用了两招,解决了这个问题:
     (1)直接在每次进入HAL_SPI_Receive_DMA( )前,把spi、DMA Rx、DMA Tx的那些个状态赋值到ready状态;
     (2)在进入HAL_SPI_Receive_DMA( )前,把SPI 的EOT、TXTF标志给清了,这两个标志要在,SPI就会终止数据业务;
     然后终于能正常收发数据了!HAL啊,问题还是有的,原子的教程也有时候还得自己慢慢调通,学无止境啊。有兴趣可以私聊qq:2629374484
回复

使用道具 举报

16

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2014-7-14
在线时间
40 小时
 楼主| 发表于 2019-2-17 22:32:21 | 显示全部楼层
本帖最后由 在路上(起航) 于 2019-2-17 22:34 编辑

HAL库版本是V1.3,有没有可能是HAL库的问题呢
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2019-2-18 12:09:42 | 显示全部楼层
一般跟版本没问题,比较多的是程序问题,你把单次传输改成循环传输试下
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

16

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2014-7-14
在线时间
40 小时
 楼主| 发表于 2019-2-18 21:09:02 | 显示全部楼层
谢谢楼上,试了一下,循环模式可以一直传输
回复

使用道具 举报

16

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2014-7-14
在线时间
40 小时
 楼主| 发表于 2019-2-18 23:07:29 | 显示全部楼层
发现一个新的现象,进行一次DMA传输后。即便关闭了DMA,用SPI发送函数也发送不了了,像是DMA锁住了SPI,有大神解决一下吗,多谢了
回复

使用道具 举报

16

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2014-7-14
在线时间
40 小时
 楼主| 发表于 2019-2-19 18:07:31 | 显示全部楼层
仿真跟踪了一下,第二次启动DMA传输时,会进入一个错误状态 hspi->State = HAL_SPI_STATE_BUSY
[mw_shl_code=applescript,true]  if (hspi->State != HAL_SPI_STATE_READY)
  {
    errorcode = HAL_BUSY;
    __HAL_UNLOCK(hspi);
    return errorcode;
  }[/mw_shl_code]
回复

使用道具 举报

6

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2018-12-7
在线时间
45 小时
发表于 2019-7-4 14:56:09 | 显示全部楼层
楼主调通了吗,方便的话想交流下,qq+734806050
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2021-7-17 02:21:22 | 显示全部楼层
一叶飞流 发表于 2021-7-16 16:18
我也遇到了这样的问题,经过几天的加班调试,终于解决了,确实是HAL库的问题。我用的是SPI1+DMA1,发送通道 ...

谢谢分享
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 11:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表