ESP32开发路程——环境搭建、引脚、烧录、UART、ADC、WS2812、RFID、DAC、FreeRTOS、CJSON


官方网站:ESPRESSIF
参考教程:史上最全的ESP32教程
官方编程指南:ESP-IDF编程指南

环境搭建

使用Arduino IDE开发起来会更快,但为了避免以后控制起来出现底层冲突,所以使用VSCODE+ESP-IDF开发环境。具体操作在参考教程链接。
(万事开头难,每次都要为配置环境这些破事挠掉几根头发,我真的会谢!)
如果没有USE EXISTING SETUP这个选项,就重启一下VSCODE!

编译例程

具体操作在参考教程链接。我的例程路径在 E:\Download\ESP-IDF\Espressif\frameworks\esp-idf-v4.4.2\examples(以防以后找不到)
烧录不成功的话,根据VSCODE的自动弹窗,把相应的需求安装配置好

引脚说明、模组烧录

ESP32引脚说明:ESP32引脚参考
ESP32模组烧录:如何为 ESP 系列模组烧录固件

常用操作

  • 自己创建工程
    • 查看-控制面板(ctrl+shift+p)
    • 搜索:ESP-IDF:Create project from extersion template
    • 选择路径
    • 工程类型:template-app
  • 打开文件
    • 用文件夹的形式打开相应路径的template-app目录
  • 自己添加.c .h文件
    • 在main目录下,右键新建相应的.c .h文件。
    • 在main文件夹下的 CMakeList.txt 中,添加.c路径,参考如下:
idf_component_register(SRCS "Uart.c" "main.c" "ADC.c"
                   INCLUDE_DIRS ".")
  • 自己添加 include 库文件夹
  1. 在 template-app 中新建一个 include/TFT(这里是自建的组件名称) 文件夹
  2. 将 template-app 中的 CMakeLists.txt 更改如下:
cmake_minimum_required(VERSION 3.5)

set(EXTRA_COMPONENT_DIRS "./include")

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(template-app)
  1. 在 TFT 文件夹中包含所需的.c .h 和以下 CMakeLists.txt (其中的.c内容根据自己情况更改)
idf_component_register(SRCS "bitstream.c" "mmask.c" "mqrspec.c" "QR_Encode.c" "qrencode.c" "qrinput.c" "qrspec.c" "rscode.c" "split.c" "ST7735.c" "mask.c" 
                    INCLUDE_DIRS ".")

相关API详解

GPIO & RTC GPIO
UART
ADC
RMT

UART

  • 初始化
void uart_1_init(void) 
{
    const uart_config_t uart_config = {
        .baud_rate = UART_1_BAUD,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
    };
    
    uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0);
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, UART_1_TXD_PIN, UART_1_RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}
  • printf 重定向
void uart_1_printf(const char *format,...)
{
	uint16_t len;
	va_list args;	
	va_start(args, format);
	len = vsnprintf((char*)UartTxBuf, sizeof(UartTxBuf)+1, (char*)format, args);
	va_end(args);
    uart_write_bytes(UART_NUM_1, UartTxBuf, len);
    
    ESP_LOGI("Uart1Tx", "Wrote %d bytes", len);
}

ADC

参考:有关ESP32-ADC的使用介绍得比较全面简洁的一篇
ADC1支持8个通道(GPIO32-GPIO39),ADC2支持10个通道(GPIO0、GPIO2、GPIO4、GPIO12-GPIO15、GPIO25-GPIO27)注: GPIO0、GPIO2、GPIO15为芯片的Strapping 管脚;ADC2只能在WIFI功能未启动下使用。

  • 初始化
#define ADC_1_CHANNEL (ADC1_CHANNEL_7)

// 12位ADC 衰减11db(0-3.3V)
void adc_1_init(void) 
{
    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(ADC_1_CHANNEL, ADC_ATTEN_DB_11);
}
  • 获取ADC值
int adc_1_get(void)
{
    int value = adc1_get_raw(ADC_1_CHANNEL);
    return value;
}

WS2812(RMT)

  • 初始化
void WS2812_1_init(void)
{
    // 使用默认参数填入rmt_config_t结构体
    rmt_config_t config = RMT_DEFAULT_CONFIG_TX(WS2812_1_PIN, RMT_TX_CHANNEL);
    // 将时钟设置为40MHz
    config.clk_div = 2;

    // 调用两个函数完成初始化
    ESP_ERROR_CHECK(rmt_config(&config));
    ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));

    // install ws2812 driver 安装ws2812驱动
    led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(WS2812_1_NUM, (led_strip_dev_t)config.channel);
    WS2812_1_strip = led_strip_new_rmt_ws2812(&strip_config);
    if (!WS2812_1_strip) {
        ESP_LOGE("WS2812", "install WS2812 driver failed");
    }
    // Clear LED strip (turn off all LEDs)关闭所有ws2812
    ESP_ERROR_CHECK(WS2812_1_strip->clear(WS2812_1_strip, 100));
}
  • 点亮某颗灯珠
// 红
	ESP_ERROR_CHECK(WS2812_1_strip->set_pixel(WS2812_1_strip, 0, 255, 0, 0));
	ESP_ERROR_CHECK(WS2812_1_strip->refresh(WS2812_1_strip, 100));

RFID

  • .h 内参数定义
