ESP32_UART的简单使用

冇雨
2023-09-29 / 0 评论 / 133 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年09月29日,已超过450天没有更新,若内容或图片失效,请留言反馈。

串口协议简介

  串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息,ESP32 自有一个串口用于程序下载和 log 打印,就是这个道理。
  在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流,协议层则规定我们用中文还是英文来交流

物理层

  串口通讯的物理层有很多标准及变种,我们主要讲解 RS-232 标准 ,RS-232 标准主要规定了信号的用途、通讯接口以及信号的电平标准。使用 RS-232 标准的串口设备间常见的
通讯结构如下
ln4olzqy.png
  在上面的通讯方式中,两个通讯设备的“DB9 接口”之间通过串口信号线建立起连接,串口信号线中使用“RS-232 标准”传输数据信号。由于 RS-232 电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个“电平转换芯片”转换成控制器能识别的“TTL校准”的电平信号,才能实现通讯。

协议层

  串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口。在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据,其组成如下:
ln4ooiw9.png
1.波特率
  文中主要讲解的是串口异步通讯,异步通讯中由于没有时钟信号(如前面讲解的 DB9接口中是没有时钟信号的),所以两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码,上图中用虚线分开的每一格就是代表一个码元。常见的波特率为 4800、9600、115200 等
2.通讯的起始和停止信号
串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑 0 的数据位表示,而数据包的停止信号可由 0.5、1、1.5 或 2 个逻辑 1 的数据位表示,只要双方约定一致即可。
3.有效数据
  在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为 5、6、7 或 8 位长
4.数据校验
在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及无校验(noparity)。在无校验的情况下,数据包中不包含校验位

硬件设计及原理

设备连接

UART1功能映射 ESP32 的引脚TTL转串口引脚
TX发送1RX
RX接收3TX
3V3供电 VCC
GND接地 GND

  若使用的实验板 UART 的连接方式或引脚不一样,只需根据工程修改引脚即可,程序的控制原理相同。

ln4p6d1j.png

软件设计


#include <stdio.h>
#include "freertos/FreeRTOS.h"//freertos系统文件
#include "freertos/task.h"//任务创建
#include "driver/uart.h"//串口驱动
#include "driver/gpio.h"//gpio(引脚,输入输出)
#include "sdkconfig.h"

#define Uart_1 UART_NUM_0       //选择串口端口
#define Uart1_rate   115200     //设置串口波特率
#define Uart1_data    UART_DATA_8_BITS//数据位
#define Uart1_parity    UART_PARITY_DISABLE//奇偶校验
#define Uart1_stop     UART_STOP_BITS_1 //停止位  
#define Uart1_ctrl    UART_HW_FLOWCTRL_DISABLE//流控
#define Uart1_flow      122//硬件RTS阀值
#define BUF_SIZE 1024
void uart_init()
{
    //配置UART相关参数
    uart_config_t uart1_config =
    {
        .baud_rate = Uart1_rate,
        .data_bits = Uart1_data,
        .parity    = Uart1_parity,
        .stop_bits = Uart1_stop,
        .flow_ctrl = Uart1_ctrl,
        .rx_flow_ctrl_thresh = Uart1_flow,
    };
    //串口参数配置 串口号、串口配置参数
    ESP_ERROR_CHECK(uart_param_config(Uart_1,&uart1_config));
    //安装串口驱动 串口编号、接收buff、发送buff、事件队列、分配中断的标志
    ESP_ERROR_CHECK(uart_set_pin(Uart_1,1,3,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE));
    //安装串口驱动 串口编号、接收buff、发送buff、事件队列、分配中断的标志
    ESP_ERROR_CHECK(uart_driver_install(Uart_1,1024 *2,1024*2,0,NULL,0));
    
     // 申请临时内存
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);

     while (1) {
        // Read data from the UART 接收到串口数据
        int len = uart_read_bytes(Uart_1, data, BUF_SIZE, 20 / portTICK_PERIOD_MS);
        // Write data back to the UART 发送串口数据
        uart_write_bytes(Uart_1, (const char *) data, len);
    }
}


void app_main(void)
{
  xTaskCreate(uart_init, "uart_echo_task", 1024*2, NULL,10, NULL); //创建串口应声虫任务
}
1

评论

博主关闭了所有页面的评论