code: 添加现有程序

This commit is contained in:
DuRuofu
2025-02-17 17:40:08 +08:00
parent 08123c535e
commit 9e552ea395
281 changed files with 13912 additions and 0 deletions

6
code/01.start/blink/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
*build
*managed_components
dependencies.lock
sdkconfig
sdkconfig.old

View File

@@ -0,0 +1,6 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(blink)

View File

@@ -0,0 +1,77 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# Blink Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates how to blink a LED using GPIO or using the [led_strip](https://components.espressif.com/component/espressif/led_strip) component for the addressable LED, i.e. [WS2812](https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf).
The `led_strip` is installed via [component manager](main/idf_component.yml).
## How to Use Example
Before project configuration and build, be sure to set the correct chip target using `idf.py set-target <chip_name>`.
### Hardware Required
* A development board with Espressif SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for Power supply and programming
Some development boards use an addressable LED instead of a regular one. These development boards include:
| Board | LED type | Pin |
| -------------------- | -------------------- | -------------------- |
| ESP32-C3-DevKitC-1 | Addressable | GPIO8 |
| ESP32-C3-DevKitM-1 | Addressable | GPIO8 |
| ESP32-S2-DevKitM-1 | Addressable | GPIO18 |
| ESP32-S2-Saola-1 | Addressable | GPIO18 |
| ESP32-S3-DevKitC-1 | Addressable | GPIO48 |
See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it.
### Configure the Project
Open the project configuration menu (`idf.py menuconfig`).
In the `Example Configuration` menu:
* Select the LED type in the `Blink LED type` option.
* Use `GPIO` for regular LED blink.
* Set the GPIO number used for the signal in the `Blink GPIO number` option.
* Set the blinking period in the `Blink period in ms` option.
### Build and Flash
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Output
As you run the example, you will see the LED blinking, according to the previously defined period. For the addressable LED, you can also change the LED color by setting the `led_strip_set_pixel(led_strip, 0, 16, 16, 16);` (LED Strip, Pixel Number, Red, Green, Blue) with values from 0 to 255 in the [source file](main/blink_example_main.c).
```text
I (315) example: Example configured to blink addressable LED!
I (325) example: Turning the LED OFF!
I (1325) example: Turning the LED ON!
I (2325) example: Turning the LED OFF!
I (3325) example: Turning the LED ON!
I (4325) example: Turning the LED OFF!
I (5325) example: Turning the LED ON!
I (6325) example: Turning the LED OFF!
I (7325) example: Turning the LED ON!
I (8325) example: Turning the LED OFF!
```
Note: The color order could be different according to the LED model.
The pixel number indicates the pixel position in the LED strip. For a single LED, use 0.
## Troubleshooting
* If the LED isn't blinking, check the GPIO or the LED type selection in the `Example Configuration` menu.
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "blink_example_main.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,91 @@
/* Blink Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "led_strip.h"
#include "sdkconfig.h"
static const char *TAG = "example";
/* Use project configuration menu (idf.py menuconfig) to choose the GPIO to blink,
or you can edit the following line and set a number here.
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO
static uint8_t s_led_state = 0;
#ifdef CONFIG_BLINK_LED_RMT
static led_strip_handle_t led_strip;
static void blink_led(void)
{
/* If the addressable LED is enabled */
if (s_led_state) {
/* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */
led_strip_set_pixel(led_strip, 0, 16, 16, 16);
/* Refresh the strip to send data */
led_strip_refresh(led_strip);
} else {
/* Set all LED off to clear all pixels */
led_strip_clear(led_strip);
}
}
static void configure_led(void)
{
ESP_LOGI(TAG, "Example configured to blink addressable LED!");
/* LED strip initialization with the GPIO and pixels number*/
led_strip_config_t strip_config = {
.strip_gpio_num = BLINK_GPIO,
.max_leds = 1, // at least one LED on board
};
led_strip_rmt_config_t rmt_config = {
.resolution_hz = 10 * 1000 * 1000, // 10MHz
};
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
/* Set all LED off to clear all pixels */
led_strip_clear(led_strip);
}
#elif CONFIG_BLINK_LED_GPIO
static void blink_led(void)
{
/* Set the GPIO level according to the state (LOW or HIGH)*/
gpio_set_level(BLINK_GPIO, s_led_state);
}
static void configure_led(void)
{
ESP_LOGI(TAG, "Example configured to blink GPIO LED!");
gpio_reset_pin(BLINK_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
}
#endif
void app_main(void)
{
/* Configure the peripheral according to the LED type */
configure_led();
while (1) {
ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF");
blink_led();
/* Toggle the LED state */
s_led_state = !s_led_state;
vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
}
}

View File

@@ -0,0 +1,2 @@
dependencies:
espressif/led_strip: "^2.0.0"

View File

@@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import logging
import os
import pytest
from pytest_embedded_idf.dut import IdfDut
@pytest.mark.supported_targets
@pytest.mark.generic
def test_blink(dut: IdfDut) -> None:
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'blink.bin')
bin_size = os.path.getsize(binary_file)
logging.info('blink_bin_size : {}KB'.format(bin_size // 1024))

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,4 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
# target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -0,0 +1,42 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "main";
void Task_1(void *pvParameters)
{
for (;;)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Task_1");
}
vTaskDelete(NULL);
}
void Task_2(void *pvParameters)
{
for (;;)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Task_2");
}
vTaskDelete(NULL);
}
void app_main(void)
{
UBaseType_t taskPriority_1 = 0;
UBaseType_t taskPriority_2 = 0;
TaskHandle_t taskHandle_1 = NULL;
TaskHandle_t taskHandle_2 = NULL;
xTaskCreate(Task_1, "Task_1", 2048, NULL, 12, &taskHandle_1);
taskPriority_1 = uxTaskPriorityGet(taskHandle_1);
ESP_LOGI(TAG, "Task_1 优先级:%d", taskPriority_1);
xTaskCreate(Task_2, "Task_1", 2048, NULL, 12, &taskHandle_2);
taskPriority_2 = uxTaskPriorityGet(taskHandle_2);
ESP_LOGI(TAG, "Task_1 优先级:%d", taskPriority_2);
}

