1

我一直在学习如何对 stm32 进行编程,但遇到了一个我似乎无法自行调试的问题。基本上,我想通过 UART 接收 3 个字节并使用 DMA 将它们存储到内存中。任何帮助将不胜感激。确切的模式是 nucleo-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。USART 的时钟在 hal_msp 以及引脚配置中启用,这是正确的,因为我使用 CubeMX 生成该代码。

4

2 回答 2

1

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

如果您使用在正常程序流程之外更改的变量,则它们必须是易失的,以让编译器知道它们容易产生副作用。

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

于 2018-09-03T21:48:03.010 回答
0

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

于 2018-09-03T21:55:42.467 回答