// GPIO 相关
#define NFC_RST_GPIO_PIN        GPIO_NUM_25
#define NFC_SPI_MISO_PIN        GPIO_NUM_19
#define NFC_SPI_MOSI_PIN        GPIO_NUM_23
#define NFC_SPI_SCLK_PIN        GPIO_NUM_18
#define NFC_SPI_CS_PIN          GPIO_NUM_5

#define DMA_CHAN                2
  • 初始化
void RFID_init(void)
{
    // GPIO初始化
    gpio_pad_select_gpio(NFC_RST_GPIO_PIN);                 // 选择一个GPIO
    gpio_set_direction(NFC_RST_GPIO_PIN, GPIO_MODE_OUTPUT); // 把这个GPIO作为输出
    NFC_GPIO_Write(NFC_RST_HIGH);
    gpio_pad_select_gpio(NFC_SPI_CS_PIN);                   // 选择一个GPIO
    gpio_set_direction(NFC_SPI_CS_PIN, GPIO_MODE_OUTPUT);   // 把这个GPIO作为输出

    // SPI初始化
    esp_err_t ret;
    spi_bus_config_t spiBusConfig =
    {
        .miso_io_num = NFC_SPI_MISO_PIN,                    // MISO信号线
        .mosi_io_num = NFC_SPI_MOSI_PIN,                    // MOSI信号线
        .sclk_io_num = NFC_SPI_SCLK_PIN,                    // SCLK信号线
        .quadwp_io_num = -1,                                // WP信号线,专用于QSPI的D2
        .quadhd_io_num = -1,                                // HD信号线,专用于QSPI的D3
        .max_transfer_sz = 64 * 8,                          // 最大传输数据大小
    };
    spi_device_interface_config_t spiDeviceConfig =
    {
        .clock_speed_hz = SPI_MASTER_FREQ_10M,              // Clock out at 10 MHz,
        .mode = 0,                                          // SPI mode 0
        /*
         * The timing requirements to read the busy signal from the EEPROM cannot be easily emulated
         * by SPI transactions. We need to control CS pin by SW to check the busy signal manually.
         */
        .spics_io_num = -1,
        .queue_size = 7,                                    // 传输队列大小,决定了等待传输数据的数量
    };
    //Initialize the SPI bus
    ret = spi_bus_initialize(SPI3_HOST, &spiBusConfig, DMA_CHAN);
    ESP_ERROR_CHECK(ret);
    ret = spi_bus_add_device(SPI3_HOST, &spiDeviceConfig, &s_spiHandle);
    ESP_ERROR_CHECK(ret);

    // RFID初始化
    pcdReset();                                 // 复位
    delayMs(5);
        ESP_LOGI(TAG, "reg: %02x" ,readRawRc(Status1Reg));
        ESP_LOGI(TAG, "reg: %02x" ,readRawRc(Status2Reg));
        ESP_LOGI(TAG, "reg: %02x" ,readRawRc(WaterLevelReg));
    pcdAntennaOn();                             // 开启天线发射
}
  • 使用RFID
static void RFID_task(void *arg)
{
    while(1)
    {
        uint8_t card[4];
        MFRC522_ReadCardSerialNo(card);
        ESP_LOGI("RFID", "card: %02x%02x%02x%02x", card[0], card[1], card[2], card[3]);
        bsp_delay_ms(1000);
    }
}

DAC(音频输出)

官方例程
转化音频文件

FreeRTOS

基于ESP32-FreeRTOS学习笔记

  • 信号量定义
	SemaphoreHandle_t semphr_adc_1;
  • 信号量创建
	// 创建信号量
    semphr_adc_1 = xSemaphoreCreateBinary();
  • 信号量释放
	// 释放信号量
	xSemaphoreGive(semphr_adc_1);
  • 信号量获得
	// 获得信号量
	xSemaphoreTake(semphr_adc_1, portMAX_DELAY);//获得信号量

CJSON

参考:
cJSON使用
STM32快速使用CJSON(打包与解析)

  • 打包
    cJSON * usr;
	char *data;
    // 打包成json数据
    usr=cJSON_CreateObject();   //创建根数据对象
    cJSON_AddItemToObject(usr, "A", cJSON_CreateNumber(123));      //根节点下添加数字
    cJSON_AddItemToObject(usr, "B", cJSON_CreateString("hello"));		   //根节点下添加字符
    cJSON_AddItemToObject(usr, "C", cJSON_CreateString("你好"));			   //根节点下添加汉字
    data = cJSON_Print(usr);   //将json形式打印成正常字符串形式(带有\r\n)

	// 串口发送数据
    uart_1_printf("%s",data);

    // 释放内存
    cJSON_Delete(usr);
    free(data);

打包后的数据:

{
	"A":	123,
	"B":	"hello",
	"C":	"你好"
}
  • 解析
    cJSON *json,*json_one,*json_two,*json_three;

    json = cJSON_Parse(out); //将得到的字符串解析成json形式

    json_one = cJSON_GetObjectItem( json , "one" );  //从json获取键值内容
    json_two = cJSON_GetObjectItem( json , "two" );//从json获取键值内容
    json_three = cJSON_GetObjectItem( json , "three" );//从json获取键值内容

    printf("\r\none:%s   two:%d   three:%d",json_one->valuestring,json_two->valueint,json_three->valueint);

    cJSON_Delete(json);  //释放内存 

待解析数据:

{
	"one":	"hello",
	"two":	"2",
	"three":	8
}

解析结果:(json_two->valueint = 0 json_two->valuestring = 2)

one:hello   two:0   three:8

完整工程

ESP32完整工程

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值