查看: 3136|回复: 1

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

[复制链接]
  • TA的每日心情
    开心
    2022-11-7 10:36
  • 签到天数: 898 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2020-7-13 09:09:05 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 story_xjj 于 2020-7-13 08:53 编辑

    串口的使用
        在前一个基本输入输出的测试基础上,这次测试一个相对复杂一点的外部设备,串口。
        BRD4183A无线模块和BRD4001A联合使用的时候,串口的使用分为EFR32MG22处理器上的配置和主板虚拟串口的配置两个部分。
    1、基本硬件接口说明
    根据手册中的介绍,BRD4183A模块可以使用虚拟串口和主机通讯。
    2.jpg
    根据BRD4183A模块的接口定义,我们可以确定,VCOM的引出接口包括PA05-TX,PA06-RX,PA00-RTS,PB02-CTS。还有一个重要的东西,就是PA04-VCOM_ENABLE。
        通过BRD4001A主板的原理图可以看到,主板通过一个开关芯片TS3A4751将无线模块输出的VCOM信号和外界隔开了,这个VCOM_ENABLE就是切换开关。根据原理图的定义,高电平使能输出,低电平禁止输出。
    3.png
    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。

    4.png
    收发引脚的配置,根据手册中的描述和例子,需要将对应的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”页。

    5.jpg
    主板配置端口和help显示内容
    6.png
    此时我们敲一下回车,会看到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);
        }

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

    回复

    使用道具 举报

    该用户从未签到

    发表于 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.最后,赞一个,赶紧收藏下。

    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-11-23 13:02 , Processed in 0.128206 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.