View File

@@ -0,0 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,4 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
# target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -0,0 +1,41 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "main";
void Task_1(void *pvParameters)
{
for (;;)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Task_1");
}
vTaskDelete(NULL);
}
void Task_2(void *pvParameters)
{
for (;;)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Task_2");
}
vTaskDelete(NULL);
}
void app_main(void)
{
TaskHandle_t taskHandle_1 = NULL;
TaskHandle_t taskHandle_2 = NULL;
xTaskCreate(Task_1, "Task_1", 2048, NULL, 12, &taskHandle_1);
xTaskCreate(Task_2, "Task_1", 2048, NULL, 12, &taskHandle_2);
// 输出任务列表
static char cBuffer[512]={0};
vTaskList(cBuffer);
ESP_LOGI(TAG, "任务列表:\n%s", cBuffer);
}

View File

@@ -0,0 +1,7 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,29 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "main";
// 任务函数
void myTask(void *pvParameters)
{
for (;;)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "myTask");
}
}
void app_main(void)
{
// 创建一个 FreeRTOS 任务
// 参数说明:
// 1. 任务入口函数myTask
// 2. 任务名称:"myTask",用于调试时标识任务
// 3. 任务堆栈大小2048 字节(适当分配以避免栈溢出)
// 4. 任务参数NULL未传递参数
// 5. 任务优先级1优先级较低空闲任务优先级为 0
// 6. 任务句柄NULL不需要保存任务句柄
xTaskCreate(myTask, "myTask", 2048, NULL, 1, NULL);
}

View File

