【STM32学习笔记】6、USART

发布于 2021-01-30  63 次阅读


在之前我们用到过串口去传输一些数据,比如利用串口返回按下的按钮的键值等。但是当时都只是直接调用写好的USART库函数,并没有深入的了解其中的原理。这次的任务就是自行编写串口的初始化函数,并利用串口控制开发板上的LED开关和在OLED屏幕上显示输入的x*50+100的结果。

首先删掉模板中的已经写好的usart.h、usart.c,然后开始自己编写。首先我们自己定义一个RX和TX,这里就要用到已经很熟悉的GPIO的设置,代码如下:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟

//PA9  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//设置PA9为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);

//PA10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//设置PA10为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_InitStructure);

将PA9接上串口模块的RXD,将PA10接上模块的TXD,然后就来到我们的USART串口的配置部分:

USART_InitTypeDef USART_InitStructure;//定义USART结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能时钟

USART_InitStructure.USART_BaudRate =9600;//定义波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//定义工作的发送的数据字节数为8bit
USART_InitStructure.USART_StopBits = USART_StopBits_1;//设置停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//关闭奇偶验证
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//关闭硬件控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//配置串口双工
USART_Init(USART1,&USART_InitStructure);//初始化串口

USART_Cmd(USART1,ENABLE);//使能串口1

到这一步我们就已经配置好我们的串口了,但是工作还没完成,我们还需要配置NVIC开启中断。

NVIC_InitTypeDef NVIC_InitStructure;//定义一个NVIC结构体

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//定义NVIC频道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;//指定抢占优先级为3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//启用IRQ通道
NVIC_Init(&NVIC_InitStructure);

//打开串口1的接收中断,当串口1接收到数据时会触发此中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

//单独编写中断服务函数
void USART1_IRQHandler(void){
	u8 res;
	if(USART_GetFlagStatus(USART1,USART_IT_RXNE)){//如果串口1接收数据中断
		res = USART_ReceiveData(USART1);//读取串口1接收到的数据
		USART_SendData(USART1,res);//通过串口1回发接收到的数据
	}
}

最后我们把上面这些代码稍微整理一下:

以上的代码实现了通过串口输入并返回接收到的文本信息,以及通过输入“led”来控制开发板上LED的开关。

接着我们要实现的功能是在OLED屏幕上显示输入的x*50+100的结果。现在我们重新调用以及编写好的库函数,我们可以在usart.c中找到相关的USART_Init的函数定义,与我们上面的程序并没有太多的不同,只是在定义波特率的时候,应用了形参,让用户可以调用函数初始化USART的时候直接定义波特率,不需要修改代码。

由于数据类型转换起来很麻烦,我打算直接用OLED_ShowNum函数去显示结果,具体代码如下。

效果如下: