官方网站: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 库文件夹
- 在 template-app 中新建一个 include/TFT(这里是自建的组件名称) 文件夹
- 将 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)
- 在 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详解
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
- 信号量定义
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