@@ -0,0 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,4 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
# target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -0,0 +1,64 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "main";
typedef struct
{
int Int;
int Array[3];
} MyStruct;
// 任务函数1:接收整型参数
void Task_1(void *pvParameters)
{
int *pInt = (int *)pvParameters;
ESP_LOGI(TAG, "取得整型参数为:%d", *pInt);
vTaskDelete(NULL);
}
// 任务函数2:接收数组参数
void Task_2(void *pvParameters)
{
int *pArray = (int *)pvParameters;
ESP_LOGI(TAG, "取得数组参数为:%d %d %d", *pArray, *(pArray + 1), *(pArray + 2));
vTaskDelete(NULL);
}
// 任务函数3:接收结构体参数
void Task_3(void *pvParameters)
{
MyStruct *pStruct = (MyStruct *)pvParameters;
ESP_LOGI(TAG, "取得结构体参数为:%d %d %d %d", pStruct->Int, pStruct->Array[0], pStruct->Array[1], pStruct->Array[2]);
vTaskDelete(NULL);
}
// 任务函数4:接收字符串参数
void Task_4(void *pvParameters)
{
char *pChar = (char *)pvParameters;
ESP_LOGI(TAG, "取得字符串参数为:%s", pChar);
vTaskDelete(NULL);
}
int Parameters_1 = 1;
int Parameters_2[3] = {1, 2, 3};
MyStruct Parameters_3 = {1, {1, 2, 3}};
static const char *Parameters_4 = "Hello World!";
void app_main(void)
{
// 传递整形参数
xTaskCreate(Task_1, "Task_1", 2048, (void *)&Parameters_1, 1, NULL);
// 传递数组参数
xTaskCreate(Task_2, "Task_2", 2048, (void *)&Parameters_2, 1, NULL);
// 传递结构体参数
xTaskCreate(Task_3, "Task_3", 3048, (void *)&Parameters_3, 1, NULL);
// 传递字符串参数(注意这里没有取地址符号&)
xTaskCreate(Task_4, "Task_4", 3048, (void *)Parameters_4, 1, NULL);
}

View File

@@ -0,0 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,32 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "main";
// 任务函数
void myTask(void *pvParameters)
{
for (;;)
{
vTaskDelay(500 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "myTask");
}
}
void app_main(void)
{
// 任务句柄
TaskHandle_t taskHandle = NULL;
// 创建一个 FreeRTOS 任务
xTaskCreate(myTask, "myTask", 2048, NULL, 1, &taskHandle);
vTaskDelay(2000 / portTICK_PERIOD_MS);
// 删除任务
if (taskHandle != NULL)
{
vTaskDelete(taskHandle);
}
}

View File

@@ -0,0 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,28 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "main";
// 任务函数
void myTask(void *pvParameters)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "myTask:1");
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "myTask:2");
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "myTask:3");
// 删除任务(如果传递 NULL则删除当前任务)
vTaskDelete(NULL);
}
void app_main(void)
{
// 任务句柄
TaskHandle_t taskHandle = NULL;
// 创建一个 FreeRTOS 任务
xTaskCreate(myTask, "myTask", 2048, NULL, 1, &taskHandle);
}

View File

@@ -0,0 +1,5 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(main)

View File

@@ -0,0 +1,4 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
# target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -0,0 +1,40 @@
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
static const char *TAG = "main";
// 定时器回调
void TimerCallback_1(TimerHandle_t xTimer)
{
// 取到定时器的名字
const char *timerName = pcTimerGetName(xTimer);
// 取得定时器的ID
void *timerID = pvTimerGetTimerID(xTimer);
ESP_LOGI(TAG, "定时器名称:%s,定时器id:%d,定时器回调函数执行", timerName, (int)timerID);
}
void app_main(void)
{
// 创建定时器句柄
TimerHandle_t xTimer_1;
TimerHandle_t xTimer_2;
xTimer_1 = xTimerCreate("timer1", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, TimerCallback_1);
xTimer_2 = xTimerCreate("timer2", pdMS_TO_TICKS(2000), pdTRUE, (void *)1, TimerCallback_1);
xTimerStart(xTimer_1, 0); // 启动定时器
xTimerStart(xTimer_2, 0); // 启动定时器
vTaskDelay(pdMS_TO_TICKS(5000));
//停止定时器
xTimerStop(xTimer_1, 0);
xTimerStop(xTimer_2, 0);
}
// 其他常用函数
// xTimerChangePeriod():修改定时器周期
// xTimerReset():重置定时器
// xTimerDelete():删除定时器

