串口数据存储开发板
背景与目标
在嵌入式系统开发中,串口通信是一种常见且重要的功能,它用于实现设备之间的异步串行数据传输,广泛应用于各种场景,如设备调试、数据采集和传输等,本文将详细介绍一个基于串口数据存储的开发板的设计与实现过程,包括硬件配置、软件开发以及测试步骤。
硬件设计
开发板简介
本开发板选用的是庐山派K230开发板,它具有多个UART接口,开发板上有三个UART接口:UART0、UART2和UART3,UART0默认被系统大核RT-Smart占用,用于调试,我们在运行CanMV固件烧录时,只能使用UART2和UART3。
UART接口配置
UART2: TXD为BANK0_GPIO11, RXD为BANK0_GPIO12
UART3: TXD为BANK4_GPIO50, RXD为BANK4_GPIO51
为了确保串口通信的稳定性和性能,我们进行了以下测试步骤:
1、初始化UART端口: 配置BANK0_GPIO11和BANK0_GPIO12为UART2的TXD和RXD,配置BANK4_GPIO50和BANK4_GPIO51为UART3的TXD和RXD,设置波特率、数据位、停止位和校验位等参数。
2、发送和接收数据: 使用串口调试助手软件连接至开发板的UART2和UART3,发送测试字符串或命令至开发板,并验证是否能够正确接收,在开发板上编写简单的串口收发程序,测试双向通信。
3、稳定性测试: 持续发送大量数据,观察是否存在丢包现象,在不同环境下(如电磁干扰较强的地方)测试UART通信的稳定性。
4、性能测试: 测量最大可接受的波特率,以测试数据传输速度,检查在高速传输时的错误率,如帧错误、溢出错误等。
软件开发
串口初始化
我们需要初始化串口,包括设置波特率、数据位、停止位等参数,以下是一个简单的初始化串口函数示例:
void uart_init(void) { // 使能时钟 rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_USART0); // Tx PA9 复用推挽输出 gpio_mode_set(GPIOA, GPIO_MODE_AF_PP, GPIO_PUPD_PULLUP, GPIO_PIN_9); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); // Rx PA10 gpio_mode_set(GPIOA, GPIO_MODE_AF_PP, GPIO_PUPD_PULLUP, GPIO_PIN_10); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); nvic_irq_enable(USART0_IRQn, 0, 0); gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9 | GPIO_PIN_10); /* USART 设置 */ usart_deinit(USART0); usart_baudrate_set(USART0, 115200); usart_word_length_set(USART0, USART_WL_8BIT); usart_stop_bit_set(USART0, USART_STB_1BIT); usart_parity_config(USART0, USART_PM_NONE); usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); usart_enable(USART0); usart_interrupt_enable(USART0, USART_INT_RBNE); usart_interrupt_enable(USART0, USART_INT_IDLE); /* 使能USART0空闲中断 */ }
发送数据
发送数据时,将要发送的数据写入到串口数据寄存器中,直到发送完所有数据为止,以下是一个简单的发送数据函数示例:
void send_data(const char* data) { while (*data) { usart_data_transmit(USART0, *data++); while (usart_flag_get(USART0, USART_FLAG_TCF)); // 等待发送完成 } }
接收数据
接收数据时,从串口数据寄存器中读取接收到的数据,直到读取完所有数据为止,以下是一个简单的接收数据函数示例:
void receive_data() { char received = usart_data_receive(USART0); if (received != -1) { printf("Received: %c ", received); } }
中断处理
在嵌入式系统中,通常会使用中断来处理串口接收和发送,以下是一个简单的中断处理函数示例:
void USART0_IRQHandler(void) { if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { gd_led_toggle(); uint16_t t = usart_data_receive(USART0); // 接收数据 usart_data_transmit(USART0, t); // 回传数据 usart_interrupt_disable(USART0, USART_INT_RBNE); } else if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) { usart_interrupt_disable(USART0, USART_INT_FLAG_IDLE); } }
数据处理API
为了方便处理接收到的数据,我们可以设计一个轻量级的API,以下是一个示例代码:
struct _ChangNum { char* Source; char Sign[8]; float NUM[8]; char flag; }; char Data_ChangNum(struct _ChangNum* Item) { char DataArray[12] = {0}; // 数字的str数 char str[36]; // 装source数据到这个缓存区,这个缓存区是要变的 char Data; char n, m = 0; char i, flag = 1; // i是当前找的是第几个Sign char FindTime = strlen(Item->Sign); // 要找多少个 char Length = strlen(Item->Source); // 源的长度 strcpy(str, Item->Source); if (Length > 36) Length = 36; for (i = 0; i < FindTime; i++) { flag = 0; for (n = 0; n < Length; n++) { Data = str[n]; if (str[n] == Item->Sign[i]) { // 找到标志 str[n] = 0; flag = 1; // 开始识别str m = 0; } if (flag) { if ((str[n] <= '9' && str[n] >= '0') || str[n] == '.' || str[n] == '-') { DataArray[m] = str[n]; // 把数字相关str的装起来 m++; // m是数字在str的长度 } else { if (m > 0) { // 数字部分结束 if (DataArray[m-1] == '.' || DataArray[m-1] == '-') // 不让最后一位为 '.' and '-' DataArray[m-1] = 'Array[m] = ' break; } } } } } Item->NUM[i] = atof(DataArray); return Item->flag; }
测试与验证
为了确保我们的串口数据存储开发板工作正常,我们需要进行一系列的测试,以下是一些常见的测试步骤:
1、物理层通信测试: 使用笔记本端的串口工具(如串口调试助手)测试串口的物理层通信,而不用考虑高层协议,通过USB线连接到ZCU106板卡,板卡内通过USB转串口芯片连接到FPGA,查阅开发板原理图,找到FPGA的时钟和复位管脚,确保复位默认拉低,是高有效复位信号,使用开源的Verilog代码进行接口设计和约束,通过jtag下载bit文件,并使用ila查看波形。
2、双向通信测试: 在开发板上编写简单的串口收发程序,测试双向通信是否正常,发送测试字符串或命令至开发板,并验证是否能够正确接收。
3、稳定性测试: 持续发送大量数据,观察是否存在丢包现象,在不同环境下(如电磁干扰较强的地方)测试UART通信的稳定性。
4、性能测试: 测量最大可接受的波特率,以测试数据传输速度,检查在高速传输时的错误率,如帧错误、溢出错误等。
上文归纳与展望
通过以上步骤,我们成功实现了一个基于串口数据存储的开发板,该开发板不仅具备基本的串口通信功能,还具有良好的稳定性和高性能,我们可以进一步优化代码和硬件设计,提升开发板的性能和可靠性,也可以考虑增加更多的功能模块,如无线通信模块、传感器接口等,以满足更多应用场景的需求。
各位小伙伴们,我刚刚为大家分享了有关“串口数据存储开发板”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!