STM32学习笔记——之USART2篇
USART2位于APB1总线
学习环境:
STM32芯片:STM32F103VBT6 开发板:万利STM3210B-LK1
USART2引脚 PD5——USART2 TX, PD6——USART2 RX (重定义引脚) 1、USART2与PC通信 (USART2发送)
首先需要对USART2配置,因为在万利板子上的USART2进行了重映射,因此配置跟USART1有区别①开启GPIOD以及AFIO时钟,开启USART2时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //USART2在APB1总线 ②配置USART2的TX(PD5)以及RX(PD6)引脚
先进行定义结构体变量,用来配置相应引脚的速度以及输入输出模式
GPIO_InitTypeDef GPIO_InitStructure; 进行USART2的重映射配置
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); //USART2重映射 配置USART2的RX(PD6)引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOD, &GPIO_InitStructure); 配置USART2的TX(PD5)引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOD, &GPIO_InitStructure);
③配置USART1的波特率、数据位数、停止位、校验以及硬件流控制
首先定义结构体变量
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; //波特率--9600
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数--8位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位—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); ④使能USART1
USART_Cmd(USART1, ENABLE);
通过上面四个步骤的操作,即可完成对USART2的配置。USART2于USART1的配置区别主要在与第①步,因为万利板子的USART2进行了重映射,所以在配置USART2外设时钟时,除了开启GPIOD端口时钟外,还需要开启AFIO复用功能时钟;因为USART2位于APB1总线,因此配置USART2的时钟函数也与配置USART1的时钟函数不同。
(1)利用STM32固件库函数实现USART2向PC发送数据
实现USART1配置后,即可实现串口通信功能,在此下面程序实现了USART1串口发送功能
CPU_INT08U TxBuffer[] = \
TxBuffer[]为USART1准备发送到PC的字符串,此发送程序通过UCOS-II建立任务实现,发送函数使用STM32固件库V2.0中的发送函数实现,任务程序如下 static void TaskUsart2(void* pdata) {
CPU_INT08U TxCounter = 0; pdata = pdata; while(1) {
while(TxCounter < strlen(TxBuffer)) {
USART_SendData(USART2, TxBuffer[TxCounter++]); //串口发送函数,发送数据 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) {} //等待发送寄存器为空 }
TxCounter = 0;
OSTimeDly(OS_TICKS_PER_SEC); //延时实现任务切换 } }
2、USART2与PC串口通信(STM32串口接收,使用中断实现)
USART具有10个中断源,只有一个接口连接到中断控制器(USART的各种中断事件被连接到同一个中断向量),因此在进入中断时需要软件判断发生的是哪个中断。
USART1串口配置前三步如上节所述①②③,接下来配置串口使能中断
④USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收数据寄存器不为空产生中断 ⑤USART_Cmd(USART2, ENABLE); //使能串口USART2 ⑥配置NVIC
void NVIC_Configuration(void) {
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //无抢占式优先级
/* Enable the USART2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级设置为零 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
至此以上几步实现了USART2的串口中断接收配置,接下来在中断函数中写代码实现中断接收,以及将接收成功的字符发送到PC,在PC端利用串口助手进行监视接收是否成功。 程序利用UCOS-II内核实现,使用的UCOS-II版本V2.86,将USART2串口中断函数写在app_vect_v5.c
文件中,根据此C文件中开始部分的定义
因此在app_vect_v5.c文件中编写的USART1中断函数如下
static void BSP_IntHandlerUSART2 (void) //此处名称必须与app_vect_v5.c开头定义部分相同,否则不能实现中断,此处的BSP_IntHandlerUSART2可能为USART2的中断入口 {
CPU_INT08U USART2RXData;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//判断是否产生中断 {
USART_ClearITPendingBit(USART2, USART_FLAG_RXNE);//产生中断,清除中断标志 USART2RXData = USART_ReceiveData(USART2); //接收串口数据 USART_SendData(USART2, USART2RXData); //发送串口数据 } }
配置总结:
? 配置并使能时钟 ①配置USART2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
②配置系统时钟,配置使用到得GPIO口时钟(USART2用到GPIOD口), RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
③因为此处的USART2引脚使用的是重映射的GPIO口,所以需要配置AFIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
? 如果需要使能中断,则需要配置NVIC,如果不需要中断则继续进行下面的配置 ? 配置RX,TX引脚
? 配置串口,配置串口的波特率,数据位,停止位等等,并且初始化串口 ? 使能相应串口中断(如果需要中断) ? 开启相应串口,至此,串口配置完成