STM32
直播中

刘丽

7年用户 1235经验值
私信 关注
[问答]

如何使用STM32L476G-DISCO开发板对UART4引脚做测试呢

如何使用STM32L476G-DISCO开发板对UART4引脚做测试呢?有哪些操作步骤呢?

回帖(1)

肖蕾

2021-11-17 10:14:25
  环境
  STM32L476G-DISCO 开发板
  STM32CubeIDE 1.1.0
  STM32CubeMX 5.4.0
  说明:由于STM32L476G-DISCO 开发板将UART4串口的RX(PA1)和TX(PA0)两个引脚分别用于JoyStick的按键输入,和地相连,所以如果同样使用STM32L476G-DISCO开发板的UART4引脚做测试,需要根据原理图,将威廉希尔官方网站 板的C43C42R59断开(硬件小白,不知道不断可不可以)。
  STM32CubeMX配置
  UART4配置
  打开UART4,选择Asynchronous异步通信模式。参数设置默认。
  
  中断(NVIC)设置,打开串口总中断。
  
  DMA设置,打开接收Rx的DMA通道。
  
  GPIO设置,选择Rx和Tx的GPIO引脚。默认打开即可。
  
  整体的引脚视图
  
  时钟配置,选择自动生成的配置即可。
  
  之后生成工程文件即可。实际用的是STM32CubeIDE创建的工程,直接生成代码。
  相关代码(只贴出修改的代码)
  usart.c
  /* UART4 init function */
  void MX_UART4_Init(void) {
  huart4.Instance = UART4;
  huart4.Init.BaudRate = 115200;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart4) != HAL_OK) {
  Error_Handler();
  }
  //在这里添加__HAL_UART_ENABLE_IT(),打开huart4的空闲中断
  __HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
  }
  stm32l4xx_it.c
  //从其他文件中找到定义的相关变量
  /* USER CODE BEGIN EV */
  extern uint8_t rxData[100];
  extern uint8_t tempData[100];
  extern uint8_t receiveFlag;
  /* USER CODE END EV */
  /**
  * @brief This function handles UART4 global interrupt.
  */
  void UART4_IRQHandler(void) {
  /* USER CODE BEGIN UART4_IRQn 0 */
  uint8_t temp;
  if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_IDLE) != RESET) {
  //空闲中断
  //temp = huart4.Instance-》ISR;
  //清除空闲中断标志位
  __HAL_UART_CLEAR_IDLEFLAG(&huart4);
  //清除数据读寄存器
  temp = huart4.Instance-》RDR;
  temp = temp;
  //关闭DMA传输通道,防止在处理数据过程中有新的数据被DMA导入
  HAL_UART_DMAStop(&huart4);
  //对传输的数据进行转存处理,把rxData暂存区空闲出来,用来接收新的数据。
  if (strlen(rxData) != 0) {
  memcpy(tempData, rxData, strlen(rxData));
  memset(rxData, 0x00, strlen(rxData));
  }
  //再次清楚空闲中断标志位。打开空闲中断,重新启动串口DMA传输。
  __HAL_UART_CLEAR_IDLEFLAG(&huart4);
  __HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
  HAL_UART_Receive_DMA(&huart4, rxData, 100);
  //接收标志位置位。通知在主函数中处理数据。
  receiveFlag = SET;
  }
  /* USER CODE END UART4_IRQn 0 */
  HAL_UART_IRQHandler(&huart4);
  /* USER CODE BEGIN UART4_IRQn 1 */
  /* USER CODE END UART4_IRQn 1 */
  }
  main.c
  /* USER CODE BEGIN Includes */
  #include “string.h”
  /* USER CODE END Includes */
  //定义一些需要用到的全局变量。这些变量可能在其他文件中用到
  /* USER CODE BEGIN PV */
  uint8_t rxData[100] = { 0 };
  uint8_t tempData[100] = { 0 };
  uint8_t receiveFlag = RESET;
  /* USER CODE END PV */
  /* USER CODE BEGIN 4 */
  //定义UART错误回调函数,用来处理串口的各种错误。注意,如果是用多个串口同时工作,需要简单修改本函数中的判断逻辑,实现更好的兼容和代码的简洁。
  void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE : This function should not be modified, when the callback is needed,
  the HAL_UART_ErrorCallback can be implemented in the user file.
  */
  if (__HAL_UART_GET_FLAG(&huart4, UART_FLAG_ORE) != RESET) {
  __HAL_UART_CLEAR_OREFLAG(&huart4);
  HAL_UART_Receive_DMA(&huart4, rxData, 100);
  }
  }
  //主函数
  /**
  * @brief The application entry point.
  * @retval int
  */
  int main(void) {
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_UART4_Init();
  /* USER CODE BEGIN 2 */
  //在最开始开启串口的DMA传输
  /*
  经过测试、如果这里的数据长度BUFFERSIZE设为10的话,在第一次接收到的数据超过10位数据时,只能收到前10位数据,
  之后就无法继续接收数据了。断点了一下,并没有进入ORE的错误处理回调函数。还需要进一步调试。如果有
  哪位大佬看出来问题,不吝赐教。
  */
  HAL_UART_Receive_DMA(&huart4, rxData, BUFFERSIZE);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1) {
  /* USER CODE END WHILE */
  //当空闲中断一帧数据接收完成后,receiveFlag这个变量在中断函数中被置位。我们在主函数将接收到的数据再通过串口发送给上位机。
  if (receiveFlag != RESET){
  receiveFlag = RESET;
  HAL_UART_Transmit(&huart4, tempData, strlen(tempData), 1000);
  memset(tempData, 0x00, strlen(tempData));
  }
  HAL_Delay(500);
  /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
  }
  /* USER CODE END 4 */
  结果
  将BUFFERSIZE设置为1024后,牺牲了一些空间,但是保证串口接收到的数据不会丢失是正确的。具体的结果图就不贴了。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分