一、串口配置
串口设置的一般步骤可以总结为如下几个步骤:
- 串口时钟使能,GPIO 时钟使能
- 串口复位
- GPIO端口模式设置
- 串口参数初始化
- 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
- 使能串口
- 编写中断处理函数
串口时钟使能
(串口是挂载在APB2 下面的外设,所以使能函数为)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
串口复位
(当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作)
void USART_DeInit(USART_TypeDef* USARTx);//串口复位
比如:USART_DeInit(USART1); //复位串口 1
串口参数初始化
使用这个函数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
USART_InitStructure.USART_BaudRate = bound; //波特率设置;
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为 8 位数据格式
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); //初始化串口
数据发送与接收
STM32 库函数操作USART_DR寄存器发送数据的函数是:(写入一个数据)
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
STM32 库函数操作USART_DR寄存器读取串口接收到的数据的函数是:(接受数据)
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
串口状态
读取串口状态的函数是:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
例如我们要判断读寄存器是否非空(RXNE),操作库函数的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
我们要判断发送是否完成(TC),操作库函数的方法是:
USART_GetFlagStatus(USART1, USART_FLAG_TC);
串口使能
USART_Cmd(USART1, ENABLE); //使能串口
开启串口响应中断
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断,接收到数据中断 我们在发送数据结束的时候(TC,发送完成)要产生中断,那么方法是:
USART_ITConfig(USART1,USART_IT_TC,ENABLE);
获取相应中断状态
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
比如我们使能了串口发送完成中断,那么当中断发生了, 我们便可以在中断处理函数中调用这 个函数来判断到底是否是串口发送完成中断,方法是:
USART_GetITStatus(USART1, USART_IT_TC)
二、代码
初始化代码
//初始化 IO 串口 1 //bound:波特率
void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//①串口时钟使能,GPIO时钟使能,复用时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
//②串口复位
USART_DeInit(USART1);
//③GPIO端口模式设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//④串口参数初始化
USART_InitStructure.USART_BaudRate = bound;
//使能USART1,GPIOA时钟 //复位串口 1 //ISART1_TX PA.9
//复用推挽输出 //初始化GPIOA.9
//USART1_RX PA.10 //浮空输入
//初始化GPIOA.10 //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为 8 位
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); //初始化串口
#if EN_USART1_RX //如果使能了接收
//⑤初始化NVIC
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //中断优先级初始化
//⑤开启中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启中断
#endif
//⑥使能串口
USART_Cmd(USART1, ENABLE); //使能串口
}
GPIO外设配置:
中断函数代码
void USART1_IRQHandler(void) //串口1中断服务程序
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
USART_SendData(USART1,Res);
}
}
主函数部分代码
while(1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("rn您发送的消息为:rnrn");
for(t=0;t
{
USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
printf("rnrn");//插入换行
USART_RX_STA=0;
}
}