DMA的串口简单应用

串口通讯

1、简介

  • 串行接口是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。
    串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。

2、实现方式

(1)初始化设备

  • 将USART2改为"异步通讯"模式,其余保持默认
    alt text

注意串口工具的配置要和硬件保持一致:
alt text

  • 使能RCC,选择HSE
    alt text
  • 将按钮设置为"外部中断上升沿模式",触发为"上拉"
    alt text

(2)写入代码

I 控制小灯

  • 引入<string.h>头文件,以便输出字符串
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
/* USER CODE END Includes */
  • 定义接收数据用的字符串
  /* USER CODE BEGIN 2 */
  uint8_t ReceivedData[1];
  /* USER CODE END 2 */
  • 在主循环中写入以下内容
 /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_UART_Receive(&huart2, ReceivedData, 1,HAL_MAX_DELAY);//让单片机接收串口数据,并一直等待
	  //分析传入的指令
	  if(ReceivedData[0] == '1'){//为"1"时灯亮
		  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
	  }else if(ReceivedData[0] == '0'){//为"0"时灯灭
		  HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
	  }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

这样,当输入为"1"时,小灯亮起,输入为"0"时,小灯熄灭
alt text
alt text

II 检测按钮

  • 在主函数外部声明输出按钮状态的字符串,以及中断回调函数
/* USER CODE BEGIN 0 */
char message[] = "button pressed";//说明按钮状态的字符串
//当按钮被摁下,产生中断,CPU会执行以下代码:
 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 {
    //判断中断是否由按钮产生
	 if(GPIO_Pin == B1_Pin)
	 {
        /*注意:第二个参数要求为8位整型指针,因此需要将字符串转换数据类型*/
		 HAL_UART_Transmit(&huart2, (uint8_t*)message, strlen(message), 100);
	 }
 }
/* USER CODE END 0 */

这样,当按钮被摁下后,电脑端串口会接收到"button pressed"的字符串
alt text

3、代码清单

/**
  * @brief  在阻塞模式下接收一些数据
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 available through pData.
  * @param  huart 指向异步通讯结构体
  *               为指定的异步通讯串口模型进行配置
  * @param  pData 需要传输的数据地址(指针,可以是数组) (要求元素为16位或者8位整型)
  * @param  Size  接收的元素数量
  * @param  Timeout 判定位超时所需时间(等待时间)
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
/*参数同上*/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
//自定义的外部声明函数
 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 {
	 if(GPIO_Pin == B1_Pin)
	 {
		 HAL_UART_Transmit(&huart2, (uint8_t*)message, strlen(message), 100);
	 }
 }

流程图

  • 主函数
graph TD; Begin((开始)) ---> GPIO_Init[初始化GPIO] ---> UART_Init[初始化串口] ---> Transmit[等待串口内容] ---> Pend{判断指令内容} Pend --> |1|On[关闭小灯] Pend --> |0|Off[开启小灯] On ---> Transmit Off ---> Transmit
  • 中断
graph TD; Begin((触发中断)) ---> Pend{是否来自按钮} Pend ---> |是|Print[向串口打印“button pressed”] Pend ---> |否|endIn[结束中断] Print ---> Toggle[翻转小灯信号] Toggle ---> endIn
posted @ 2025-08-28 11:26  奶龙大王  阅读(18)  评论(0)    收藏  举报