1回答

1收藏

[评测分享] 【Silicon Labs EFR32xG22】串口的使用

#板卡评测 #板卡评测 4735 人阅读 | 1 人回复 | 2020-07-13

本帖最后由 story_xjj 于 2020-7-13 08:53 编辑

串口的使用
    在前一个基本输入输出的测试基础上,这次测试一个相对复杂一点的外部设备,串口。
    BRD4183A无线模块和BRD4001A联合使用的时候,串口的使用分为EFR32MG22处理器上的配置和主板虚拟串口的配置两个部分。
1、基本硬件接口说明
根据手册中的介绍,BRD4183A模块可以使用虚拟串口和主机通讯。
根据BRD4183A模块的接口定义,我们可以确定,VCOM的引出接口包括PA05-TX,PA06-RX,PA00-RTS,PB02-CTS。还有一个重要的东西,就是PA04-VCOM_ENABLE。
    通过BRD4001A主板的原理图可以看到,主板通过一个开关芯片TS3A4751将无线模块输出的VCOM信号和外界隔开了,这个VCOM_ENABLE就是切换开关。根据原理图的定义,高电平使能输出,低电平禁止输出。
2、程序设计和初始化
根据硬件连接关系说明,为了简化测试过程,我这里不开启硬件流控制功能,也就是RTS和CTS两个引脚就不用了。这里以USART0为例测试。
1)使能GPIO时钟
    //开启GPIO时钟使能
    CMU_ClockEnable(cmuClock_GPIO, true);
2)使能USART0时钟
    //开启USART0时钟使能
    CMU_ClockEnable(cmuClock_USART0,true);

3)配置引脚
这里需要多说两句,根据手册的描述,USART0的收发两个引脚可以使用芯片的所有引出引脚,芯片内部有个矩阵,可以将引脚和外设输出输入连接在一起。必须要说,这个芯片的设计相当牛。但是根据硬件连接关系,我们只能使用PA04,PA05和PA06。

收发引脚的配置,根据手册中的描述和例子,需要将对应的TX配置为推挽输出模式,RX配置为输入模式。
//  配置引脚
    GPIO_PinModeSet(PORTIO_USART0_TX_PORT,PORTIO_USART0_TX_PIN,gpioModePushPull,true);
    GPIO_PinModeSet(PORTIO_USART0_RX_PORT,PORTIO_USART0_RX_PIN,gpioModeInput,true);
重要的地方,必须敲黑板说3便,我在这个地方卡了一天,由于硬件设计非常灵活,所以USART0的收发两个引脚必须路由到指定的GPIO引脚上去,而且要注意,光是路由过去还不行,还必须要使能相应的引脚功能。重点重点重点。
//  引脚路由
    GPIO->USARTROUTE_SET[USART_NUM(USART0)].RXROUTE =
           (PORTIO_USART0_RX_PORT<<_GPIO_USART_RXROUTE_PORT_SHIFT) |
           (PORTIO_USART0_RX_PIN <<_GPIO_USART_RXROUTE_PIN_SHIFT);

    GPIO->USARTROUTE_SET[USART_NUM(USART0)].TXROUTE =
           (PORTIO_USART0_TX_PORT<<_GPIO_USART_TXROUTE_PORT_SHIFT) |
           (PORTIO_USART0_TX_PIN <<_GPIO_USART_TXROUTE_PIN_SHIFT);
//  引脚使能
    GPIO->USARTROUTE_SET[USART_NUM(USART0)].ROUTEEN =(GPIO_USART_ROUTEEN_RXPEN | GPIO_USART_ROUTEEN_TXPEN);

4)配置串口
系统中的外设库已经集成了usart的串口库函数,这个还是相当方便的,我们直接调用接口函数就可以完成串口的初始化。
       //配置USART0
       USART_InitAsync(USART0,&usart0_conf);
