你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

HAL_DMA_USARAT 普通模式只能发送一次数据,不知如何再次启DMA

[复制链接]
285686334 提问时间:2018-12-4 14:25 /
#include"stm32l0xx_hal.h"

UART_HandleTypeDef   USART2_Handler ;
DMA_HandleTypeDef    DMA1_Handler ;

uint8_t  DMA1_USART2_TxDat = 0xaa ;

void USARTx_Initialization(void)
{
        __HAL_RCC_USART2_CLK_ENABLE();
       
        USART2_Handler.Instance             = USART2 ;
        USART2_Handler.Init.BaudRate        = 9600 ;
        USART2_Handler.Init.Mode            = UART_MODE_TX ;
        USART2_Handler.Init.WordLength      = UART_WORDLENGTH_8B ;
       USART2_Handler.Init.StopBits        = UART_STOPBITS_1 ;
       USART2_Handler.Init.Parity          = UART_PARITY_NONE ;
       USART2_Handler.Init.HwFlowCtl       = UART_HWCONTROL_NONE ;

      while(HAL_UART_Init(&USART2_Handler)!=HAL_OK);
}

void DMA1_Initialization(void)
{
        __HAL_RCC_DMA1_CLK_ENABLE() ;
       
        DMA1_Handler.Instance                   = DMA1_Channel4 ;
        DMA1_Handler.Init.Direction             = DMA_MEMORY_TO_PERIPH ;
        DMA1_Handler.Init.Mode                  = DMA_NORMAL ;
       DMA1_Handler.Init.MemDataAlignment      = DMA_MDATAALIGN_BYTE ;
      DMA1_Handler.Init.PeriphDataAlignment   = DMA_PDATAALIGN_BYTE ;
      DMA1_Handler.Init.MemInc                = DMA_MINC_DISABLE ;
      DMA1_Handler.Init.PeriphInc             = DMA_PINC_DISABLE ;
     DMA1_Handler.Init.Priority              = DMA_PRIORITY_HIGH ;
     DMA1_Handler.Init.Request               = DMA_REQUEST_4 ;         
     while(HAL_DMA_Init(&DMA1_Handler)!=HAL_OK);
       
     __HAL_LINKDMA(&USART2_Handler,hdmatx,DMA1_Handler);
       
//        HAL_UART_Transmit_DMA(&USART2_Handler,&DMA1_USART2_TxDat,1);
}

int  main(void)
{
       
        HAL_Init();
        USARTx_Initialization();
        DMA1_Initialization();
       
        while(1)
        {               
                HAL_UART_Transmit_DMA(&USART2_Handler,&DMA1_USART2_TxDat,1);       //第一次发送数据成功
               
/*以下是再次使能DMA与重启DAM ,但是不行 ,不知道是地址不对,还是我定义的数据类型为 uint8_t 错误 **/
                __HAL_DMA_ENABLE(&DMA1_Handler);
                HAL_DMA_Start( &DMA1_Handler,(uint32_t)DMA1_USART2_TxDat,(uint32_t)USART2_Handler.Instance ->TDR ,1);       
        }
}


评分

参与人数 1 ST金币 +20 收起 理由
STMCU + 20

查看全部评分

收藏 评论9 发布时间:2018-12-4 14:25

举报

9个回答
285686334 回答时间:2018-12-4 14:29:56
补充一下 :
   1、 自己判断是 HAL_DMA_Start(); 错误 ,但是本人不知道如何填写这个函数的源地址与目标地址 。
   2 、 我用 USART2 发送一个 byte ,所以定义的数据类型为 uint8_t ,是否要更改为 uint32_t 。
jeffhe1 回答时间:2018-12-4 16:24:21
傳送資料長度要一樣 , DMA1_Handler.Init.MemDataAlignment      = DMA_MDATAALIGN_BYTE ;
                                DMA1_Handler.Init.PeriphDataAlignment   = DMA_PDATAALIGN_BYTE ;