View File

@@ -0,0 +1,7 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.3.2 Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32s3"
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y

View File

@@ -0,0 +1,6 @@
build
*managed_components
dependencies.lock
sdkconfig
sdkconfig.old

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(adc_continuous)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "adc_continuous.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,165 @@
#include <string.h>
#include <stdio.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_adc/adc_continuous.h"
#define _EXAMPLE_ADC_UNIT_STR(unit) #unit
// C预处理器的字符串化操作符 #,它可以将宏参数转换为字符串常量。如果传递 ADC_UNIT 给 _EXAMPLE_ADC_UNIT_STR它会生成字符串 "ADC_UNIT"。
#define EXAMPLE_ADC_UNIT_STR(unit) _EXAMPLE_ADC_UNIT_STR(unit)
// 宏嵌套
// 用于从 adc_digi_output_data_t 结构体中提取通道号和数据值。
#define EXAMPLE_ADC_GET_CHANNEL(p_data) ((p_data)->type1.channel)
#define EXAMPLE_ADC_GET_DATA(p_data) ((p_data)->type1.data)
#define ADC_UNIT ADC_UNIT_1
// ADC通道
//static adc_channel_t channel[2] = {ADC_CHANNEL_6, ADC_CHANNEL_7};
static adc_channel_t channel[1] = {ADC_CHANNEL_6};
static TaskHandle_t s_task_handle;
static const char *TAG = "ADC_CONTINUOUS";
// ADC连续模式的事件回调(一个转换帧完成时)
static bool IRAM_ATTR s_conv_done_cb(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data)
{
BaseType_t mustYield = pdFALSE;
//Notify that ADC continuous driver has done enough number of conversions
//vTaskNotifyGiveFromISR 是 FreeRTOS 提供的一个函数它允许从中断服务例程ISR安全地向任务发送通知
vTaskNotifyGiveFromISR(s_task_handle, &mustYield);
return (mustYield == pdTRUE);
}
// adc初始化
static void continuous_adc_init(adc_channel_t *channel, uint8_t channel_num, adc_continuous_handle_t *out_handle)
{
// 创建一个ADC连续模式的句柄
adc_continuous_handle_t handle = NULL;
// 配置ADC连续模式的参数
adc_continuous_handle_cfg_t adc_config = {
.max_store_buf_size = 1024, // 最大存储缓冲区大小
.conv_frame_size = 256, // 转换帧大小
};
ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &handle));
// ADC IO
adc_continuous_config_t dig_cfg = {
.sample_freq_hz = 20 * 1000, // 采样频率
.conv_mode = ADC_CONV_SINGLE_UNIT_1, // 转换模式
.format = ADC_DIGI_OUTPUT_FORMAT_TYPE1, // 输出格式
};
adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0};
dig_cfg.pattern_num = channel_num; // 通道数量
for (int i = 0; i < channel_num; i++) {
adc_pattern[i].atten = ADC_ATTEN_DB_11; // ADC 衰减
adc_pattern[i].channel = channel[i] & 0x7; // 通道
adc_pattern[i].unit = ADC_UNIT; // ADC单元
adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; // 位宽
// 打印配置信息
// - PRIx8 是一个预处理宏,定义在 C 语言的标准库头文件 <inttypes.h> 中。它用于以可移植的方式格式化输出 uint8_t 类型的数据为十六进制形式。
ESP_LOGI(TAG, "adc_pattern[%d].atten is :%"PRIx8, i, adc_pattern[i].atten);
ESP_LOGI(TAG, "adc_pattern[%d].channel is :%"PRIx8, i, adc_pattern[i].channel);
ESP_LOGI(TAG, "adc_pattern[%d].unit is :%"PRIx8, i, adc_pattern[i].unit);
}
// 要使用的 ADC 通道的配置列表
dig_cfg.adc_pattern = adc_pattern;
ESP_ERROR_CHECK(adc_continuous_config(handle, &dig_cfg));
*out_handle = handle;
}
void app_main(void)
{
esp_err_t ret; // 返回状态
uint32_t ret_num = 0; // 转换完成的数据数量
// 定义接收数组
uint8_t result[256] = {0};
// 初始化数组,填充为0xcc
memset(result, 0xcc, 256);
//获取app_mian任务的句柄。
s_task_handle = xTaskGetCurrentTaskHandle();
// 初始化ADC
adc_continuous_handle_t handle = NULL;
continuous_adc_init(channel, sizeof(channel) / sizeof(adc_channel_t), &handle);
// 事件回调
adc_continuous_evt_cbs_t cbs = {
// 当一个转换帧完成时,触发此事件:s_conv_done_cb
.on_conv_done = s_conv_done_cb,
};
// 注册事件回调
ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle, &cbs, NULL));
// 启动ADC连续模式
ESP_ERROR_CHECK(adc_continuous_start(handle));
while (1) {
/**
* This is to show you the way to use the ADC continuous mode driver event callback.
* This `ulTaskNotifyTake` will block when the data processing in the task is fast.
* However in this example, the data processing (print) is slow, so you barely block here.
*
* Without using this event callback (to notify this task), you can still just call
* `adc_continuous_read()` here in a loop, with/without a certain block timeout.
*/
// ulTaskNotifyTake() 等待通知
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// 生成字符串
char unit[] = EXAMPLE_ADC_UNIT_STR(ADC_UNIT);
while (1) {
// 读取ADC数据
ret = adc_continuous_read(handle, result, 256, &ret_num, 0);
// 读取成功
if (ret == ESP_OK) {
// 显示读取操作的返回状态和实际读取到的数据字节数
ESP_LOGI("TASK", "ret is %x, ret_num is %"PRIu32" bytes", ret, ret_num);
// 循环遍历读取到的数据解析每个ADC数据项并打印出来
// - 循环以 SOC_ADC_DIGI_RESULT_BYTES 为步长迭代这个常量定义了每个ADC数据项的字节大小。
// - adc_digi_output_data_t 是一个结构体类型用于解析ADC数据项。
// - EXAMPLE_ADC_GET_CHANNEL(p) 和 EXAMPLE_ADC_GET_DATA(p) 是宏,用于从 adc_digi_output_data_t 结构体中提取通道号和数据值。
for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) {
adc_digi_output_data_t *p = (adc_digi_output_data_t*)&result[i];
uint32_t chan_num = EXAMPLE_ADC_GET_CHANNEL(p);
uint32_t data = EXAMPLE_ADC_GET_DATA(p);
/*检查通道编号验证,如果通道编号超过最大通道,则数据无效 */
// - PRIu32 是 C 语言标准库中的宏,它用于以可移植的方式格式化输出 uint32_t 类型的数据。
if (chan_num < SOC_ADC_CHANNEL_NUM(ADC_UNIT)) {
ESP_LOGI(TAG, "Unit: %s, Channel: %"PRIu32", Value: %"PRIu32, unit, chan_num, data);
} else {
ESP_LOGW(TAG, "Invalid data [%s_%"PRIu32"_%"PRIu32"]", unit, chan_num, data);
}
}
/**
* Because printing is slow, so every time you call `ulTaskNotifyTake`, it will immediately return.
* To avoid a task watchdog timeout, add a delay here. When you replace the way you process the data,
* usually you don't need this delay (as this task will block for a while).
*/
vTaskDelay(1);
} else if (ret == ESP_ERR_TIMEOUT) {
//We try to read `EXAMPLE_READ_LEN` until API returns timeout, which means there's no available data
break;
}
}
}
// 停止ADC连续模式
ESP_ERROR_CHECK(adc_continuous_stop(handle));
ESP_ERROR_CHECK(adc_continuous_deinit(handle));
}

