STM3 USART + DMA未接收

问题描述 投票:1回答:2

我一直在学习如何编程stm32,我遇到了一个我似乎无法自己调试的问题。基本上,我希望通过UART接收3个字节,并使用DMA将它们存储到存储器中。任何帮助将不胜感激。确切的模式是核 - f401RE上的模式

  #include "main.h"
#include "stm32f4xx_hal.h"
#include <string.h>
#include <stdlib.h>


UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
uint8_t dataArrived =0;

int main(void)
{

HAL_Init();


  SystemClock_Config();

  MX_GPIO_Init();

  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
  HAL_Delay(500);
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
  HAL_Delay(500);

  __HAL_RCC_DMA1_CLK_ENABLE();  //enable clock to dma

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);


  hdma_usart2_tx.Instance  = DMA1_Stream5;
  hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
  hdma_usart2_tx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
  hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart2_tx.Init.Mode = DMA_NORMAL;
  hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
  HAL_DMA_Init(&hdma_usart2_tx);

  __HAL_LINKDMA(&huart2,hdmarx,hdma_usart2_tx);

  HAL_NVIC_SetPriority(DMA1_Stream5_IRQn,0,0);
  HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);

  HAL_NVIC_SetPriority(USART2_IRQn,0,0);
  HAL_NVIC_EnableIRQ(USART2_IRQn);

  uint8_t data[3];
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
  HAL_UART_Receive_DMA(&huart2, &data, 3);

  while(!dataArrived); //Wait for the arrival of data from UART
  /* Infinite loop */
  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
  while(1);

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
    dataArrived = 1;
}

void DMA1_Stream5_IRQHandler(void){
    HAL_DMA_IRQHandler(&hdma_usart2_tx);
}

基本上代码应该做的是等待接收三个字节并打开一个led。在hal_msp中启用USART的时钟以及引脚的配置,这是正确的,因为我使用CubeMX生成该代码。

stm32 cortex-m hal nucleo
2个回答
1
投票

dataArrived必须是volatile否则编译器看不到任何正常的程序流路径导致变量更改并优化它。

总是如果你使用在正常程序流程之外改变的变量,它们必须是易变的,让编译器知道它们是副作用。

当然重要的是使用任何级别优化。


0
投票

事实证明我有错误的dma流。我使用的是stream6,它用于Tx而不是stream5,这是用于Rx ... noob错误:/

© www.soinside.com 2019 - 2024. All rights reserved.