【PC电脑windows编写代码-学习uart0串口编写代码-串口程序-简单通讯交互-基础样例学习】
【PC电脑windows编写代码-学习uart0串口编写代码-串口程序-简单通讯交互-基础样例学习】
1、概述
最为新手,想要快速入门相关设备,比如ESP32,可能最好的方式就是直接手动去敲一遍代码,而串口算是单片机入门中,必不可少的一个基础课程,很多通讯,以及打印各种信息,都需要,而加入一些交互,能让我们更好调试单片机。
我打算出3章,像之前STM32那种单片机,调试串口一样。
第一章,也就是串口基础篇,简单调试ESP32,进行交互。
第二章,将会结合GPIO,进行一些简单外围控制。
第三章,将会结合上位机,使用自制上位机进行联合调试。
2、实验环境
ESP32说明:ESP32-S3 是一款集成 2.4 GHz Wi-Fi 和 Bluetooth 5 (LE) 的 MCU 芯片,支持远距离模式 (Long Range)。ESP32-S3 搭载 Xtensa? 32 位 LX7 双核处理器,主频高达 240 MHz,内置 512 KB SRAM (TCM),具有 45 个可编程 GPIO 管脚和丰富的通信接口。ESP32-S3 支持更大容量的高速 Octal SPI flash 和片外 RAM,支持用户配置数据缓存与指令缓存。
硬件信息:开发板 ESP32-S3-DevKitM-1(EPS32-S3-wroom-1模块)
调试环境:Windows下
串口工具:USB转串口TTL/232等
其他硬件:杜邦线,两个usb-type-c连接线等。
3、 所遇问题说明-问题总结
总结来说,在调试过程中,遇到一些问题,以将问题罗列,如果你遇到了,可以先直接看问题。
1、串口1乱码
在实际编写代码的时候,打算用uart1的,但是发现一直在打乱码。
如下图改到uar0,就没有问题。
这块可能需要对下手册的。
2、不同函数打印出来的信息速度快慢不同
实际调试时,发现如下两个函数。
uart_write_bytes(UART_PORT_NUM0, test_str1, strlen(test_str1));
printf("this is 991!\n");
如果你使用第一个,函数直接向端口写,那么可以直接在端口输出结果。
但是如果使用第二个,会发现,只有你再次输入时,才会打印出来。
如下图所示。
后来实际再次调试的时候,也就是为本次写文章的时候,调试的时候,不出现了,那现这样吧。
3、完全匹配与部分匹配数据
在实际应用的过程中,我开始打算只要输入字符相匹配,那么执行功能。
后来发现,实际情况中,可能会出现其他字符,没办法完全保证,输入和比较的字符完全一致,那么就可以使用部分字符串匹配。而反应到代码中,就是两个不同函数的调用。
//完全匹配才会打印
if (strncmp((const char *)data, expected_string, strlen(expected_string)) == 0) {
}
//部分匹配才会打印
if(strstr ((const char *)data, expected_string0)!=NULL )
{
}
4、 实验过程
1、建立空白工程
找个空白工厂,或者复制一个,相关可以看一下工程。
【ESP32-PC电脑windows-环境搭建-记录-hello-world-运行基础样例学习】
2、编写代码
编写代码,如下,将主要代码直接放在下面。
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"
#define TX_PIN 18
#define RX_PIN 19
#define BUF_SIZE 1024
#define UART_PORT_NUM0 UART_NUM_0
const char *expected_string = "990";
const char *expected_string0 = "990";
const char *expected_string1 = "991";
const char *test_str0 = "write_this_is_990";
const char *test_str1 = "write_this_is_991";
void app_main(void) {
// 配置UART参数
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_PORT_NUM0, &uart_config);
// 设置UART1使用的TX和RX引脚
uart_set_pin(UART_PORT_NUM0, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
// 安装UART驱动程序,使用默认缓冲区大小
uart_driver_install(UART_PORT_NUM0, BUF_SIZE * 2, BUF_SIZE * 2, 0, NULL, 0);
// 发送和接收数据的缓冲区
uint8_t *data = (uint8_t *)malloc(BUF_SIZE);
while (1) {
// 发送数据
const char *test_str = "Hello from UART0!";
uart_write_bytes(UART_PORT_NUM0, test_str, strlen(test_str));
// 从UART接收数据
int length = 0;
ESP_ERROR_CHECK(uart_get_buffered_data_len(UART_NUM_0, (size_t *)&length));
length = uart_read_bytes(UART_PORT_NUM0, data, length, 20 / portTICK_PERIOD_MS);
//-------------------------------------------------
if (length > 0) {
data[length] = 0; // 确保字符串以null终止
printf("Received data: '%s'\n", (char *)data);
vTaskDelay(100 / portTICK_PERIOD_MS);
if(strstr ((const char *)data, expected_string0)!=NULL )
{
uart_write_bytes(UART_PORT_NUM0, test_str0, strlen(test_str0));
vTaskDelay(100 / portTICK_PERIOD_MS);
printf("printf:this is 990\n");
vTaskDelay(100 / portTICK_PERIOD_MS);
// break;
}
if(strstr ((const char *)data, expected_string1) !=NULL )
{
uart_write_bytes(UART_PORT_NUM0, test_str1, strlen(test_str1));
vTaskDelay(100 / portTICK_PERIOD_MS);
printf("this is 991!\n");
vTaskDelay(100 / portTICK_PERIOD_MS);
// break;
}
//------------------------------------------------
// 检查data是否以expected_string开头
if (strncmp((const char *)data, expected_string, strlen(expected_string)) == 0) {
printf("this is 990==strncmp==pass.\n");
vTaskDelay(100 / portTICK_PERIOD_MS);
} else {
// printf("this is 990--strncmp--fail.\n");
// vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
3、调试下载
下载完了按下复位
4、验证
(1)串口输入“990”,字符完全匹配和部分匹配。
(2)串口输入“abc990”,部分匹配。
自己串口输入“99011”,输入的时候,发现也通过完全匹配,还是挺惊讶的,这块大家根据自己最终结果来选择使用吧。
(3)串口交替输入“990”和“991”,打印函数对比。
如下,可以看到,printf函数,是在下次打印触发的,和之前不一样了,如下图是以前有问题的时候,每次会打印上次结果。
既然这次结果正常,那么就以本次为主。
如下为本次实验情况。
5、代码连接
代码链接:https://download.csdn.net/download/qq_22146161/88666274
6、细节部分
(1)其他错误:uart driver error
如上图,可以看到写入 1244,是缓存的问题。
缓存的问题:检查是否有足够的空间在UART的发送缓冲区中存储要发送的数据。如果缓冲区已满,可能需要增加缓冲区大小或等待缓冲区可用。
(2)常见错误解决办法:
调试单片机的时候,或者说调试串口的时候,其实很难问题穷尽,但是一些方式,可以帮我们更快定位。
- UART配置错误:确保你的UART配置与你所使用的引脚和硬件设置相匹配。检查波特率、数据位、校验位和停止位是否正确配置。
- GPIO引脚不正确或被占用:检查你用作UART的GPIO引脚是否正确,并且没有被其他功能(如SPI、I2C或内置功能)占用。
- UART驱动安装问题:确保UART驱动正确安装,没有内存分配错误或其他问题。
- 缓冲区问题:检查是否有足够的空间在UART的发送缓冲区中存储要发送的数据。如果缓冲区已满,可能需要增加缓冲区大小或等待缓冲区可用。
- 硬件问题:检查你的ESP32开发板和任何连接的串行设备是否存在硬件故障。
电源和接地问题:确保所有设备都有适当的电源和接地。
为了解决这个问题,可以尝试以下步骤:
- 重新检查UART配置:确保UART的初始化和配置正确无误。
- 检查GPIO引脚:验证所选择的GPIO引脚是否适合用作UART,且未被占用。
- 检查驱动安装:确保使用 uart_driver_install 函数正确安装了UART驱动。
- 增加缓冲区大小:如果需要,可以在调用 uart_driver_install 时增加缓冲区大小。
- 硬件检查:检查ESP32开发板和相关硬件是否有任何明显的损坏或连接问题。
(3)无法下载原因:
感觉ESP无法下载都可以单独出一篇文章里,今天又发现无法下载的一个样例。
和USB转换TTL转换器,相互冲突,这就很神奇。
解决方式: 先拔掉串口转换器
(4)解释说明
我这里为使用串口转换器进行调试,所以选择了使用引脚,也可能使用自己带的调试串口。
当使用引脚时,时常能发下,PC不识别USB的报错。
7、总结
实践出真知,以实际实验为结果。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!