硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1138|回复: 15
收起左侧

[ThreadX全家桶] 使用DMA的一个问题

[复制链接]

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
发表于 2021-12-20 17:18:11 | 显示全部楼层 |阅读模式
本帖最后由 linminghui 于 2021-12-20 17:19 编辑

用串口来通信,加上DMA,可以发送和接收,但是这个标志位一直没有.判断条件不满足
QQ截图20211220171625.png

回复

使用道具 举报

3

主题

1261

回帖

1270

积分

至尊会员

积分
1270
发表于 2021-12-20 20:44:51 | 显示全部楼层
  1.   /*##-3- Configure the DMA ##################################################*/
  2.   /* Configure the DMA handler for Transmission process */
  3.   hdma_tx.Instance                 = USARTx_TX_DMA_STREAM;
  4.   hdma_tx.Init.Request             = USARTx_TX_DMA_CHANNEL;
  5.   hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  6.   hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
  7.   hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
  8.   hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  9.   hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
  10.   hdma_tx.Init.Mode                = DMA_NORMAL;
  11.   hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
  12.   hdma_tx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  13.   hdma_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  14.   hdma_tx.Init.MemBurst            = DMA_MBURST_INC4;
  15.   hdma_tx.Init.PeriphBurst         = DMA_PBURST_INC4;

  16.   HAL_DMA_Init(&hdma_tx);

  17.   /* Associate the initialized DMA handle to the UART handle */
  18.   __HAL_LINKDMA(huart, hdmatx, hdma_tx);

  19.   /* Configure the DMA handler for reception process */
  20.   hdma_rx.Instance                 = USARTx_RX_DMA_STREAM;
  21.   hdma_rx.Init.Request             = USARTx_RX_DMA_CHANNEL;
  22.   hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  23.   hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
  24.   hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
  25.   hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  26.   hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
  27.   hdma_rx.Init.Mode                = DMA_NORMAL;
  28.   hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
  29.   hdma_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
  30.   hdma_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
  31.   hdma_rx.Init.MemBurst            = DMA_MBURST_INC4;
  32.   hdma_rx.Init.PeriphBurst         = DMA_PBURST_INC4;

  33.   HAL_DMA_Init(&hdma_rx);

  34.   /* Associate the initialized DMA handle to the the UART handle */
  35.   __HAL_LINKDMA(huart, hdmarx, hdma_rx);
复制代码


你初始化都正确不?  上面示例代码,LINK部分,你的驱动里写了吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107683
QQ
发表于 2021-12-21 09:04:36 | 显示全部楼层
OS里面时候建议这种中断标志之类的都在中断里面完成,中断里仅发个消息通知给你的任务好点。
回复

使用道具 举报

58

主题

267

回帖

446

积分

高级会员

积分
446
发表于 2021-12-21 09:13:27 | 显示全部楼层
这种用法不对,DMA 发送时,你说的那个位在 DMA 完成中断中就已经处理完了,中断优先级比你这里高,当然你就查不到了。  正确做法就是三楼硬汉的方法,发送之后不用你自己循环查,在完成回调函数里发个信号量,你这里等待信号量就是了。
回复

使用道具 举报

3

主题

1261

回帖

1270

积分

至尊会员

积分
1270
发表于 2021-12-21 21:23:56 | 显示全部楼层
万一,他没开中断呢?
回复

使用道具 举报

80

主题

722

回帖

962

积分

金牌会员

积分
962
发表于 2021-12-22 00:06:09 | 显示全部楼层
morning_enr6U 发表于 2021-12-21 21:23
万一,他没开中断呢?

有道理
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107683
QQ
发表于 2021-12-22 09:43:46 | 显示全部楼层
morning_enr6U 发表于 2021-12-21 21:23
万一,他没开中断呢?

那个函数HAL_UART_Transmit_DMA里面会开启一批中断。

用户仅需NVIC开启就行。
回复

使用道具 举报

5

主题

192

回帖

212

积分

高级会员

积分
212
发表于 2021-12-22 13:28:49 | 显示全部楼层
串口DMA传输完成有callback函数,无论是IT和DMA都是HAL_UART_TxCpltCallback
你可以在这个回调函数里面建立标志位。

你这个写法和我以前一样,但是这样不对。

HAL库完全不用管这些标志位

可以看下这篇我写的

https://www.armbbs.cn/forum.php? ... p;highlight=STM32V6
回复

使用道具 举报

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
 楼主| 发表于 2021-12-22 13:54:22 | 显示全部楼层
eric2013 发表于 2021-12-22 09:43
那个函数HAL_UART_Transmit_DMA里面会开启一批中断。

用户仅需NVIC开启就行。

在哪里发送、接收完成了
回复

使用道具 举报

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
 楼主| 发表于 2021-12-22 13:58:32 | 显示全部楼层
旮旯旭 发表于 2021-12-22 13:28
串口DMA传输完成有callback函数,无论是IT和DMA都是HAL_UART_TxCpltCallback
你可以在这个回调函数里面建 ...

嗯,我好好看看。谢谢
回复

使用道具 举报

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
 楼主| 发表于 2021-12-22 15:08:17 | 显示全部楼层
发送可以进到发送完成回调函数,但是接受出现了个问题
QQ截图20211222150751.png
回复

使用道具 举报

2

主题

273

回帖

279

积分

高级会员

积分
279
发表于 2021-12-22 16:36:34 | 显示全部楼层
hal 库已经支持的进去中断会自动清除硬件标志位 我试过用if (HAL_DMA_STATE_BUSY != HAL_DMA_GetState(&huart1->hdmatx))检测DMA也不稳定
回复

使用道具 举报

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
 楼主| 发表于 2021-12-22 19:01:27 | 显示全部楼层
旮旯旭 发表于 2021-12-22 13:28
串口DMA传输完成有callback函数,无论是IT和DMA都是HAL_UART_TxCpltCallback
你可以在这个回调函数里面建 ...

请问,怎么实现不定长的串口接收DMA,我在网上找都是说用串口的空闲中断,但是我一开空闲中断就一直停留在串口中断里面了?
回复

使用道具 举报

3

主题

1261

回帖

1270

积分

至尊会员

积分
1270
发表于 2021-12-22 22:30:19 | 显示全部楼层
空闲中断后,要读取数据寄存器一次,就不进了,  不过DMA的你可以参考论坛里, 利用DMA半传输中断的,和接收超时中断,来做不定长传输的。
回复

使用道具 举报

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
 楼主| 发表于 2021-12-24 10:43:09 | 显示全部楼层
我用空闲中断+DMA做不定长传输,发送在接收的时候如果数据太长的话,只会接收到一部分33个,剩余的部分没了,波特率是1M
回复

使用道具 举报

17

主题

84

回帖

135

积分

初级会员

积分
135
QQ
 楼主| 发表于 2021-12-27 10:56:11 | 显示全部楼层
找到原因了,我把数据长度的类型设置得太小了
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-11 21:15 , Processed in 0.347780 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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