本帖最后由 l爱学习 于 2023-3-17 13:37 编辑
串口作为MCU必备外设,是进行数据传输的重要手段之一。CH32V307系列MCU一共具有8个串口,包含 3 个通用同步异步收发器(USART1/2/3)和 5 个通用异步收发器(UART4/5/6/7/8),支持全双工或半双工的同步或异步通信,波特率最高可配置为9Mbps,支持DMA和多种中断源。本文主要介绍CH32V307 USART2的中断接收和发送,配合缓冲区,可有效提高数据传输的效率和准确性。
程序配置如下:
一、USART2接收中断整体初始化配置
1、对USART2的GPIO引脚进行初始化配置
- GPIO_InitTypeDef GPIO_InitStructure={0};
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- /* USART2 TX-->A.2 RX-->A.3 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置PA2为复用推挽输出
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOAtiNG; //设置PA3为浮空输入
- GPIO_Init(GPIOA, &GPIO_InitStructure);
USART2对应的默认的GPIO引脚为PA2和PA3引脚,其中PA2为Tx引脚,配置为复用推挽输出模式,PA3为RX引脚,配置为浮空输入模式。
2、对USART2进行初始化配置
- USART_InitTypeDef USART_InitStructure={0};
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
- USART_InitStructure.USART_BaudRate = 115200;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- 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_Tx | USART_Mode_Rx;
- USART_Init(USART2, &USART_InitStructure);
USART2的初始化配置主要对串口的主要参数进行配置,具体如下:
波特率:最大可配置为9Mbps,一般配置为115200
数据位:可配置为8位或9位,一般配置为8位,进行奇偶校验时需要配置成9位
停止位:可配置成1个停止位、0.5个停止位、2个停止位、1.5个停止位,一般配置为1个停止位
校验位:可配置成奇校验、偶校验、无奇偶校验,一般无需进行奇偶校验
硬件流控制:可配置成无硬件流控制、CTS流控、RTS流控、CTS和RTS流控,一般配置为无硬件流控制
串口模式:可配置成发送模式、接收模式,此处配置为发送和接收模式
3、USART2中断接收使能配置
- NVIC_InitTypeDef NVIC_InitStructure={0};
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级为1
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级为1
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
- NVIC_Init(&NVIC_InitStructure); //中断优先级初始化
USART2的中断接收使能配置主要配置中断的优先级
4、最后要注意使能USART2接收中断以及USART2
- USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
- USART_Cmd(USART2,ENABLE);
以上就是USART2中断接收的整体的初始化配置,注意要使能开启GPIOA以及USART2的时钟,要注意使能开启中断接收。
二、USART2发送字节函数配置,具体程序如下:
- void USARTx_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
- {
- USART_SendData(pUSARTx, data);
- while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
- }
三、USART2发送字符串函数配置,具体程序如下:
- void USARTx_SendStr(USART_TypeDef* pUSARTx, char *str)
- {
- uint8_t i = 0;
- do
- {
- USARTx_SendByte(pUSARTx, *(str+i));
- i++;
- }while(*(str+i) != '\0');
- while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET);
- }
四、USART2中断函数配置,具体程序如下:
- u8 USART_Rbuffer_Num = 0;
- u8 USART_Tbuffer_Num = 0;
- u8 USART_Rbuffer[buffer_len];//接收缓冲区数组
- void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
- void USART2_IRQHandler(void)
- {
- if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //中断产生
- {
- USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志
- USART_Rbuffer[USART_Rbuffer_Num] = USART_ReceiveData(USART2); //接收数据
- USART_Rbuffer_Num++;
- }
- for(USART_Tbuffer_Num=0;USART_Tbuffer_Num < USART_Rbuffer_Num;USART_Tbuffer_Num++)
- {
- USARTx_SendByte(USART2,USART_Rbuffer[USART_Tbuffer_Num]); //发送数据
- }
- USART_Rbuffer_Num = 0; //初始化
- USART_Tbuffer_Num = 0;
- }
此处要注意加中断声明,关于中断声明,其用于保证中断执行完成之后程序正常运行。若不添加此函数,中断执行完成之后,中断执行之前保存的信息将不会被返回,中断会被认为一个正常程序继续执行下去,但中断之后并没有程序,从而导致程序出现类似跑飞状况。添加此函数,中断执行完成之后,中断执行之前保存的信息将会被返回,从而程序可以继续正常执行,如图所示。
此外还需要注意,每次进入中断后要注意清除对应的中断标志位,否则可能会有问题。以上就是USART2中断接收的一个整体流程,将程序下载到
开发板,进行串口收发,结果如下: