本帖最后由 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); }
然后,主机端打开一个串口终端软件,看看是否会如我们设计显示信息。 实践证明,我们收到了程序中设定的信息,我们的串口应用成功了。
|