STM32F411 DMA2 keil调试时,能够使用,不调试,就没有反应
本帖最后由 nbh520 于 2017-11-7 16:58 编辑STM32F411芯片在使用USART6 RX DMA2时,发现DMA2不能正常工作,经测试发现,在keil调试状态下,DMA2可以正常接收数据,否则不能接收数据。使用环境:其他外设均以关闭,没有进入低功耗,只有USART6处于工作状态,且已验证,在不使用DMA2时,USART6能够正常接收。 USART6的软件配置如下,项目很急,请各路大神,帮帮看看,指点一下。
/******************************UART 6*****************************************/
#define GPS_COMM_USART_6 USART6
#define GPS_COMM_USART_CLK_ENABLE() __HAL_RCC_USART6_CLK_ENABLE()
#define DMA2_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE()
#define GPS_COMM_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define GPS_COMM_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define GPS_COMM_USART_FORCE_RESET() __HAL_RCC_USART6_FORCE_RESET()
#define GPS_COMM_USART_RELEASE_RESET() __HAL_RCC_USART6_RELEASE_RESET()
/* Definition for USARTx Pins */
#define GPS_COMM_USART_TX_PIN GPIO_PIN_6
#define GPS_COMM_USART_TX_GPIO_PORT GPIOC
#define GPS_COMM_USART_TX_AF GPIO_AF8_USART6
#define GPS_COMM_USART_RX_PIN GPIO_PIN_7
#define GPS_COMM_USART_RX_GPIO_PORT GPIOC
#define GPS_COMM_USART_RX_AF GPIO_AF8_USART6
/* Definition for USARTx's DMA */
#define GPS_COMM_USART_TX_DMA_CHANNEL DMA_CHANNEL_5
#define GPS_COMM_USART_RX_DMA_CHANNEL DMA_CHANNEL_5
/* Definition for USARTx's DMA Request */
#define GPS_COMM_USART_TX_DMA_STREAM DMA2_Stream6
#define GPS_COMM_USART_RX_DMA_STREAM DMA2_Stream2
/* Definition for USARTx's NVIC */
#define GPS_COMM_USART_DMA_TX_IRQn DMA2_Stream6_IRQn
#define GPS_COMM_USART_DMA_RX_IRQn DMA2_Stream2_IRQn
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example:
* - Peripheral's clock enable
* - Peripheral's GPIO Configuration
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDefGPIO_InitStruct;
if(huart->Instance == GPS_COMM_USART_6)
{
/*##-1- Enable peripherals and GPIO Clocks #################################*/
GPS_COMM_USART_TX_GPIO_CLK_ENABLE();
GPS_COMM_USART_RX_GPIO_CLK_ENABLE();
GPS_COMM_USART_CLK_ENABLE();
DMA2_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
GPIO_InitStruct.Pin = GPS_COMM_USART_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPS_COMM_USART_TX_AF;
HAL_GPIO_Init(GPS_COMM_USART_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPS_COMM_USART_RX_PIN;
GPIO_InitStruct.Alternate = GPS_COMM_USART_RX_AF;
HAL_GPIO_Init(GPS_COMM_USART_RX_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the DMA ##################################################*/
gps_comm_hdma_rx.Instance = GPS_COMM_USART_RX_DMA_STREAM;
gps_comm_hdma_rx.Init.Channel = GPS_COMM_USART_RX_DMA_CHANNEL;
gps_comm_hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
gps_comm_hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
gps_comm_hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
gps_comm_hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
gps_comm_hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
gps_comm_hdma_rx.Init.Mode = DMA_NORMAL;
gps_comm_hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
gps_comm_hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
gps_comm_hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
gps_comm_hdma_rx.Init.MemBurst = DMA_MBURST_INC4;
gps_comm_hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&gps_comm_hdma_rx);
/* Associate the initialized DMA handle to the the UART handle */
__HAL_LINKDMA(huart, hdmarx, gps_comm_hdma_rx);
/*##-4- Configure the NVIC for DMA #########################################*/
//HAL_NVIC_SetPriority(USART5_DMA_TX_IRQn, 2, 1);
//HAL_NVIC_EnableIRQ(USART5_DMA_TX_IRQn);
HAL_NVIC_SetPriority(GPS_COMM_USART_DMA_RX_IRQn, GPS_COMM_USART_DMA_RX_IRQn_PRE_PRIORITY, DEFAULT_IRQ_SUB_PRIORITY);
HAL_NVIC_EnableIRQ(GPS_COMM_USART_DMA_RX_IRQn);
/*##-3- Configure the NVIC for UART ########################################*/
//HAL_NVIC_SetPriority(GPS_COMM_USART_IRQn, GPS_COMM_USART_DMA_RX_IRQn_PRE_PRIORITY, DEFAULT_IRQ_SUB_PRIORITY);
//HAL_NVIC_EnableIRQ(GPS_COMM_USART_IRQn);
}
}
/*************************************************************************
** function name: gps_comm_init
** description:
** input para:
**
** return:
**************************************************************************/
void gps_comm_init(void)
{
UartHandle.Instance = GPS_COMM_USART_6;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl= UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
/* Initialization Error */
GPS_COMM_DRIVER_DEBUG("** MY DEBUG INTERFACE FAILED. ** \r\n");
}
else
{
//MY_DEBUG("** MY DEBUG INTERFACE successfully. ** \r\n");
}
}
使用DMA做串口接收时,在启动DMA后需要将串口溢出标志清除(有些应用场景,串口接收端是一直有数据存在的),才能正常接收。
这个问题之前在使用STM32L072时,就已经发现解决了,但由于F4平台和L0平台在清除溢出标志方式略有不同。
为了避免有人出现同样的问题,下面给大家描述一下,两者的不同之处:STM32L0清除USART标志直接调用__HAL_USART_CLEAR_IT()即可
STM32F4 __HAL_UART_CLEAR_FLAG()能够清除的标志只有UART_FLAG_CTS、UART_FLAG_LBD、UART_FLAG_TC、UART_FLAG_RXNE,而PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun error) and IDLE (Idle line detected) flags 等标志的清除需要读取USART_SR register才行。
STM32L0
/** @briefClears the specified USART ISR flag, in setting the proper ICR register flag.
* @param__HANDLE__: specifies the USART Handle which can be USART1 or USART2.
* @param__IT_CLEAR__: specifies the interrupt clear register flag that needs to be set
* to clear the corresponding interrupt
* This parameter can be one of the following values:
* @arg USART_CLEAR_PEF: Parity Error Clear Flag
* @arg USART_CLEAR_FEF: Framing Error Clear Flag
* @arg USART_CLEAR_NEF: Noise detected Clear Flag
* @arg USART_CLEAR_OREF: OverRun Error Clear Flag
* @arg USART_CLEAR_IDLEF: IDLE line detected Clear Flag
* @arg USART_CLEAR_TCF: Transmission Complete Clear Flag
* @arg USART_CLEAR_CTSF: CTS Interrupt Clear Flag
* @retval None
*/
#define __HAL_USART_CLEAR_IT(__HANDLE__, __IT_CLEAR__) ((__HANDLE__)->Instance->ICR = (uint32_t)(__IT_CLEAR__))
STM32F4
/** @briefClears the specified UART pending flag.
* @param__HANDLE__: specifies the UART Handle.
* This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or
* UART peripheral.
* @param__FLAG__: specifies the flag to check.
* This parameter can be any combination of the following values:
* @arg UART_FLAG_CTS:CTS Change flag (not available for UART4 and UART5).
* @arg UART_FLAG_LBD:LIN Break detection flag.
* @arg UART_FLAG_TC: Transmission Complete flag.
* @arg UART_FLAG_RXNE: Receive data register not empty flag.
*
* @note PE (Parity error), FE (Framing error), NE (Noise error), ORE (Overrun
* error) and IDLE (Idle line detected) flags are cleared by software
* sequence: a read operation to USART_SR register followed by a read
* operation to USART_DR register.
* @note RXNE flag can be also cleared by a read to the USART_DR register.
* @note TC flag can be also cleared by software sequence: a read operation to
* USART_SR register followed by a write operation to USART_DR register.
* @note TXE flag is cleared only by a write to the USART_DR register.
*
* @retval None
*/
#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))
现在都使用的Cube一键配置了。。。。。现在能够帮你看出问题来的人,估计只有cube了!!! MrJiu 发表于 2017-11-7 11:23
现在都使用的Cube一键配置了。。。。。现在能够帮你看出问题来的人,估计只有cube了!!! ...
cube配置的代码,我也对比看了,没什么问题。本来想用keil断点调试看看,问题出在哪,结果就发现调试的时候,DMA2能够正常接收,吐血啊。 nbh520 发表于 2017-11-7 16:57
使用DMA做串口接收时,在启动DMA后需要将串口溢出标志清除(有些应用场景,串口接收端是一直有数据存在的), ...
你好!在论坛里看到你说用stm32L072做过DMA串口接收。我也在用DMA+串口空闲中断做任意长度数据的接收。现在遇到一个问题,如下:
假设DMA缓冲区长度为N,当数据长度≥N+1时,DMA接收中断能接收到前N个,串口空闲中断能接收到第N+1个,无论数据多长,串口空闲中断也只能接到1个。发现是串口溢出,我在串口中断中把溢出标志清除了,仍是如此。求指教。谢谢。
页:
[1]