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();串口接收错误函数
相关推荐
代码山河8 小时前
Python就业方向全解析:后端、爬虫、数据分析、AI你选哪个?
python·学习·架构·教程·面向对象·项目
释厄6238 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
吠品9 小时前
智谱开源 ZCode 之后,真正的考试才开始
单片机·嵌入式硬件·1024程序员节
Chery114010 小时前
高速ADC与精密DAC怎么选?DP9230D与DP8532D应用解析
嵌入式硬件·物联网·射频工程
小嘉丶学长12 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
小李不想当小白13 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
LCG米13 小时前
STM32驱动W5500以太网模块实测:TCP吞吐瓶颈定位、TX指针回绕陷阱与断线重连保活落地
stm32·单片机·嵌入式硬件·tcp/ip
尼喃15 小时前
662K/65Z5三脚稳压芯片规格书—PW6566B33/B30引脚功能
嵌入式硬件
创界工坊工作室15 小时前
63-基于STC89C52霍尔传感器的智能化电能表设计
stm32·单片机·嵌入式硬件·51单片机·proteus
智购科技自动售货机厂家16 小时前
让AI经营自动售货机:从Project Vend看工具权限与业务规则~YH
大数据·服务器·单片机·嵌入式硬件·深度学习