STM32 USART串口通信 综合练习
USART(通用同步/异步串行接收/发送器)串口通信具有以下特点:
USART串口通信的参数
USART串口通信的优缺点
优点:
缺点:
tim.c配置
#include "stm32f10x.h"
#include "led.h"void Tim_init(u16 arr,u16 psc){
TIM_TimeBaseInitTypeDef Tim2;
NVIC_InitTypeDef NVIC_Initx;
//1、开启定时器2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //开启TIM2时钟
//2、定时器初始化
Tim2.TIM_Period = arr; //自动装载值 装载值10000-1
Tim2.TIM_CounterMode=TIM_CounterMode_Up; //计数模式 向上计数
Tim2.TIM_ClockDivision=TIM_CKD_DIV1; //时钟分割是输入捕获用的,故这里随便给
Tim2.TIM_Prescaler=psc; //预分频值 7200-1TIM_TimeBaseInit(TIM2,&Tim2);
//3、打开更新中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //此处有中断//4、优先级 有中断就有中断优先级
NVIC_Initx.NVIC_IRQChannel = TIM2_IRQn; //配置目标:中断线0
NVIC_Initx.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initx.NVIC_IRQChannelPreemptionPriority = 1; //设置抢占优先级
NVIC_Initx.NVIC_IRQChannelSubPriority = 2; //设置响应优先级
NVIC_Init(&NVIC_Initx);
//5、启动定时器
TIM_Cmd(TIM2,ENABLE);
}//构建中断服务函数,在.s启动文件中找
void TIM2_IRQHandler()
{
//交替闪烁
//如果B5输出为1 则B5输出为0 E5输出1
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))
{
LED1_ON;
LED2_OFF;
}
else //如果B5输出为0 则B5输出为1 E5输出0
{
LED2_ON;
LED1_OFF;
}
// 否则B5输出为1 E5输出为0
//清除中断标记位 如何已经触发过来,再次使用不清除就一直是触发过后的高电平
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
tim.h配置
#ifndef __TIM_H
#define __TIM_H#include "stm32f10x.h"
void Tim_init(u16 arr,u16 psc);#endif
usart.c配置
#include "stm32f10x.h"
#include "usart.h"void Usart_Init(int bsp)
{
GPIO_InitTypeDef Initx;
NVIC_InitTypeDef NVIC_Initx;
USART_InitTypeDef USART_Initx;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1,ENABLE);//开io时钟
//1、io设置 A9复用推挽和A10浮空 复用
//初始化 A9复用推挽 A10浮空 复用
Initx.GPIO_Mode = GPIO_Mode_AF_PP;
Initx.GPIO_Pin = GPIO_Pin_9;
Initx.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&Initx);//A9复用推挽
Initx.GPIO_Mode = GPIO_Mode_IN_FLOATING;
Initx.GPIO_Pin = GPIO_Pin_10;
Initx.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&Initx);//A10浮空 复用
//2、开串口1时钟
//3、设置串口1的工作方式
USART_Initx.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//输入和输出
USART_Initx.USART_Parity = USART_Parity_No;//无奇偶校验 Even偶校验 Odd奇校验
USART_Initx.USART_StopBits = USART_StopBits_1;//帧结尾传输一个停止位
USART_Initx.USART_WordLength = USART_WordLength_8b;//9位数据位
USART_Initx.USART_BaudRate = bsp;//波特率
USART_Initx.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制
USART_Init(USART1,&USART_Initx);
//4、打开串口的 “接收” 数据中断
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收中断
//5、设置中断优先级
NVIC_Initx.NVIC_IRQChannel = USART1_IRQn;//配置目标USART1 全局中断
NVIC_Initx.NVIC_IRQChannelCmd = ENABLE;
NVIC_Initx.NVIC_IRQChannelPreemptionPriority = 2; //设置抢占优先级
NVIC_Initx.NVIC_IRQChannelSubPriority = 2; //设置响应优先级
NVIC_Init(&NVIC_Initx);
//6、启动串口
USART_Cmd(USART1,ENABLE);
}
void USART1_IRQHandler()
{
u16 data;
if(USART_GetITStatus(USART1,USART_IT_RXNE)) //是接收中断就触发此条件
{
data = USART_ReceiveData(USART1);//读数据
USART_SendData(USART1,data);//把data数据发出去
USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除中断标记位
}//可能有多个原因引起串口中断
//else if(xxx中断)}
usart.h文件配置
#ifndef __USART_H
#define __USART_H#include "stm32f10x.h"
void Usart_Init();#endif
main.c配置
#include "stm32f10x.h"
#include "tim.h"
#include "usart.h"int main()
{
u16 data;
u8 num[6],i = 0;
//中断分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);Tim_init(999,8999);
Usart_Init(115200);
//delay_init();
//编写程序功能
//BEEP_ON;
while(1){;
//读取定时器的当前值
data = TIM_GetCounter(TIM2);
i = 0;
//拆分当前值
while(data)
{
num[++i] = data %10;//把个位放入数组中保存
data = data / 10;//去掉当前数的个位
}
//发送当前值
for(;i>=1;i–)
{
USART_SendData(USART1,num[i]+'0');
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
}
//发完一组数据,换行
USART_SendData(USART1,'\r');
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
USART_SendData(USART1,'\n');
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
}
return 0;
}
运行结果:
总结
USART 是一种功能强大的串行通信接口,广泛应用于各种嵌入式系统和物联网设备中。通过合理配置 USART 参数,可以实现高效、稳定的数据传输。
作者:随便@_@