打印
[RISC-V MCU 应用开发]

【原创】 【RISC-V MCU CH32V103测评】多串口通讯及验证

[复制链接]
3087|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 jinglixixi 于 2020-11-19 21:16 编辑

CH32V103配置有3个串口,适用于需要同时使用多个串口工作的环境,例如用在一个采用串口屏来显示工作界面并绘制数据波形曲线、一个串口用来控制数据记录仪来存储原始数据、一个串口来控制MP3音频播放模块来播报数据或发出语音提示等。
那么这3个串行通讯口都使用哪些引脚呢?
其使用的引脚情况如表1所示:
其中,USART1主要供打印输出之用,其接口电路如图1所示。
  
图1 串口1接口电路

那么我们如何才能在使用器件少的情况下,来完成同时测试3路串口通信的任务呢?
这里介绍的方法是,让2路串口进行收发通信,让另一路串口来输出信息。
具体的任务分配是:
USART1执行老本行,来完成信息输出的工作;而将USART2和USART3组成一个模拟双方收发数据的终端。
那完成这一任务都需要哪些器件呢?
一条杜邦线,一个USB转TTL通信串口模块及导线,具体的连接形式如图2所示。
杜邦线的作用是将USART2的TX连接到USART3的RX,这样就用一条杜邦线连接起了模拟通信的收发双发。
USB转TTL通信串口模块大的作用,则是将USART1的输出信息传输到电脑,并通过串口助手等工具软件来显示信息。
当然了,如果你要想令USART2和USART3的地位平等,那也很容易,无非是再添加一条杜邦线,将空置的2个通讯引脚连接起来便是了!
图2 多串口通信线路连接

那在程序设计上该如何设计呢?
为了便于测试,这里将待发送的信息存入数组中:
u8 TxBuffer[] = "Buffer Send fromUSART2 to USART3 by polling!";
然后通过USARTx_CFG函数对USART2和USART3进行初始化,其内容如下:
void USARTx_CFG(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB1Periph_USART3, ENABLE);     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB , 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;  
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART3 TX-->B.10  RX-->B.11 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);   
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);
USART_Cmd(USART2, ENABLE);
USART_Init(USART3, &USART_InitStructure);
USART_Cmd(USART3, ENABLE);
}

实现多串口通信测试的主程序如下:
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
USART_Printf_Init(115200);
printf("SystemClk:%d\r\n",SystemCoreClock);
printf("USART Polling TEST\r\n");
USARTx_CFG();
while(TxCnt<TxSize)
{
USART_SendData(USART2, TxBuffer[TxCnt++]);
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
while(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);
RxBuffer[RxCnt++] = (USART_ReceiveData(USART3));
}
TransferStatus=Buffercmp(TxBuffer,RxBuffer,TxSize);
if(TransferStatus)
{
printf("send success!\r\n");
printf("TXBuffer: %s \r\n",TxBuffer);
printf("RxBuffer: %s \r\n",RxBuffer);
}
else
{
printf("send fail!\r\n");
printf("TXBuffer: %s \r\n",TxBuffer);
printf("RxBuffer: %s \r\n",RxBuffer);
}
while(1);
}

其中关键的程序段是:
while(TxCnt<TxSize)
{
    USART_SendData(USART2,TxBuffer[TxCnt++]);
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    while(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);
    RxBuffer[RxCnt++] = (USART_ReceiveData(USART3));
}

它通过定义循环的次数,由USART2把信息发送出去,而与此同时又通过USART3将信息接收回来,最终由USART1把接收的信息原样显示出来以供比对判别。
经编译下载后,其运行效果如图3所示,说明多串口通信是正确的。
若感兴趣的话,在此基础上可以拓展出许多有应用价值的功能。
图3 多串口通信测试

使用特权

评论回复
评论
jinglixixi 2020-11-24 16:43 回复TA
@大头哥 :的确是,没有的情况下,这不失为一种方式将3个串口一锅烩了。 
大头哥 2020-11-24 15:53 回复TA
感觉如果有2块板子互联会更直观。。。 

相关帖子

沙发
zeshoufx| | 2020-11-20 08:58 | 只看该作者
谢谢分享【多串口通讯及验证 】

使用特权

评论回复
板凳
jinglixixi|  楼主 | 2020-11-20 10:03 | 只看该作者
zeshoufx 发表于 2020-11-20 08:58
谢谢分享【多串口通讯及验证 】

使用特权

评论回复
地板
koala889| | 2021-6-19 14:32 | 只看该作者
串口,不是各自管理各自的就好了么?

使用特权

评论回复
5
jinglixixi|  楼主 | 2021-6-20 09:07 | 只看该作者
koala889 发表于 2021-6-19 14:32
串口,不是各自管理各自的就好了么?

看你怎么用

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

460

主题

2761

帖子

38

粉丝