本帖最后由 lilijin1995 于 2022-10-23 11:56 编辑
#申请原创#
@21小跑堂
3.3 Eg3_USART前面几节介绍了 CH32V003的 IO 口操作。这一节我们将学习 CH32V003的串口,教大家如何使用 CH32V003的串口来发送和接收数据。本章将实现如下功能:CH32V003通过串口和上位机的对话,CH32V003在收到上位机发过来的字符串后,原原本本的返回给上位机。 串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。现在基本上所有的 MCU 都会带有串口,CH32V003自然也不例外。 3.3.1硬件设计:硬件过于简单,这里展示一下原理图,USART1 TX-->D.5 RX-->D.6。 3.3.2 软件设计:本节的代码设计,我们直接在MRS(MounRiver Studio)建立的工程目录Debug下面的debug.c,debug.h上修改。这里我们对代码部分稍作讲解。打开串口实验工程,我们就可以看到上述两个文件里面的代码,先介绍 USART_Printf_Init函数,该函数代码如下: - /*********************************************************************
- * @fn USART_Printf_Init
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Initializes the USARTx peripheral.
- *
- * @param baudrate - USART communication baud rate.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] None
- */
- void USART_Printf_Init(uint32_t baudrate) {
- GPIO_InitTypeDef GPIO_InitStructure = { 0 };
- USART_InitTypeDef USART_InitStructure = { 0 };
- NVIC_InitTypeDef NVIC_InitStructure = { 0 };
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1,
- ENABLE);
-
- /* USART1 TX-->D.5 RX-->D.6 */
- 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);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
-
- USART_InitStructure.USART_BaudRate = baudrate;
- 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(USART1, &USART_InitStructure);
- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
-
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- ;
-
- USART_Cmd(USART1, ENABLE);
- }
从该代码可以看出,其初始化串口的过程,总结出6个步骤。我们用标号①~⑥标示了顺序:① 串口时钟使能,GPIO 时钟使能② 串口复位③ GPIO 端口模式设置④ 串口参数初始化⑤ 初始化 NVIC 并且开启中断⑥ 使能串口这里需要重申的是,对于复用功能下的 GPIO 模式怎么判定,这个需要查看《CH32V003RM》P54 的表格“表 7-3 通用同步异步串行收发器(USART)”,这里还是拿出来再讲解一下吧。查看手册得知,配置全双工的串口 1,那么 TX(PA9)管脚需要配置为推挽复用输出,RX(PA10)管脚配置为浮空输入或者带上拉输入。模式配置参考下面表格: file:///C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221022222712218.png?lastModify=1666496354 接下来,还要编写中断服务函数。串口 1 的中断服务函数USART1_IRQHandler
- void USART1_IRQHandler(void) {
- u8 Res;
- if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
- Res = USART_ReceiveData(USART1);
- if ((USART_RX_STA & 0x8000) == 0) //接收未完成
- {
- if (USART_RX_STA & 0x4000) //接收到了0x0d
- {
- if (Res != 0x0a)
- USART_RX_STA = 0; //接收错误,重新开始
- else
- USART_RX_STA |= 0x8000; //接收完成了
- } else //还没收到0X0D
- {
- if (Res == 0x0d)
- USART_RX_STA |= 0x4000;
- else {
- USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
- USART_RX_STA++;
- if (USART_RX_STA > (USART_REC_LEN - 1))
- USART_RX_STA = 0; //接收数据错误,重新开始接收
- }
- }
- }
- }
- }
大家对上面代码一定很熟悉,没错这就是正点原子STM32的串口接收代码,这里大家可以去支持正版学习一下; 3.3.3 下载验证:打开串口调试助手可以看到,“请输入数据,以回车键结束”提示发送数据,勾选发送新行后,发送数据直接回显; file:///C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221022224532898.png?lastModify=1666496354
3.3.4 学习视频:
|