STM32学习 1 ----串口通讯--阻塞式收发+支持printf

一、MicroLib微库和ARM标准C库有什么区别?

MicroLib是针对以C语言编写的基于ARM嵌入式应用程序的高度优化的库。与ARM Compiler工具链附带的标准C库相比,MicroLib具有明显的代码大小优势。下图可见微库在不同内核下代码量明显少很多:

因为针对MCU,通常存储(代码)资源相对较小,为了使其能用上标准函数,工对标准C库进行了优化,以减小代码量:

1.代码(数据)量更小 (对比上图)

2.缺少一些不常用标准库函数,比如:文件 I/O 的库函数。

3.微库最大程度优化代码量,可能会导致有些库代码运行速度更慢。

微库函数也是一种函数,其很多库函数原型在网上都能找到,如果你有特殊需求,可以不用微库,在库函数原型的基础上进行修改。比如:你的项目经过验证,发现微库的代码量,或者运行速度都不理想的情况下,可以自己修改原型函数。当然,在万不得已的情况下才建议修改原型函数。通常还是建议直接使用微库,毕竟经过别人多次验证的库,出现bug的概率更小。

keil上打开MicroLIB

二、修改usart.c

1)usart.h,在头文件头部定义段加入stdio.h

cpp 复制代码
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
2)重写fputc() & fgetc函数
cpp 复制代码
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"

/* USER CODE BEGIN 0 */
extern UART_HandleTypeDef huart1;
/**
 * @brief 重写C标准库fputc函数,重定向printf到串口1
 * @param ch 要输出的字符
 * @param f 输出流(printf默认传stdout,可忽略)
 * @retval 成功输出的字符
 */
int fputc(int ch, FILE *f)
{
    // 阻塞式发送字符到串口1(确保发送完成)
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); ///< 普通串口发送数据
    while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TC) == RESET)
    {

    }///<等待发送完成

    // 符合标准库返回要求
    return ch;
}

/**
 * @brief 重写C标准库fgetc函数,重定向scanf/getchar到串口1
 * @param f 输入流(scanf默认传stdin,可忽略)
 * @retval 成功接收的字符
 */
int fgetc(FILE * f) 
{
	uint8_t ch = 0;
    HAL_UART_Receive(&huart1, &ch, 1, HAL_MAX_DELAY);           ///< 普通串口接收数据
    while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET)
    {

    }///<等待接收完成

    // 符合标准库返回要求
    return ch; 
}

/* USER CODE END 0 */

3)main 函数的测试代码:

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

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    printf("STM32 HAL_UART_Transmit Success: %d\r\n", 12345); // 自动调用重写的fputc

4)运行效果

5)串口发送/接收函数

  • HAL_UART_Transmit();串口发送数据,使用超时管理机制
  • HAL_UART_Receive();串口接收数据,使用超时管理机制
  • HAL_UART_Transmit_IT();串口中断模式发送
  • HAL_UART_Receive_IT();串口中断模式接收
  • HAL_UART_Transmit_DMA();串口DMA模式发送
  • HAL_UART_Transmit_DMA();串口DMA模式接收

6)串口中断函数

  • HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
  • HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //串口发送中断回调函数
  • HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); //串口发送一半中断回调函数(用的较少)
  • HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //串口接收中断回调函数
  • HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
  • HAL_UART_ErrorCallback();串口接收错误函数
相关推荐
莎士比亚的文学花园2 小时前
硬件入门——51单片机
单片机·嵌入式硬件·51单片机
東雪木2 小时前
软件设计师考试复习——CPU 结构、流水线、存储体系(主存 / 辅存)
学习·软件设计师复习
2501_918126912 小时前
学习所有6502写游戏动作的语句
汇编·嵌入式硬件·学习·游戏·个人开发
夏日听雨眠2 小时前
文件学习9
数据结构·学习·算法
野犬寒鸦2 小时前
从零起步学习JVM|| 第二章:JVM基本组成及JVM内存区域详解
服务器·开发语言·后端·学习·面试·职场和发展
罗罗攀2 小时前
PyTorch学习笔记|张量的线性代数运算
人工智能·pytorch·笔记·学习·线性代数
苦涩花开54862 小时前
Kubernetes学习,记一些笔记
笔记·学习·kubernetes
liliangcsdn2 小时前
LLM长文本场景-多文档分布式分析示例
人工智能·学习
丝斯20112 小时前
AI学习笔记整理(74)——Python学习3
笔记·python·学习