HAL_DMA_USARAT 普通模式只能发送一次数据,不知如何再次启DMA
#include"stm32l0xx_hal.h"UART_HandleTypeDef USART2_Handler ;
DMA_HandleTypeDef DMA1_Handler ;
uint8_tDMA1_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);
}
intmain(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、 自己判断是 HAL_DMA_Start(); 错误 ,但是本人不知道如何填写这个函数的源地址与目标地址 。
2 、 我用 USART2 发送一个 byte ,所以定义的数据类型为 uint8_t ,是否要更改为 uint32_t 。 傳送資料長度要一樣 , 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 庫的函數 還不是很熟:L
DMA1_Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE ;
DMA1_Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE ;
长度是一样的啊 。
uint8_tDMA1_USART2_TxDat = 0xaa ;数据我只是 定义了一个变量 ,也要 递增吗 ? 递增就跑飞啦 ? HAL_DMA_Start( &DMA1_Handler,(uint32_t)DMA1_USART2_TxDat,(uint32_t)USART2_Handler.Instance ->TDR ,1); 自己感觉应该是这个 启动函数没写对,不会写了。 HAL_DMA_Start里包含了 __HAL_DMA_ENABLE,不需要写两次,你应该去看看HAL的串口标准库文件,里面有几个串口操作的函数HAL_UART_Receive_DMA和HAL_UART_DMAStop应该要用到的 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 ;
另外 注意你定义变量数据类型也跟上面配置一致,即字节,半字、字要对应。 DMA需要配置中断的, __HAL_DMA_ENABLE(&DMA1_Handler)跟 HAL_DMA_Start重复了吧,都不需要的,已经包含在发送函数中了。
另外如果想开始后,DMA自己不停的发,DMA1_Handler.Init.Mode= DMA_NORMAL ;这里要改成循环模式,正常模式只会发送一次的。
循环发送,这样写没有问题,我的意思是 用 普通模式 ,发送一次数据后,再发送一次数据 ,应该这么改 ,据说是要重新启动一下 DMA函数, 我的判断是HAL_DMA_Start这个函数没写对。
函数的原型是这样HAL_DMA_Start (DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
uint8_tDMA1_USART2_TxDat = 0xaa ;但是我定义的 发送 数据类型是 uint8_t , 应该也是 8bit 的吧。是不是这个地方 有问题? 直接用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]