zoukankan      html  css  js  c++  java
  • 105-ESP32_SDK开发-串口,485通信

    <p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnESP32" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>

    说明

    模块有3个串口,每个串口管脚可以设置到任意的gpio上

    模组出厂默认使用GPIO1,GPIO3作为串口0引脚(日志打印);  GPIO17,GPIO16作为串口1引脚(AT指令)

    开发板上也把串口1连接了485上.

    说明2

    每个串口都有一个128字节的FIFO缓存区,知道这个就可以.

    设置串口1,带接收缓存,不带发送缓存区的方式(最简洁的方式)

    设置GPIO17,GPIO16作为串口1引脚.

    没有设置发送缓存,调用 uart_write_bytes 发送数据的时候是阻塞的.

    #include <stdio.h>
    #include <string.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    #include "driver/gpio.h"
    #include "driver/timer.h"
    #include "esp_timer.h"
    #include "driver/uart.h"
    
    #define TXD1_PIN (GPIO_NUM_17) //串口1的发送数据引脚
    #define RXD1_PIN (GPIO_NUM_16) //串口1的接收数据引脚
    #define BUF_SIZE (1024) //接收数据缓存大小,该大小需要大于内部FIFO大小:UART_FIFO_LEN(128)
    /*串口任务*/
    static void uart_task(void *arg)
    {
        /*配置串口参数*/
        uart_config_t uart_config = {
            .baud_rate = 115200,//波特率
            .data_bits = UART_DATA_8_BITS,//数据位8位
            .parity    = UART_PARITY_DISABLE,//无奇偶校验
            .stop_bits = UART_STOP_BITS_1,//停止位1位
            .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,//不使用硬件流控
            .source_clk = UART_SCLK_APB,//串口使用的时钟
        };
        /*初始化串口1*/
        uart_driver_install(UART_NUM_1, 
            BUF_SIZE, //串口1接收缓存大小
            0, //不使用发送缓存(发送数据的时候便会阻塞发送)
            0, //队列大小为0;没有使用freertos内部缓存管理
            NULL, //不使用QueueHandle_t 内部缓存管理,设置为空
            0 //设置串口中断优先级,设置为0意味着让系统从1-3级中自动选择一个
        );
        /*设置串口参数*/
        uart_param_config(UART_NUM_1, &uart_config);
        /*设置串口的TX,RX,RTS,DTR引脚*/             //不使用RTS,DTR
        uart_set_pin(UART_NUM_1, TXD1_PIN, RXD1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
        /*申请一块内存,用于临时存储接收的数据*/
        uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
        while (1) {
            //接收串口数据                                         //每隔10ms判断一次,可以写成portMAX_DELAY(一直判断)
            int len = uart_read_bytes(UART_NUM_1, data, BUF_SIZE, 10 / portTICK_RATE_MS);
            //把接收的数据发送出去
            uart_write_bytes(UART_NUM_1, (const char *) data, len);
        }
    }
    void app_main(void)
    {
        xTaskCreate(uart_task, "uart_task", 2048, NULL, 10, NULL);
    }

    下载程序到开发板以后可以通过串口测试

    485接口默认连接串口1,也可以使用485进行通讯

    发送什么数据将会返回什么数据

     

    设置串口1,带接收缓存,带发送缓存区的方式

    设置上发送缓存区以后,调用 uart_write_bytes 发送数据的时候,将不会阻塞在那里.

    设置串口1,带接收缓存,带发送缓存区,并使用上freertos内部的缓存管理的方式

    加上缓存管理

    从缓存管理中获取数据

    #include <stdio.h>
    #include <string.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/queue.h"
    #include "driver/gpio.h"
    #include "driver/timer.h"
    #include "esp_timer.h"
    #include "driver/uart.h"
    
    #define TXD1_PIN (GPIO_NUM_17) //串口1的发送数据引脚
    #define RXD1_PIN (GPIO_NUM_16) //串口1的接收数据引脚
    #define BUF_SIZE (1024) //接收数据缓存大小,该大小需要大于内部FIFO大小:UART_FIFO_LEN(128)
    
    #define BUF_SEND_SIZE (1024) //发送数据缓存大小,该大小需要大于内部FIFO大小:UART_FIFO_LEN(128)
    
    
    static QueueHandle_t QueueHandle_t_uart1;
    
    /*串口任务*/
    static void uart_task(void *arg)
    {
        /*配置串口参数*/
        uart_config_t uart_config = {
            .baud_rate = 115200,//波特率
            .data_bits = UART_DATA_8_BITS,//数据位8位
            .parity    = UART_PARITY_DISABLE,//无奇偶校验
            .stop_bits = UART_STOP_BITS_1,//停止位1位
            .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,//不使用硬件流控
            .source_clk = UART_SCLK_APB,//串口使用的时钟
        };
        /*初始化串口1*/
        uart_driver_install(UART_NUM_1, 
            BUF_SIZE, //串口1接收缓存大小
            BUF_SEND_SIZE, //串口1发送缓存大小
            10, //队列大小为10
            &QueueHandle_t_uart1, //缓存管理
            0 //设置串口中断优先级,设置为0意味着让系统从1-3级中自动选择一个
        );
        /*设置串口参数*/
        uart_param_config(UART_NUM_1, &uart_config);
        /*设置串口的TX,RX,RTS,DTR引脚*/             //不使用RTS,DTR
        uart_set_pin(UART_NUM_1, TXD1_PIN, RXD1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    
        /*申请一块内存,用于临时存储接收的数据*/
        uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
        uart_event_t event;
        while (1) {
            if(xQueueReceive(QueueHandle_t_uart1, (void * )&event, portMAX_DELAY))
            {
                switch(event.type) {
                    case UART_DATA://接收到数据
                        //读取接收的数据
                        uart_read_bytes(UART_NUM_1, data, event.size, portMAX_DELAY);
                        //返回接收的数据
                        uart_write_bytes(UART_NUM_1, (const char*) data, event.size);
                        break;
                    case UART_FIFO_OVF://FIFO溢出(建议加上数据流控制)
                        uart_flush_input(UART_NUM_1);
                        xQueueReset(QueueHandle_t_uart1);
                        break;
                    case UART_BUFFER_FULL://接收缓存满(建议加大缓存 BUF_SIZE)
                        uart_flush_input(UART_NUM_1);
                        xQueueReset(QueueHandle_t_uart1);
                        break;
                    case UART_BREAK://检测到接收数据中断
                        break;
                    case UART_PARITY_ERR://数据校验错误
                        break;
                    case UART_FRAME_ERR://数据帧错误
                        break;
                    case UART_PATTERN_DET://接收到相匹配的字符(没用到)
                        break;
                    default:
                        break;
                }
            }
        }
        free(data);
        data = NULL;
        vTaskDelete(NULL);
    }
    void app_main(void)
    {
        xTaskCreate(uart_task, "uart_task", 2048, NULL, 10, NULL);
    }

    如果想配置串口0或者串口2

    把以下变量的最后一个数字改为0或者2即可

    关于模式匹配和485方向控制,参考

    https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/peripherals/uart.html?highlight=uart_pattern_det#

    官方文档

  • 相关阅读:
    Android数据存储之SQLCipher数据库加密
    Android数据加密之Aes加密
    Android自定义控件之自定义组合控件
    Android自定义控件之自定义属性
    Android自定义控件之基本原理
    Java设计模式之代理模式(Proxy)
    Android注解使用之使用Support Annotations注解优化代码
    Java学习之注解Annotation实现原理
    Android数据存储之GreenDao 3.0 详解
    Android性能优化之App应用启动分析与优化
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/15112125.html
Copyright © 2011-2022 走看看