View File

@@ -0,0 +1,6 @@
build
*managed_components
dependencies.lock
sdkconfig
sdkconfig.old

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(adc_oneshot)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "adc_oneshot.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,46 @@
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_adc/adc_oneshot.h"
#define EXAMPLE_ADC1_CHAN0 ADC_CHANNEL_6 // 根据您的硬件配置选择合适的通道
#define EXAMPLE_ADC1_CHAN1 ADC_CHANNEL_7 // 根据您的硬件配置选择合适的通道
static const char* TAG = "ADC_ONESHOT_EXAMPLE";
void app_main(void)
{
adc_oneshot_unit_handle_t adc1_handle;
adc_oneshot_unit_init_cfg_t init_config1 = {
.unit_id = ADC_UNIT_1,
.ulp_mode = ADC_ULP_MODE_DISABLE,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB_11, // 设置适当的衰减以匹配您的输入电压范围
};
// 配置两个通道
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &config));
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config));
int adc_raw[2];
// 对每个通道进行单次转换并读取结果
for (int i = 0; i < 10; i++) {
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0]));
ESP_LOGI(TAG, "ADC1 Channel[%d] Raw Data: %d", EXAMPLE_ADC1_CHAN0, adc_raw[0]);
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN1, &adc_raw[1]));
ESP_LOGI(TAG, "ADC1 Channel[%d] Raw Data: %d", EXAMPLE_ADC1_CHAN1, adc_raw[1]);
vTaskDelay(pdMS_TO_TICKS(1000)); // 等待1秒再次读取
}
// 回收资源
ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle));
}

