STM32使用中断方式进行USART数据收发以及printf函数的重写

发布时间:2024年01月05日

时间记录:2024/1/5

一、USART/UART介绍

协议介绍
(1)起始位,一位逻辑电平0表示
(2)数据位,8-9位,逻辑高低电平,一般使用8位
(3)校验位,分为奇校验、偶校验、无校验
(4)停止位,0.5、1、1.5、2个逻辑电平1表示
(5)波特率,数据传输的速度,1S发送接收的比特位数,常用的115200、9600
UART协议图
串口介绍
串口1:
????TX:PA9 RX:PA10
串口2:
????TX:PA2 RX:PA3
串口3:
????TX:PB10 RX:PB11

二、以串口1为例实现数据的收发

(1)使能GPIO时钟,配置GPIO端口

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStruct;
    
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//发送数据端口,复用推挽输出
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//接收数据端口,浮空输入
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);

(2)使能串口时钟,配置串口初始化参数

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    
    USART_InitTypeDef USART_InitStruct;
    
    USART_InitStruct.USART_BaudRate = 115200;//波特率
    USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//模式,收发模式
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;//数据位长度,8位
    USART_InitStruct.USART_Parity = USART_Parity_No;//校验位,无校验位
    USART_InitStruct.USART_StopBits = USART_StopBits_1;//一位停止位
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_Init(USART1,&USART_InitStruct);

(3)设置串口接收中断,使能串口

	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//设置接收中断
    USART_Cmd(USART1,ENABLE);//使能串口

(4)设置中断NVIC,未设置中断分组的话可以先进行设置

    NVIC_InitTypeDef NVIC_InitStruct;
    
    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStruct);

(5)编写中断函数进行数据接收处理,每次接收到1字节数据

void USART1_IRQHandler(void)
{
    uint16_t temp;
    if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){//接收到数据
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);//软件清除中断状态位
        temp=USART_ReceiveData(USART1);//接收1字节数据
    }
}

(6)编写发送数据函数进行数据发送,每次发送1字节数据

	while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)==RESET);//0表示数据还未转移到移位寄存器,1表示数据已经移动到移位寄存器可以发送数据
    USART_SendData(USART1,data);//每次发送1字节数据
    while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);//1表示发送完成

三、重写printf函数进行串口数据的发送

方法1:
(1)引入头文件stdio.h
(2)在串口函数中重写fputc函数

int fputc(int ch,FILE* f)
{
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//0表示数据还未转移到移位寄存器,1表示数据已经移动到移位寄存器可以发送数据
    USART_SendData(USART1,(u8)ch);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);//1表示发送完成
    return 0;
}

(3)设置使用微库,小扳手->Device->将Use MicroLIB前面的多选框勾选上
使用微库
方法2:
(1)与方法1的(1)(2)步骤一致
(2)在串口函数中写入一些必要的定义即可,定义如下

#pragma import(__use_no_semihosting);//不使用半主机模式

//避免使用半主机模式
void _sys_exit(int x)
{
    x=x;
}

//标准库需要支持的函数
struct __FILE
{
    int handle;
};
FILE __stdout;

四、最后看一下实现的一个效果,使用串口调试助手发送任意消息,以\r\n结尾认为接收完毕,进入回调函数发送MYUSARTTEST1217字符到串口调试助手显示
效果展示
STM32代码和串口调试助手软件有需要可私信本人领取

文章来源:https://blog.csdn.net/m0_49156395/article/details/135417929
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。