实验目的
1.使用串口和PC机通信:接收和发送信息
2.接收GNSS模块定位信息
实验准备
- PSoc62™开发板
- CH340 USB转TTL模块
- ATGM332D GNSS模块
- 公母头杜邦线x4
板载资源
板载有多少uart
创建工程例程,在libraries/HAL_Drivers/uart_config.h
中查看BSP支持的uart数量及对应的GPIO,可以看到一共有7组uart
/** Copyright (c) 2006-2023, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2022-07-08 Rbb666 first version*/#ifndef __UART_CONFIG_H__
#define __UART_CONFIG_H__#include <rtthread.h>
#include "board.h"#ifdef __cplusplus
extern "C"
{
#endif#ifdef BSP_USING_UART0/* UART0 device driver structure */cy_stc_sysint_t UART0_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_0_interrupt_IRQn,.intrPriority = (7u),};
#endif
#ifdef BSP_USING_UART1/* UART1 device driver structure */cy_stc_sysint_t UART1_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_1_interrupt_IRQn,.intrPriority = (7u),};
#endif
#ifdef BSP_USING_UART2/* UART2 device driver structure */cy_stc_sysint_t UART2_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_2_interrupt_IRQn,.intrPriority = (7u),};
#endif
#ifdef BSP_USING_UART3/* UART3 device driver structure */cy_stc_sysint_t UART3_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_3_interrupt_IRQn,.intrPriority = (7u),};
#endif
#ifdef BSP_USING_UART4/* UART4 device driver structure */cy_stc_sysint_t UART4_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_4_interrupt_IRQn,.intrPriority = (7u),};
#endif
#ifdef BSP_USING_UART5/* UART5 device driver structure */cy_stc_sysint_t UART5_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_5_interrupt_IRQn,.intrPriority = (7u),};
#endif#ifdef BSP_USING_UART6/* UART6 device driver structure */cy_stc_sysint_t UART6_SCB_IRQ_cfg ={.intrSrc = (IRQn_Type)scb_6_interrupt_IRQn,.intrPriority = (7u),};
#endif
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \{ \.name = "uart0", \.tx_pin = P0_3, \.rx_pin = P0_2, \.usart_x = SCB0, \.intrSrc = scb_0_interrupt_IRQn, \.userIsr = uart_isr_callback(uart0), \.UART_SCB_IRQ_cfg = &UART0_SCB_IRQ_cfg, \}void uart0_isr_callback(void);
#endif /* UART0_CONFIG */
#endif /* BSP_USING_UART0 */#if defined(BSP_USING_UART1)
#ifndef UART1_CONFIG
#define UART1_CONFIG \{ \.name = "uart1", \.tx_pin = P10_1, \.rx_pin = P10_0, \.usart_x = SCB1, \.intrSrc = scb_1_interrupt_IRQn, \.userIsr = uart_isr_callback(uart1), \.UART_SCB_IRQ_cfg = &UART1_SCB_IRQ_cfg, \}void uart1_isr_callback(void);
#endif /* UART1_CONFIG */
#endif /* BSP_USING_UART1 */#if defined(BSP_USING_UART2)
#ifndef UART2_CONFIG
#if defined(SOC_CY8C6244LQI_S4D92)
#define UART2_CONFIG \{ \.name = "uart2", \.tx_pin = P3_1, \.rx_pin = P3_0, \.usart_x = SCB2, \.intrSrc = scb_2_interrupt_IRQn, \.userIsr = uart_isr_callback(uart2), \.UART_SCB_IRQ_cfg = &UART2_SCB_IRQ_cfg, \}
#else
#define UART2_CONFIG \{ \.name = "uart2", \.tx_pin = P9_1, \.rx_pin = P9_0, \.usart_x = SCB2, \.intrSrc = scb_2_interrupt_IRQn, \.userIsr = uart_isr_callback(uart2), \.UART_SCB_IRQ_cfg = &UART2_SCB_IRQ_cfg, \}
#endif /* SOC_CY8C6244LQI_S4D92 */void uart2_isr_callback(void);
#endif /* UART2_CONFIG */
#endif /* BSP_USING_UART2 */#if defined(BSP_USING_UART3)
#ifndef UART3_CONFIG
#define UART3_CONFIG \{ \.name = "uart3", \.tx_pin = P6_1, \.rx_pin = P6_0, \.usart_x = SCB3, \.intrSrc = scb_3_interrupt_IRQn, \.userIsr = uart_isr_callback(uart3), \.UART_SCB_IRQ_cfg = &UART3_SCB_IRQ_cfg, \}void uart3_isr_callback(void);
#endif /* UART3_CONFIG */
#endif /* BSP_USING_UART3 */#if defined(BSP_USING_UART4)
#ifndef UART4_CONFIG
#define UART4_CONFIG \{ \.name = "uart4", \.tx_pin = P7_1, \.rx_pin = P7_0, \.usart_x = SCB4, \.intrSrc = scb_4_interrupt_IRQn, \.userIsr = uart_isr_callback(uart4), \.UART_SCB_IRQ_cfg = &UART4_SCB_IRQ_cfg, \}void uart4_isr_callback(void);
#endif /* UART4_CONFIG */
#endif /* BSP_USING_UART4 */#if defined(BSP_USING_UART5)
#ifndef UART5_CONFIG
#define UART5_CONFIG \{ \.name = "uart5", \.tx_pin = P5_1, \.rx_pin = P5_0, \.usart_x = SCB5, \.intrSrc = scb_5_interrupt_IRQn, \.userIsr = uart_isr_callback(uart5), \.UART_SCB_IRQ_cfg = &UART5_SCB_IRQ_cfg, \}void uart5_isr_callback(void);
#endif /* UART5_CONFIG */
#endif /* BSP_USING_UART5 */#if defined(BSP_USING_UART6)
#ifndef UART6_CONFIG
#define UART6_CONFIG \{ \.name = "uart6", \.tx_pin = P6_5, \.rx_pin = P6_4, \.usart_x = SCB6, \.intrSrc = scb_6_interrupt_IRQn, \.userIsr = uart_isr_callback(uart6), \.UART_SCB_IRQ_cfg = &UART6_SCB_IRQ_cfg, \}void uart6_isr_callback(void);
#endif /* UART6_CONFIG */
#endif /* BSP_USING_UART6 */
#ifdef __cplusplus
}
#endif#endif
uart0-uart6和GPIO对应关系表
uart2是比较特殊的,两组不同的GPIO都可以使用它
分组 | RXD | TXD |
---|---|---|
uart0 | P0.2 | P0.3 |
uart1 | P10.0 | P10.1 |
uart2 | P3.0 / P9.0 | P3.1 / P9.1 |
uart3 | P6.0 | P6.1 |
uart4 | P7.0 | P7.1 |
uart5 | P5.0 | P5.1 |
uart6 | P6.4 | P6.5 |
电路图
串口IO
这里以uart0为例,P0.2
对应MCU_ARD_PWM11
,P0.3
对应MCU_ARD_PWM12
模块连接图
右侧排母从上往下第6、7引脚分别对应uart0 TXD、RXD
状态指示灯
板子有两个自主控制的绿色LED,通过上拉方式接入GPIO,MCU_USER_LED1
对应P0.0,本次实验使用它来指示uart0的数据接收状态
程序设计
和PC机通信
通过CH340 USB转TTL模块连接PC和uart0,实物连接图如下
编码实现
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"#define LED_PIN GET_PIN(0, 1)
#define UART_DEVICE_NAME "uart0"
#define BSP_UART4_RX_BUFSIZE 1024static rt_device_t serial;struct rx_msg
{rt_device_t dev;rt_size_t size;
};static struct rt_messagequeue rx_mq;static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{rt_pin_write(LED_PIN, PIN_LOW);struct rx_msg msg;rt_err_t result;msg.dev = dev;msg.size = size;result = rt_mq_send(&rx_mq, &msg, sizeof(msg));if (result == -RT_EFULL){rt_kprintf("message queue full!\n");}return result;
}static void serial_thread_entry(void *parameter)
{struct rx_msg msg;rt_err_t result;rt_uint32_t rx_length;static char rx_buffer[BSP_UART4_RX_BUFSIZE + 1];while (1){rt_memset(&msg, 0, sizeof(msg));result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
// if (result == RT_EOK){rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);rx_buffer[rx_length] = '\0';rt_device_write(serial, 0, rx_buffer, rx_length);rt_pin_write(LED_PIN, PIN_HIGH);
// rt_kprintf("%s\n",rx_buffer);}}
}static int uart0_setup(int argc, char *argv[])
{rt_err_t ret = RT_EOK;char uart_name[RT_NAME_MAX];static char msg_pool[256];char str[] = "uart0 setup successfully!\r\n";if (argc == 2){rt_strncpy(uart_name, argv[1], RT_NAME_MAX);}else{rt_strncpy(uart_name, UART_DEVICE_NAME, RT_NAME_MAX);}serial = rt_device_find(uart_name);if (!serial){rt_kprintf("find %s failed!\n", uart_name);return RT_ERROR;}struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;config.baud_rate = BAUD_RATE_9600;config.data_bits = DATA_BITS_8;config.stop_bits = STOP_BITS_1;config.bufsz = 1024;config.parity = PARITY_NONE;rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);rt_mq_init(&rx_mq, "rx_mq", msg_pool, sizeof(struct rx_msg), sizeof(msg_pool), RT_IPC_FLAG_FIFO);rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);rt_device_set_rx_indicate(serial, uart_input);rt_device_write(serial, 0, str, (sizeof(str) - 1));rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);if (thread != RT_NULL){rt_thread_startup(thread);}else{ret = RT_ERROR;}return ret;
}MSH_CMD_EXPORT(uart0_setup, uart0 setup example);int main(void)
{rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);while (1){rt_thread_mdelay(500);}
}
打开串口调试工具,打开对应的COM口,串口设置和上面的代码保持一致:波特率115200、数据位8位、停止位为1位、奇偶校验位为无
在RT-Thread Studio初始化uart0,使用msh终端输入uart0_setup命令
初始化成功,可以在串口调试工具看到以下信息
自定义串口消息,点击发送
按钮,可以看到发出去的消息被开发板转发了回来,而LED也随即闪了一下
接收GPS模块定位数据
通过uart0连接ATGM332D GNSS模块,实物连接图如下
编码实现uart0串口通信,注意GNSS模块的波特率默认为9600,其它跟上面的example保持一致
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"#define LED_PIN GET_PIN(0, 1)
#define UART_DEVICE_NAME "uart0"
#define BSP_UART4_RX_BUFSIZE 1024static rt_device_t serial;struct rx_msg
{rt_device_t dev;rt_size_t size;
};static struct rt_messagequeue rx_mq;static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{rt_pin_write(LED_PIN, PIN_LOW);struct rx_msg msg;rt_err_t result;msg.dev = dev;msg.size = size;result = rt_mq_send(&rx_mq, &msg, sizeof(msg));if (result == -RT_EFULL){rt_kprintf("message queue full!\n");}return result;
}static void serial_thread_entry(void *parameter)
{struct rx_msg msg;rt_err_t result;rt_uint32_t rx_length;static char rx_buffer[BSP_UART4_RX_BUFSIZE + 1];while (1){rt_memset(&msg, 0, sizeof(msg));result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
// if (result == RT_EOK){rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);rx_buffer[rx_length] = '\0';rt_device_write(serial, 0, rx_buffer, rx_length);rt_pin_write(LED_PIN, PIN_HIGH);rt_kprintf("%s\n",rx_buffer);}}
}static int uart0_setup(int argc, char *argv[])
{rt_err_t ret = RT_EOK;char uart_name[RT_NAME_MAX];static char msg_pool[256];char str[] = "uart0 setup successfully!\r\n";if (argc == 2){rt_strncpy(uart_name, argv[1], RT_NAME_MAX);}else{rt_strncpy(uart_name, UART_DEVICE_NAME, RT_NAME_MAX);}serial = rt_device_find(uart_name);if (!serial){rt_kprintf("find %s failed!\n", uart_name);return RT_ERROR;}struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;config.baud_rate = BAUD_RATE_9600;config.data_bits = DATA_BITS_8;config.stop_bits = STOP_BITS_1;config.bufsz = 1024;config.parity = PARITY_NONE;rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);rt_mq_init(&rx_mq, "rx_mq", msg_pool, sizeof(struct rx_msg), sizeof(msg_pool), RT_IPC_FLAG_FIFO);rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);rt_device_set_rx_indicate(serial, uart_input);rt_device_write(serial, 0, str, (sizeof(str) - 1));rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);if (thread != RT_NULL){rt_thread_startup(thread);}else{ret = RT_ERROR;}return ret;
}MSH_CMD_EXPORT(uart0_setup, uart0 setup example);int main(void)
{rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);while (1){rt_thread_mdelay(500);}
}
在msh终端输入uart0_setup后GNSS数据读取结果如下
运行效果如下,可以看到GNSS报文以1Hz的频率打印,LED灯在不停地闪烁
PSoc62™开发板之串口通信