View File

@@ -0,0 +1,6 @@
build
*managed_components
dependencies.lock
sdkconfig
sdkconfig.old

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(dac_cosine)

View File

@@ -0,0 +1,2 @@
idf_component_register(SRCS "dac_cosine.c"
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,36 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/dac_cosine.h"
void app_main(void)
{
dac_cosine_handle_t chan0_handle;
dac_cosine_handle_t chan1_handle;
/* Normally two channels can only be configured to one frequency
* But we can set force_set_freq bit to force update the frequency
* The example here will produce cosine wave at 8 KHz on both channels */
dac_cosine_config_t cos0_cfg = {
.chan_id = DAC_CHAN_0,
.freq_hz = 1000, // It will be covered by 8000 in the latter configuration
.clk_src = DAC_COSINE_CLK_SRC_DEFAULT,
.offset = 0,
.phase = DAC_COSINE_PHASE_0,
.atten = DAC_COSINE_ATTEN_DEFAULT,
.flags.force_set_freq = false,
};
dac_cosine_config_t cos1_cfg = {
.chan_id = DAC_CHAN_1,
.freq_hz = 8000,
.clk_src = DAC_COSINE_CLK_SRC_DEFAULT,
.offset = 0,
.phase = DAC_COSINE_PHASE_180,
.atten = DAC_COSINE_ATTEN_DB_6,
.flags.force_set_freq = true, // set true will allow to overwrite the frequency that set before
};
ESP_ERROR_CHECK(dac_cosine_new_channel(&cos0_cfg, &chan0_handle));
ESP_ERROR_CHECK(dac_cosine_new_channel(&cos1_cfg, &chan1_handle));
ESP_ERROR_CHECK(dac_cosine_start(chan0_handle));
ESP_ERROR_CHECK(dac_cosine_start(chan1_handle));
}

View File

@@ -0,0 +1,6 @@
build
*managed_components
dependencies.lock
sdkconfig
sdkconfig.old

View File

@@ -0,0 +1,8 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(dac_oneshot)

Some files were not shown because too many files have changed in this diff Show More