STM32使用中断方式进行USART数据收发以及printf函数的重写
2024-01-08 22:32:46
时间记录:2024/1/5
一、USART/UART介绍
协议介绍
(1)起始位,一位逻辑电平0表示
(2)数据位,8-9位,逻辑高低电平,一般使用8位
(3)校验位,分为奇校验、偶校验、无校验
(4)停止位,0.5、1、1.5、2个逻辑电平1表示
(5)波特率,数据传输的速度,1S发送接收的比特位数,常用的115200、9600
串口介绍
串口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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!