[单片机芯片] CH32V003配置USART实现接收上位机发送过来的数据并回显

[复制链接]
5354|7
 楼主| lilijin1995 发表于 2022-10-23 11:47 | 显示全部楼层 |阅读模式
本帖最后由 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。
1966993-20221015152112367-79777915.png
3.3.2 软件设计:
本节的代码设计,我们直接在MRS(MounRiver Studio)建立的工程目录Debug下面的debug.c,debug.h上修改。这里我们对代码部分稍作讲解。打开串口实验工程,我们就可以看到上述两个文件里面的代码,先介绍 USART_Printf_Init函数,该函数代码如下:
  1. /*********************************************************************
  2. * @fn      USART_Printf_Init
  3. *
  4. * [url=home.php?mod=space&uid=247401]@brief[/url]   Initializes the USARTx peripheral.
  5. *
  6. * @param   baudrate - USART communication baud rate.
  7. *
  8. * [url=home.php?mod=space&uid=266161]@return[/url]  None
  9. */
  10. void USART_Printf_Init(uint32_t baudrate) {
  11.     GPIO_InitTypeDef GPIO_InitStructure = { 0 };
  12.     USART_InitTypeDef USART_InitStructure = { 0 };
  13.     NVIC_InitTypeDef NVIC_InitStructure = { 0 };

  14.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1,
  15.             ENABLE);

  16.     /* USART1 TX-->D.5   RX-->D.6 */
  17.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  18.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  19.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  20.     GPIO_Init(GPIOD, &GPIO_InitStructure);
  21.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  22.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  23.     GPIO_Init(GPIOD, &GPIO_InitStructure);

  24.     USART_InitStructure.USART_BaudRate = baudrate;
  25.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  26.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
  27.     USART_InitStructure.USART_Parity = USART_Parity_No;
  28.     USART_InitStructure.USART_HardwareFlowControl =
  29.             USART_HardwareFlowControl_None;
  30.     USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

  31.     USART_Init(USART1, &USART_InitStructure);
  32.     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

  33.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  34.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  35.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  36.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  37.     NVIC_Init(&NVIC_InitStructure);
  38.     ;

  39.     USART_Cmd(USART1, ENABLE);
  40. }

从该代码可以看出,其初始化串口的过程,总结出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

  1. void USART1_IRQHandler(void) {
  2.     u8 Res;
  3.     if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
  4.         Res = USART_ReceiveData(USART1);
  5.         if ((USART_RX_STA & 0x8000) == 0)       //接收未完成
  6.                 {
  7.             if (USART_RX_STA & 0x4000)       //接收到了0x0d
  8.                     {
  9.                 if (Res != 0x0a)
  10.                     USART_RX_STA = 0;       //接收错误,重新开始
  11.                 else
  12.                     USART_RX_STA |= 0x8000;  //接收完成了
  13.             } else //还没收到0X0D
  14.             {
  15.                 if (Res == 0x0d)
  16.                     USART_RX_STA |= 0x4000;
  17.                 else {
  18.                     USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
  19.                     USART_RX_STA++;
  20.                     if (USART_RX_STA > (USART_REC_LEN - 1))
  21.                         USART_RX_STA = 0; //接收数据错误,重新开始接收
  22.                 }
  23.             }
  24.         }
  25.     }
  26. }

大家对上面代码一定很熟悉,没错这就是正点原子STM32的串口接收代码,这里大家可以去支持正版学习一下;
3.3.3 下载验证:
打开串口调试助手可以看到,“请输入数据,以回车键结束”提示发送数据,勾选发送新行后,发送数据直接回显;
image-20221022224532898.png
file:///C:/Users/Administrator/AppData/Roaming/Typora/typora-user-images/image-20221022224532898.png?lastModify=1666496354

3.3.4 学习视频:



tpgf 发表于 2022-11-8 11:46 | 显示全部楼层
是通过什么方式把接收到的数据显示出来的呢
guanjiaer 发表于 2022-11-8 12:06 | 显示全部楼层
串口发送数据的速度和pcb布线有直接的联系吗
heimaojingzhang 发表于 2022-11-8 12:13 | 显示全部楼层
一般串口的最高传输速度是不是就115200了呢
keaibukelian 发表于 2022-11-8 13:06 | 显示全部楼层
楼主总结出来的初始化串口的过程的6个步骤,可以进行顺序的调换吗
paotangsan 发表于 2022-11-8 13:19 | 显示全部楼层
总中断和串口中断的使能顺序有具体的要求吗
renzheshengui 发表于 2022-11-8 13:29 | 显示全部楼层
感觉中断服务里边的代码太多了 这样的话会不会造成丢失数据呢
 楼主| lilijin1995 发表于 2022-11-9 11:22 | 显示全部楼层
renzheshengui 发表于 2022-11-8 13:29
感觉中断服务里边的代码太多了 这样的话会不会造成丢失数据呢

都是ifelse,真正执行的没几句,这是参考正点原子的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

165

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部