MemInc 應該要 Enable        , DMA1_Handler.Init.MemInc                = DMA_MINC_DISABLE ;
                                         DMA1_Handler.Init.PeriphInc             = DMA_PINC_DISABLE ;
內到外 方向應該沒錯         DMA1_Handler.Init.Direction             = DMA_MEMORY_TO_PERIPH ;
可能還要再試看看 , 對 HAL 庫的函數 還不是很熟  


285686334 回答时间:2018-12-4 16:47:36
DMA1_Handler.Init.MemDataAlignment      = DMA_MDATAALIGN_BYTE ;
DMA1_Handler.Init.PeriphDataAlignment   = DMA_PDATAALIGN_BYTE ;
长度是一样的啊 。
uint8_t  DMA1_USART2_TxDat = 0xaa ;  数据我只是 定义了一个变量 ,也要 递增吗 ? 递增就跑飞啦 ?
285686334 回答时间:2018-12-4 16:48:31
HAL_DMA_Start( &DMA1_Handler,(uint32_t)DMA1_USART2_TxDat,(uint32_t)USART2_Handler.Instance ->TDR ,1);    自己感觉应该是  这个 启动函数没写对,不会写了。
andrewsss 回答时间:2018-12-4 18:12:27
HAL_DMA_Start里包含了 __HAL_DMA_ENABLE,不需要写两次,你应该去看看HAL的串口标准库文件,里面有几个串口操作的函数HAL_UART_Receive_DMA和HAL_UART_DMAStop应该要用到的

评分

参与人数 1ST金币 +4 蝴蝶豆 +2 收起 理由
STMCU + 4 + 2

查看全部评分

xmshao 回答时间:2018-12-5 16:48:07
285686334 发表于 2018-12-4 14:29
补充一下 :
   1、 自己判断是 HAL_DMA_Start(); 错误 ,但是本人不知道如何填写这个函数的源地址与目标 ...

HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); 这是函数原型。
注意变量类型要一致。你说的传输数据是字节,在这个函数调用过程中没关系,你给的只是地址和
数据个数。

下面的配置才跟你传输数据宽度有关系。
DMA1_Handler.Init.MemDataAlignment      = DMA_MDATAALIGN_BYTE ;
DMA1_Handler.Init.PeriphDataAlignment   = DMA_PDATAALIGN_BYTE ;

另外 注意你定义变量数据类型也跟上面配置一致,即字节,半字、字要对应。

评分

参与人数 1ST金币 +5 蝴蝶豆 +3 收起 理由
STMCU + 5 + 3

查看全部评分

nanguofenghuo 回答时间:2018-12-5 22:02:32
DMA需要配置中断的, __HAL_DMA_ENABLE(&DMA1_Handler)跟 HAL_DMA_Start重复了吧,都不需要的,已经包含在发送函数中了。
另外如果想开始后,DMA自己不停的发,DMA1_Handler.Init.Mode  = DMA_NORMAL ;这里要改成循环模式,正常模式只会发送一次的。

评分

参与人数 1ST金币 +5 蝴蝶豆 +2 收起 理由
STMCU + 5 + 2

查看全部评分

285686334 回答时间:2018-12-7 14:27:09
循环发送,这样写没有问题,我的意思是 用 普通模式 ,发送一次数据后,再发送一次数据 ,应该这么改 ,据说是要重新启动一下 DMA函数  , 我的判断是  HAL_DMA_Start这个函数没写对  。
      函数的原型是这样  HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
      uint8_t  DMA1_USART2_TxDat = 0xaa ;  但是我定义的 发送 数据类型是 uint8_t , 应该也是 8bit 的吧。  是不是这个地方 有问题  ?
wh8 回答时间:2018-12-7 17:04:24
直接用HAL_UART_Transmit_DMA(&USART2_Handler,&DMA1_USART2_TxDat,1);这个是HAL的API帮你做好了,只要初始化设置没错DMA自动帮你发送1字节不用再调用HAL_DMA_Start的。
且发送完成后DMA是用中断通知CPU的。中断的回调函数接口HAL库也做好了是 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版