STM32F103RCT6学习之三:串口

1.串口基础

2.串口发送

1)基本配置

注意:实现串口通信功能需在keil中设置打开Use Micro LIB,才能通过串口助手观察到串口信息

2)编辑代码

cpp 复制代码
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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  uint8_t msg[]="Hello World!\n";
  while (1)
  {
    /* USER CODE END WHILE */
		HAL_UART_Transmit(&huart1,msg,sizeof(msg),HAL_MAX_DELAY);

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

3)分析 ---关于重定向

huart1是一个串口句柄,定义在usart.c中

如果重定向printf或sprintf,只需要重定义fputc和fgetc()

cpp 复制代码
#include<stdio.h>
int fputc(int ch,FILE *f){
	
	HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);
	
	return ch;
}
int fgetc(FILE  *f){
	uint8_t ch;
	HAL_UART_Receive(&huart1,(uint8_t*)&ch,1,0xffff);
	return ch;
}

那么主函数可以如下实现::

cpp 复制代码
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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		printf("Hello World\t\n");
		HAL_Delay(500);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

**吐槽一下,显示"%"只能用下面的方法

cpp 复制代码
printf("%%");
printf("%c",'%');

3.串口接收与发送

1)进行基本配置

除了上述配置外,加入中断

2)编辑代码

触发中断时系统会调用定义于stm32f1xx_it.c的void USART1_IRQHandler(void)

可以看到该中断服务函数又调用 HAL_UART_IRQHandler(&huart1),该函数定义于stm32f1xx_hal_uart.c中:

在传输模式下,该函数调用 UART_Receive_IT(huart);该函数同样定义于stm32f1xx_hal_uart.c中,该函数调用可重定义函数 HAL_UART_RxCpltCallback(huart);并重定向printf及sprintf

cpp 复制代码
#include<stdio.h>
int fputc(int ch,FILE *f){
	
	HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);
	
	return ch;
}
int fgetc(FILE  *f){
	uint8_t ch;
	HAL_UART_Receive(&huart1,(uint8_t*)&ch,1,0xffff);
	return ch;
}
#define RX_BUFFER_SIZE 50
uint8_t rxBuffer[RX_BUFFER_SIZE];//发送缓冲区
uint8_t rxData; //单字节接收数据
uint8_t txBuffer[RX_BUFFER_SIZE+10];//发送还出去
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1) // 检查是否为 USART1
    {
        static uint16_t rxIndex = 0;

        // 保存接收到的字节到缓冲区
        if (rxIndex < RX_BUFFER_SIZE - 1)  //确保不会写入超过缓冲区边界的位置
        {
            rxBuffer[rxIndex++] = rxData;

            // 如果接收到换行符(表示消息结束)
            if (rxData == '\n')
            {
                rxBuffer[rxIndex] = '\0'; // 添加字符串结束符

                // 拼接前缀并发送数据
                sprintf((char *)txBuffer, "STM32 Received: %s", rxBuffer);
               	printf("%s", txBuffer);

                rxIndex = 0; // 重置接收缓冲区索引
            }
        }

        // 继续接收下一个字节
        HAL_UART_Receive_IT(&huart1, &rxData, 1);
    }
}
cpp 复制代码
{

  /* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1, &rxData, 1);  //开启接收中断   参数为串口句柄、数据存储地址、接收字节数
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	//uint8_t msg[]="Hello World!\t\n";
	printf("Hello World!\t\n");
  while (1)
  {
    /* USER CODE END WHILE */

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

3)分析

HAL_UART_Receive_IT()很有趣?!不要忘了加!两处!

相关推荐
2501_922639584 小时前
率能半导体 SS6285L直流双向马达驱动芯片:18V/5A,覆盖电子锁、按摩仪、电动玩具、机器人四大应用场景
单片机·嵌入式硬件·硬件工程
xier_ran4 小时前
【infra之路】AI 编译器学习笔记(十三):AI 编译器全景——TVM、XLA、IREE 与其他
人工智能·笔记·学习
连山齐名4 小时前
ai应用开发的学习笔记
服务器·笔记·学习
专一的咸鱼哥4 小时前
预训练 ONNX 模型转换为 .eim
嵌入式硬件·机器人
SuperByteMaster5 小时前
三极管 做开关电路 要尽快跳过放大区
嵌入式硬件
xier_ran5 小时前
【infra之路】AI 编译器学习笔记(十四):为什么要 tiling,以及矩阵计算单元的“固定“
人工智能·笔记·学习
铅笔小新z5 小时前
【stm32】输入捕获-超声波测距
stm32·单片机·嵌入式硬件
Zw-awa5 小时前
PID 的花样:先看懂模糊 PID 和单神经元自适应 PID
stm32
燕落南枝5 小时前
HTML 学习:辅助标签 label 与字符实体
前端·学习·html
菩提树下的凡夫5 小时前
机器视觉LED光源控制器
单片机·嵌入式硬件