USART_Enable(USART0,usartEnable);
这里需要提一下,初始化串口的时候,需要带一个配置参数进去,就是下面的定义usart0_conf,后面这个USART_INITASYNC_DEFAULT非常的好,它直接将串口的配置参数初始化为默认值。
USART_InitAsync_TypeDef usart0_conf = USART_INITASYNC_DEFAULT;
这个默认值定义我们看一下。
#defineUSART_INITASYNC_DEFAULT     \
{      \
    usartEnable,           /*Enable RX/TX when initialization is complete. */  \
    0,                     /* Usecurrent configured reference clock for configuring baud rate. */ \
    115200,                /*115200 bits/s. */  \
    usartOVS16,            /* 16xoversampling. */  \
    usartDatabits8,        /* 8data bits. */ \
    usartNoParity,         /* Noparity. */ \
    usartStopbits1,        /* 1stop bit. */\
    false,                 /* Donot disable majority vote. */ \
    false,                 /* NotUSART PRS input mode. */  \
    0,                     /* PRSchannel 0. */                \
    false,                 /*Auto CS functionality enable/disable switch */ \
    0,                     /*Auto CS Hold cycles */           \
    0,                     /*Auto CS Setup cycles */          \
usartHwFlowControlNone/* No HW flow control */        \
}
       这个定义中帮我们设置好了串口波特率,数据位,停止位,校验位等相关信息,相当实用。
5)支持printf打印功能
GCC方式的print重定向设置网络上内容挺多,下面的代码亲测可以实用。
#ifdef__GNUC__
#definePUTCHAR_PROTOTYPE int__io_putchar(int ch)
PUTCHAR_PROTOTYPE{
    USART_Tx(USART0, ch);
    return ch;
}
int _write(intfile, char *ptr, int len){
    intDataIdx;
    for(DataIdx = 0; DataIdx < len; DataIdx++)
    {
       __io_putchar(*ptr++);
    }
    return len;
}

#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
PUTCHAR_PROTOTYPE
{
    HAL_UART_Transmit(&huart1,(uint8_t *)&ch, 1, 0xFFFF);
    return ch;

}
#endif

接入如上代码后,我们只要引入头文件stdio.h后,printf我们就可以随便用了。

3、主板配置
无线模块配置完成后,实际上还是不能正常输出到主机,因为中间还有个主板通过JTAG虚拟串口的桥接转换环节,还必须要设置这个部分才可以和主机通讯。
首先,进入主板配置界面,如下图所示选中“LaunchConsole”,选中“Admin”页。

主板配置端口和help显示内容
此时我们敲一下回车,会看到WSTK>的提示符出来,输入help后回车,既可以看到上面的提示。
我们需要通过这个管理接口设置串口的波特率和流控制功能。控制命令及回显:
    WSTK>WSTK> serial vcom config handshake disable speed 115200
Baudrate set to 115200 bps
Actual baud rate: 115226 Hz
RTS handshake disabled
CTS handshake disabled
Serial configuration saved
    这表示我们设置成功了,这个的设置尤其是波特率和流控制必须和我们在单片上的相同,要不然就无法完成通讯。
4、实际测试
一切准备工作完成后,我们可以开始实践一下了。
主程序调整为
    printf("helloworld!\n\r");
    /* Infinite loop */
    while (1){
       printf("count= %d \n\r",count++);
       delay(100000);
    }

然后,主机端打开一个串口终端软件,看看是否会如我们设计显示信息。
实践证明,我们收到了程序中设定的信息,我们的串口应用成功了。

分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

eefocus_3731187

发表于 2021-4-26 10:16:38 | 只看该作者

Hi Story_xjj
首先声明下,为回你的贴子还专门注册了个账号,就跟看上一个手机壳专门买了个手机一样。

其次,楼主的贴子我亲自测试了,正常,printf正常了。IC:EFR32FG1V131FG256GM48 SDK:2.3.1

有如下几点说明:

1.printf的重定向是由于函数的WEAK功能才可以实现的,感觉添加的那一段GUNC那段宏定义的代码应该是跟函数的弱化有关的。

2.之前按网上的说法添加了retargetio.c,retargetserial.c等函数后,编译老是缺少头文件,你加一个头文件还会报别的,反正加了一堆还是报警缺少头文件。

3.我们的开发没有按照EVK的硬件原理图绘制,而是对GPIO进行了部分变更所以导致之前的printf不能使用了,所以才会出现这个问题。

4.最后,赞一个,赶紧收藏下。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条