目录
- 1.阻塞模式接收数据的影响
- [2.DEBUG 中断配置](#2.DEBUG 中断配置)
- [3. 开启串口中断函数理解](#3. 开启串口中断函数理解)
- [4. 配置中断回调函数](#4. 配置中断回调函数)
- [5. 代码](#5. 代码)
-
- [5.1 bsp_debug.h](#5.1 bsp_debug.h)
- [5.2 bsp_debug.c](#5.2 bsp_debug.c)
- [5.3 usart_com.h](#5.3 usart_com.h)
- [5.4 usart_com.c](#5.4 usart_com.c)
- 6.实验现象
1.阻塞模式接收数据的影响
根据上一节所学的,通过上位机给stm32C8T6发送数据,然后stm32C8T6接收数据后,重新发送回来,例如运行结果如下。

当我在上位机下面发送框给stm32C8T6发送数据123456789时候,stm32C8T6接收到数据后重新将数据123456789发送回来给上位机,上面框框是上位机接收到的数据。
但是这是在非阻塞模式下进行发送的数据,是正常的,我发送123456789后,单片机接收到,然后重新返回,9个字节数据,单片机每次只能接收一个字节数据,相当于它接收了9次,发送给上位机9次,数据正常,9个数据完全接收到了。
但是在另外一种情况下,在阻塞的情况下,当我在上位机向单片机发送123456789的时候,如果我已经发送过来数据了,但是单片机可能执行别的事情,比如延时3秒钟阻塞呀,这件事情的时候,就会出现数据接收不正确情况,这个是因为当我发送123456789的时候,可能在发送1的时候,1成功接收,但是发送2的时候,可能在阻塞里面了,会把那个2丢失,从而只能接收3,就是说当我吧发送的数据123456789的时候,中间可能有部分的数据会丢失,无法收到。
代码如下:
c
/**
******************************************************************************
* @file main.c
* @author 作者
* @version v1.0
* @date 2026.6.8
* @brief 串口接收之中断方式标准库写法
******************************************************************************
* @attention
*
* 版权声明
*
******************************************************************************
*/
#include "main.h"
#include "led/bsp_gpio_led.h"
#include "systick/bsp_systick.h"
#include "key/bsp_gpio_key.h"
#include "debug/bsp_debug.h"
#include "stm32f10x.h"
#include "usart/usart_com.h"
#include "delay/bsp_delay.h"
/**
* @brief 主函数
* @param 无
* @note 无
* @retval 无
*/
int main (void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
LED_GPIO_Config();
KEY_Init(&key1_info);
DEBUG_USART_Init();
ProgramRunLed_TaskInit(500);
Key_TaskInit(20);
SysTick_Init();
while(1)
{
/* 程序正常指示灯 */
ProgramRunLed_Task();
/* 按键长短触发灯 */
Key_Task();
/* 数据回显 */
if (USART_GetFlagStatus(DEBUG_USARTX, USART_FLAG_RXNE) == SET)
{
uint8_t data_temp = USART_ReceiveData(DEBUG_USARTX); //读取数据寄存器,读取后对应的寄存器会被复位
USART_SenByte(DEBUG_USARTX, data_temp);
USART_ClearFlag(DEBUG_USARTX, USART_FLAG_RXNE); //清除接收标志位
}
Rough_Delay_Ms(50);
}
}
实验现象

当我在代码里面加一个短暂延时50ms,进行阻塞时候,进行在上位机发送数据,我对123456789重复多次发送,大部分时候出现的是单片机只接收到了1,并且吧1返回给上位机,个别的时候,接收到了12和17,这是因为我发送123456789的时候,由于有短暂的阻塞50ms,导致数据接收不正确,导致数据接收过程中丢失,就是在接收别的数据的时候,可能因为阻塞的时候,导致没有接收到。
所以串口接收的时候采取的是非阻塞方式下,接下来学习串口中断方式去接收数据。
2.DEBUG 中断配置
中断函数配置
c
/**
* @brief 配置 DEBUG 中断配置
* @param 无
* @retval 无
*/
void DEBUG_NVIC_Config()
{
// 定义一个 NVIC 结构体
NVIC_InitTypeDef nvic_initstauct = { 0 };
/* 开启 AFIO 相关时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/*配置中断源*/
nvic_initstauct.NVIC_IRQChannel = DEBUG_IRQ;
/*配置抢占优先级*/
nvic_initstauct.NVIC_IRQChannelPreemptionPriority = 1;
/*配置响应优先级*/
nvic_initstauct.NVIC_IRQChannelSubPriority = 0;
/*开启中断*/
nvic_initstauct.NVIC_IRQChannelCmd = ENABLE;
// 把配置写入硬件,生效
NVIC_Init(&nvic_initstauct);
}
中断部分宏定义
c
#define DEBUG_IRQ USART1_IRQn /*外部中断向量号*/
#define DEBUG_IRQHANDLER USART1_IRQHandler /*中断处理函数*/
USART1_IRQn是在stm32f10x.h中

这个是中断号。
还有中断处理函数名字跟中断号前面一样,后面加了Handler, USART1_IRQnHandler。
3. 开启串口中断函数理解
c
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
这个函数是在stm32f10x_usart.h里面

有三个参数,
第一个参数选择的是哪一个串口,有串口1,串口2,串口3,那么我们用的是哪一个串口就选择哪一个串口
第二个参数选择的是哪一个中断源,有以下中断源选择
@arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
@arg USART_IT_LBD: LIN Break detection interrupt
@arg USART_IT_TXE: Transmit Data Register empty interrupt
@arg USART_IT_TC: Transmission complete interrupt
@arg USART_IT_RXNE: Receive Data register not empty interrupt
@arg USART_IT_IDLE: Idle line detection interrupt
@arg USART_IT_PE: Parity Error interrupt
@arg USART_IT_ERR: Error interrupt(Frame error, noise error, overrun error)
而我们是用到的是接收数据的时候触发中断源,就选择 USART_IT_RXNE
第三个参数是开启或关闭串口中断,ENABLE or DISABLE.
ENABLE是开启,DISABLE是关闭
代码
c
/**
* @brief 配置 DEBUG 串口模式
* @param 无
* @retval 无
*/
void DEBUG_USART_MODEConfig(void)
{
USART_InitTypeDef usart_InitStruct = { 0 };
/* 开启 DEBUG 相关的GPIO外设/端口时钟 */
DEBUG_APBXCLKCMD(DEBUG_USARTX_CLK_PORT, ENABLE); //开启 端口时钟
/* 配置串口的工作参数 */
//波特率配置:115200
usart_InitStruct.USART_BaudRate = DEBUG_BAUDRATE;
//硬件流控开关配置:无
usart_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
//配置工作模式:发送模式
usart_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
//校验:无校验位
usart_InitStruct.USART_Parity = USART_Parity_No;
//停止位:1个停止位
usart_InitStruct.USART_StopBits = USART_StopBits_1;
//数据帧长度:8位
usart_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(DEBUG_USARTX, &usart_InitStruct);
/* 开启串口数据接收中断 */
USART_ITConfig(DEBUG_USARTX, USART_IT_RXNE, ENABLE);
}
在配置串口模式代码里面末尾添加这行代码
c
/* 开启串口数据接收中断 */
USART_ITConfig(DEBUG_USARTX, USART_IT_RXNE, ENABLE);
开启串口1的接收数据中断源
4. 配置中断回调函数
c
/**
* @brief DEBUG 串口中断 回调函数
* @param 无
* @retval 无
*/
void DEBUG_IRQHANDLER(void)
{
/* 数据回显 */
if (USART_GetFlagStatus(DEBUG_USARTX, USART_FLAG_RXNE) == SET)
{
uint8_t data_temp = USART_ReceiveData(DEBUG_USARTX); //读取数据寄存器,读取后对应的寄存器会被复位
USART_SenByte(DEBUG_USARTX, data_temp);
USART_ClearFlag(DEBUG_USARTX, USART_FLAG_RXNE); //清除接收标志位
}
}
原本if里面那个函数是判断数据寄存器是否有数据,如果有就直接读取数据,但是现在是在中断函数里面操作,所以需要在中断寄存器里面判断数据寄存器是否有数据。
而


这个if是在SR寄存器里面操作的,而中断函数需要到中断寄存器操作



而检测数据寄存器是否有数据,在串口中断函数里面应该用这个

在stm32f10x_usart.c文件里面
这个函数操作的是CR1寄存器



在CR1中选择接收缓冲区非空中断使能RXNEIE
串口函数里面检测数据寄存器数据函数:
c
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
它有两个参数
参数1选择的是哪一个串口,有串口1,串口2,串口3...
参数2选择的是中断源
@param USART_IT: specifies the USART interrupt source to check.
This parameter can be one of the following values:
@arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
@arg USART_IT_LBD: LIN Break detection interrupt
@arg USART_IT_TXE: Tansmit Data Register empty interrupt
@arg USART_IT_TC: Transmission complete interrupt
@arg USART_IT_RXNE: Receive Data register not empty interrupt
@arg USART_IT_IDLE: Idle line detection interrupt
@arg USART_IT_ORE_RX : OverRun Error interrupt if the RXNEIE bit is set
@arg USART_IT_ORE_ER : OverRun Error interrupt if the EIE bit is set
@arg USART_IT_NE: Noise Error interrupt
@arg USART_IT_FE: Framing Error interrupt
@arg USART_IT_PE: Parity Error interrupt
而我们第二个参数选择的是 USART_IT_RXNE
而清除标志位在中断函数也有一个函数
c
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)

清除只能清除这四个中断源标志位
@arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
@arg USART_IT_LBD: LIN Break detection interrupt
@arg USART_IT_TC: Transmission complete interrupt.
@arg USART_IT_RXNE: Receive Data register not empty interrupt.
原本我们的清除标志位函数是
c
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
它能清除四个标志位
This parameter can be any combination of the following values:
@arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
@arg USART_FLAG_LBD: LIN Break detection flag.
@arg USART_FLAG_TC: Transmission Complete flag.
@arg USART_FLAG_RXNE: Receive data register not empty flag.
这个清除是对寄存器SR操作清除

通过对比发现
不管是检测数据寄存器是否有数据函数还是清除标志位函数有两种:
第一种是普通的对直接对SR寄存器操作
c
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
第二种是在串口中断函数CR寄存器操作
c
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)
可以发现在中断函数里面操作的函数,函数名字中间带一个IT。
代码:
c
/**
* @brief DEBUG 串口中断 回调函数
* @param 无
* @retval 无
*/
void DEBUG_IRQHANDLER(void)
{
/* 数据回显 */
if (USART_GetITStatus(DEBUG_USARTX, USART_IT_RXNE) == SET)
{
uint8_t data_temp = USART_ReceiveData(DEBUG_USARTX); //读取数据寄存器,读取后对应的寄存器会被复位
USART_SenByte(DEBUG_USARTX, data_temp);
USART_ClearITPendingBit(DEBUG_USARTX, USART_IT_RXNE); //清除接收标志位
}
}
5. 代码
5.1 bsp_debug.h
c
#ifndef __BSP_DEBUG_H
#define __BSP_DEBUG_H
#include "stm32f10x.h"
#define DEBUG_USART_NUM 1
#if(DEBUG_USART_NUM == 1)
#define DEBUG_TX_GPIO_PORT GPIOA /* GPIO 端口 */
#define DEBUG_TX_GPIO_CLK_PORT RCC_APB2Periph_GPIOA /* GPIO 端口时钟 */
#define DEBUG_TX_GPIO_PIN GPIO_Pin_9 /* 对应PIN脚 */
#define DEBUG_RX_GPIO_PORT GPIOA /* GPIO 端口 */
#define DEBUG_RX_GPIO_CLK_PORT RCC_APB2Periph_GPIOA /* GPIO 端口时钟 */
#define DEBUG_RX_GPIO_PIN GPIO_Pin_10 /*对应PIN脚 */
#define DEBUG_USARTX USART1 /* 串口号 */
#define DEBUG_USARTX_CLK_PORT RCC_APB2Periph_USART1 /* 串口外设时钟位 */
#define DEBUG_APBXCLKCMD RCC_APB2PeriphClockCmd /* 串口外设时钟 */
#define DEBUG_BAUDRATE 115200 /* 波特率 */
#define DEBUG_IRQ USART1_IRQn /*外部中断向量号*/
#define DEBUG_IRQHANDLER USART1_IRQHandler /*中断处理函数*/
#elif(DEBUG_USART_NUM == 2)
#define DEBUG_TX_GPIO_PORT GPIOA /* GPIO 端口 */
#define DEBUG_TX_GPIO_CLK_PORT RCC_APB2Periph_GPIOA /* GPIO 端口时钟 */
#define DEBUG_TX_GPIO_PIN GPIO_Pin_2 /* 对应PIN脚 */
#define DEBUG_RX_GPIO_PORT GPIOA /* GPIO 端口 */
#define DEBUG_RX_GPIO_CLK_PORT RCC_APB2Periph_GPIOA /* GPIO 端口时钟 */
#define DEBUG_RX_GPIO_PIN GPIO_Pin_3 /* 对应PIN脚 */
#define DEBUG_USARTX USART2 /* 串口号 */
#define DEBUG_USARTX_CLK_PORT RCC_APB1Periph_USART2 /* 串口外设时钟位 */
#define DEBUG_APBXCLKCMD RCC_APB1PeriphClockCmd /* 串口外设时钟 */
#define DEBUG_BAUDRATE 115200 /* 波特率 */
#define DEBUG_IRQ USART2_IRQn /*外部中断向量号*/
#define DEBUG_IRQHANDLER USART2_IRQHandler /*中断处理函数*/
#elif(DEBUG_USART_NUM == 3)
#define DEBUG_TX_GPIO_PORT GPIOB /* GPIO 端口 */
#define DEBUG_TX_GPIO_CLK_PORT RCC_APB2Periph_GPIOB /* GPIO 端口时钟 */
#define DEBUG_TX_GPIO_PIN GPIO_Pin_10 /* 对应PIN脚 */
#define DEBUG_RX_GPIO_PORT GPIOB /* GPIO 端口 */
#define DEBUG_RX_GPIO_CLK_PORT RCC_APB2Periph_GPIOB /* GPIO 端口时钟 */
#define DEBUG_RX_GPIO_PIN GPIO_Pin_11 /* 对应PIN脚 */
#define DEBUG_USARTX USART3 /* 串口号 */
#define DEBUG_USARTX_CLK_PORT RCC_APB1Periph_USART3 /* 串口外设时钟位 */
#define DEBUG_APBXCLKCMD RCC_APB1PeriphClockCmd /* 串口外设时钟 */
#define DEBUG_BAUDRATE 115200 /* 波特率 */
#define DEBUG_IRQ USART3_IRQn /*外部中断向量号*/
#define DEBUG_IRQHANDLER USART3_IRQHandler /*中断处理函数*/
#endif
void DEBUG_USART_PinConfig(void);
void DEBUG_USART_MODEConfig(void);
void DEBUG_USART_Init(void);
void DEBUG_NVIC_Config(void);
#endif /*__BSP_DEBUG_H*/
5.2 bsp_debug.c
c
/**
******************************************************************************
* @file bsp_debug.c
* @author 作者
* @version v1.0
* @date 2026.6.6
* @brief 调试串口函数接口
******************************************************************************
* @attention
*
* 版权声明
*
******************************************************************************
*/
#include "debug/bsp_debug.h"
#include "usart/usart_com.h"
/**
* @brief 初始化控制 DEBUG 串口 的IO
* @param 无
* @retval 无
*/
void DEBUG_USART_PinConfig(void)
{
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
#if 1
/*对串口发送模式IO配置*/
/* 开启 DEBUG 相关的GPIO外设/端口时钟 */
RCC_APB2PeriphClockCmd(DEBUG_TX_GPIO_CLK_PORT, ENABLE); //开启GPIOA 端口时钟
// 配置引脚:选择GPIOA的Pin9
GPIO_InitStruct.GPIO_Pin = DEBUG_TX_GPIO_PIN;
// 配置输出速度:50MHz
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
// 配置工作模式:推挽复用
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(DEBUG_TX_GPIO_PORT, &GPIO_InitStruct);
#endif
#if 1
/*对串口接收模式IO配置*/
/* 开启 DEBUG 相关的GPIO外设/端口时钟 */
RCC_APB2PeriphClockCmd(DEBUG_RX_GPIO_CLK_PORT, ENABLE); //开启GPIOA 端口时钟
// 配置引脚:选择GPIOA的Pin10
GPIO_InitStruct.GPIO_Pin = DEBUG_RX_GPIO_PIN;
// 配置输出速度:50MHz
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
// 配置工作模式:上拉输入/浮空输入
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(DEBUG_RX_GPIO_PORT, &GPIO_InitStruct);
#endif
}
/**
* @brief 配置 DEBUG 串口模式
* @param 无
* @retval 无
*/
void DEBUG_USART_MODEConfig(void)
{
USART_InitTypeDef usart_InitStruct = { 0 };
/* 开启 DEBUG 相关的GPIO外设/端口时钟 */
DEBUG_APBXCLKCMD(DEBUG_USARTX_CLK_PORT, ENABLE); //开启 端口时钟
/* 配置串口的工作参数 */
//波特率配置:115200
usart_InitStruct.USART_BaudRate = DEBUG_BAUDRATE;
//硬件流控开关配置:无
usart_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
//配置工作模式:发送模式
usart_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
//校验:无校验位
usart_InitStruct.USART_Parity = USART_Parity_No;
//停止位:1个停止位
usart_InitStruct.USART_StopBits = USART_StopBits_1;
//数据帧长度:8位
usart_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(DEBUG_USARTX, &usart_InitStruct);
/* 开启串口数据接收中断 */
USART_ITConfig(DEBUG_USARTX, USART_IT_RXNE, ENABLE);
}
/**
* @brief 配置 DEBUG 中断配置
* @param 无
* @retval 无
*/
void DEBUG_NVIC_Config()
{
// 定义一个 NVIC 结构体
NVIC_InitTypeDef nvic_initstauct = { 0 };
/* 开启 AFIO 相关时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/*配置中断源*/
nvic_initstauct.NVIC_IRQChannel = DEBUG_IRQ;
/*配置抢占优先级*/
nvic_initstauct.NVIC_IRQChannelPreemptionPriority = 1;
/*配置响应优先级*/
nvic_initstauct.NVIC_IRQChannelSubPriority = 0;
/*开启中断*/
nvic_initstauct.NVIC_IRQChannelCmd = ENABLE;
// 把配置写入硬件,生效
NVIC_Init(&nvic_initstauct);
}
/**
* @brief DEBUG 串口初始化
* @param 无
* @retval 无
*/
void DEBUG_USART_Init(void)
{
/* 配置 DEBUG 中断配置 */
DEBUG_NVIC_Config();
/*配置 DEBUG 串口模式*/
DEBUG_USART_MODEConfig();
/* 串口 GPIO 配置 */
DEBUG_USART_PinConfig();
/* 串口使能 */
USART_Cmd(DEBUG_USARTX, ENABLE);
}
/**
* @brief DEBUG 串口中断 回调函数
* @param 无
* @retval 无
*/
void DEBUG_IRQHANDLER(void)
{
/* 数据回显 */
if (USART_GetITStatus(DEBUG_USARTX, USART_IT_RXNE) == SET)
{
uint8_t data_temp = USART_ReceiveData(DEBUG_USARTX); //读取数据寄存器,读取后对应的寄存器会被复位
USART_SenByte(DEBUG_USARTX, data_temp);
USART_ClearITPendingBit(DEBUG_USARTX, USART_IT_RXNE); //清除接收标志位
}
}
/***************************************END OF FILE *********************************************************/
5.3 usart_com.h
c
#ifndef __USART_COM_H
#define __USART_COM_H
#include "stm32f10x.h"
#include "stdio.h"
void USART_SenByte(USART_TypeDef* pUSARTx, uint8_t ch);
void USART_SenArray(USART_TypeDef* pUSARTx, uint8_t* array, uint32_t num);
void USART_SenString(USART_TypeDef* pUSARTx, char* str);
#endif /*__USART_COM_H*/
5.4 usart_com.c
c
/**
******************************************************************************
* @file usart_com.c
* @author 作者
* @version v1.0
* @date 2026.6.7
* @brief 重定向c库printf函数到usart端口
******************************************************************************
* @attention
*
* 版权声明
*
******************************************************************************
*/
#include "usart/usart_com.h"
#include "debug/bsp_debug.h"
/**
* @brief 发送一字节函数
* @param pUSARTx:USARTx(X=1,2,3)/UARTx(x=4,5)
* @param ch:要发送的数据
* @note
* @retval 无
*/
void USART_SenByte(USART_TypeDef* pUSARTx, uint8_t ch)
{
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
/*发送一字节数据到pUSARTx*/
USART_SendData(pUSARTx, ch);
/* 等待发送数据寄存器为空 */
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/**
* @brief 发送8位的数组函数
* @param pUSARTx:USARTx(X=1,2,3)/UARTx(x=4,5)
* @param arrary:要发送的数组
* @param num: 数组大小
* @note
* @retval 无
*/
void USART_SenArray(USART_TypeDef* pUSARTx, uint8_t* array, uint32_t num)
{
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
for(uint32_t i = 0; i < num; i++)
{
/*发送一字节数据到pUSARTx*/
USART_SendData(pUSARTx, array[i]);
/* 等待发送数据寄存器为空 */
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
}
/**
* @brief 发送字符串函数
* @param pUSARTx:USARTx(X=1,2,3)/UARTx(x=4,5)
* @param str:要发送的字符串
* @note
* @retval 无
*/
void USART_SenString(USART_TypeDef* pUSARTx, char* str)
{
uint32_t k = 0;
/* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
do
{
/*发送一字节数据到pUSARTx*/
USART_SendData(pUSARTx, *(str + k));
k++;
/* 等待发送数据寄存器为空 */
while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}while(*(str + k) != '\0');
}
/**
* @brief 将一个字符写入到文件中,重定向C库函数printf到串口,重定向后可使用printf函数
* @param ch:要写入的字符
* @param f:指向FILE结构的指针
* @note 无
* @retval 成功,返回该字符
*/
int fputc(int ch, FILE* f)
{
/* 等待发送完成 */
while(USART_GetFlagStatus(DEBUG_USARTX, USART_FLAG_TC) == RESET);
/*发送一字节数据到pUSARTx*/
USART_SendData(DEBUG_USARTX, ch);
/* 等待发送数据寄存器为空 */
while(USART_GetFlagStatus(DEBUG_USARTX, USART_FLAG_TXE) == RESET);
return ch;
}
/***************************************END OF FILE *********************************************************/
6.实验现象
去个人主页找到视频名字是:串口发送与接收