STM32 串口发送与接收
接线图
代码配置
根据上一章发送的代码配置,在GPIO配置的基础上需要再配置PA10引脚做RX接收,引脚模式可以选择浮空输入或者上拉输入,在USART配置串口模式里加上RX模式。
配置中断
//配置中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
配置NVIC
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//配置中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
NVIC_Init(&NVIC_InitStructure);
整体函数
void USART_Config(void)
{
//定义结构体变量
GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量
USART_InitTypeDef USART_InitStructure;//定义USART1结构体变量
NVIC_InitTypeDef NVIC_InitStructure;//定义NVIC结构体变量
//开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//开启USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIO A族的时钟
//配置GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//这里选择复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//只需要发送 所以只配置PA9引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速率
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//这里选择上拉输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//只需要发送 所以只配置PA9引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速率
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置USART
USART_InitStructure.USART_BaudRate = 9600;//波特率
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//串口模式 TX发送 RX接受 这里选择发送模式
USART_InitStructure.USART_Parity = USART_Parity_No;//校验位 这里选择无校验
USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长
USART_Init(USART1, &USART_InitStructure);
//配置中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//配置中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
NVIC_Init(&NVIC_InitStructure);
//开启USART
USART_Cmd(USART1, ENABLE);//使能USART1
}
中断函数
uint8_t RX_Data;//定义串口接收数据变量
uint8_t RX_Flag;//定义串口接收标志位变量
//获取串口接收标志位 flag自动清除函数
uint8_t Serial_GetRXFlag(void)
{
if(RX_Flag == 1)//如果标志位为1
{
RX_Flag = 0;
return 1; //则返回1,并且清除标志位
}
return 0;//如果为0 则返回0
}
//获取串口接受的数据
uint8_t Serial_GetRXData(void)
{
return RX_Data;//返回接收的数据
}
//中断函数
void USART1_IRQHandler(void)
{
//判断中断标志位
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
RX_Data = USART_ReceiveData(USART1);//读取数据寄存器,并存放在数据变量里
RX_Flag = 1; //将接收标志位置1
//清除标志位
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
主函数
#include "USART.h"
int main(void)
{
OLED_Init();
USART_Config();
OLED_ShowString(1, 1, "RXData:");
while(1)
{
if(Serial_GetRXFlag() == 1)
{
RX_Data = Serial_GetRXData();
Serial_SendByte(RX_Data);
OLED_ShowHexNum(1, 8, RX_Data, 2);
}
}
}