mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-12 13:27:36 +00:00
adc: add adc programming guide on c3
This commit is contained in:
6
examples/peripherals/adc/esp32c3/adc/CMakeLists.txt
Normal file
6
examples/peripherals/adc/esp32c3/adc/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
# The following 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.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(adc)
|
63
examples/peripherals/adc/esp32c3/adc/README.md
Normal file
63
examples/peripherals/adc/esp32c3/adc/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
| Supported Targets | ESP32-C3 |
|
||||
| ----------------- | -------- |
|
||||
|
||||
# ADC DMA Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example shows how to use DMA-Read-APIs and Single-Read-APIs to read voltage from GPIO pins via ADC controller.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
|
||||
* A development board with ESP32C3 SoC
|
||||
* A USB cable for power supply and programming
|
||||
|
||||
For `single_read` (Single-Read-APIs example), we use `ADC1_CHANNEL_2`, `ADC1_CHANNEL_3`, `ADC1_CHANNEL_4`, `ADC2_CHANNEL_0`. Hence we need to connect voltage sources (0 ~ 3.3V) to GPIO2, GPIO3, GPIO4, GPIO5 respectively.
|
||||
|
||||
For `continuous_read` (DMA-Read-APIs example), we use `ADC1_CHANNEL_0`, `ADC1_CHANNEL_1` and `ADC2_CHANNEL_0`. Therefore, GPIO0, GPIO1 and GPIO5 should be connected to voltage sources (0 ~ 3.3V).
|
||||
|
||||
If other ADC units/channels are selected in your application, you need to change the GPIO pin (please refer to the `ESP32C3 Technical Reference Manual`).
|
||||
|
||||
### Configure the project
|
||||
|
||||
```
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
Running this example, you will see the following log output on the serial monitor:
|
||||
```
|
||||
I (322) ADC1_CH2: 7c8
|
||||
I (322) ADC1_CH3: 278
|
||||
I (322) ADC1_CH4: d4b
|
||||
I (322) ADC2_CH0: 48
|
||||
```
|
||||
```
|
||||
ADC1_CH0: 61b
|
||||
ADC1_CH1: 39b
|
||||
ADC2_CH0: 4b
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* program upload failure
|
||||
|
||||
* Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
|
||||
* The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
|
||||
|
||||
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
|
2
examples/peripherals/adc/esp32c3/adc/main/CMakeLists.txt
Normal file
2
examples/peripherals/adc/esp32c3/adc/main/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "adc_dma_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
124
examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c
Normal file
124
examples/peripherals/adc/esp32c3/adc/main/adc_dma_example_main.c
Normal file
@@ -0,0 +1,124 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/adc.h"
|
||||
|
||||
#define TIMES 256
|
||||
|
||||
static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask, adc_channel_t *channel, uint8_t channel_num)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
adc_digi_init_config_t adc_dma_config = {
|
||||
.max_store_buf_size = 1024,
|
||||
.conv_num_each_intr = 256,
|
||||
.adc1_chan_mask = adc1_chan_mask,
|
||||
.adc2_chan_mask = adc2_chan_mask,
|
||||
};
|
||||
ret = adc_digi_initialize(&adc_dma_config);
|
||||
assert(ret == ESP_OK);
|
||||
|
||||
adc_digi_pattern_table_t adc_pattern[10] = {0};
|
||||
|
||||
//Do not set the sampling frequency out of the range between `SOC_ADC_SAMPLE_FREQ_THRES_LOW` and `SOC_ADC_SAMPLE_FREQ_THRES_HIGH`
|
||||
adc_digi_config_t dig_cfg = {
|
||||
.conv_limit_en = 0,
|
||||
.conv_limit_num = 250,
|
||||
.sample_freq_hz = 620,
|
||||
};
|
||||
|
||||
dig_cfg.adc_pattern_len = channel_num;
|
||||
for (int i = 0; i < channel_num; i++) {
|
||||
uint8_t unit = ((channel[i] >> 3) & 0x1);
|
||||
uint8_t ch = channel[i] & 0x7;
|
||||
adc_pattern[i].atten = ADC_ATTEN_DB_0;
|
||||
adc_pattern[i].channel = ch;
|
||||
adc_pattern[i].unit = unit;
|
||||
}
|
||||
dig_cfg.adc_pattern = adc_pattern;
|
||||
ret = adc_digi_controller_config(&dig_cfg);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
|
||||
static bool check_valid_data(const adc_digi_output_data_t *data)
|
||||
{
|
||||
const unsigned int unit = data->type2.unit;
|
||||
if (unit > 2) return false;
|
||||
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void continuous_read(void *arg)
|
||||
{
|
||||
esp_err_t ret;
|
||||
uint32_t ret_num = 0;
|
||||
uint8_t result[TIMES] = {0};
|
||||
memset(result, 0xcc, TIMES);
|
||||
|
||||
uint16_t adc1_chan_mask = BIT(0) | BIT(1);
|
||||
uint16_t adc2_chan_mask = BIT(0);
|
||||
adc_channel_t channel[3] = {ADC1_CHANNEL_0, ADC1_CHANNEL_1, (ADC2_CHANNEL_0 | 1 << 3)};
|
||||
|
||||
continuous_adc_init(adc1_chan_mask, adc2_chan_mask, channel, sizeof(channel) / sizeof(adc_channel_t));
|
||||
adc_digi_start();
|
||||
|
||||
int n = 20;
|
||||
while(n--) {
|
||||
ret = adc_digi_read_bytes(result, TIMES, &ret_num, ADC_MAX_DELAY);
|
||||
for (int i = 0; i < ret_num; i+=4) {
|
||||
adc_digi_output_data_t *p = (void*)&result[i];
|
||||
if (check_valid_data(p)) {
|
||||
printf("ADC%d_CH%d: %x\n", p->type2.unit+1, p->type2.channel, p->type2.data);
|
||||
} else {
|
||||
printf("Invalid data [%d_%d_%x]\n", p->type2.unit+1, p->type2.channel, p->type2.data);
|
||||
}
|
||||
}
|
||||
// If you see task WDT in this task, it means the conversion is too fast for the task to handle
|
||||
}
|
||||
|
||||
adc_digi_stop();
|
||||
ret = adc_digi_deinitialize();
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
|
||||
static void single_read(void *arg)
|
||||
{
|
||||
esp_err_t ret;
|
||||
int adc1_reading[3] = {0xcc};
|
||||
int adc2_reading[1] = {0xcc};
|
||||
|
||||
const char TAG_CH[][10] = {"ADC1_CH2", "ADC1_CH3","ADC1_CH4", "ADC2_CH0"};
|
||||
|
||||
adc1_config_width(ADC_WIDTH_BIT_DEFAULT);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_2, ADC_ATTEN_DB_0);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_0);
|
||||
adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_0);
|
||||
|
||||
int n = 20;
|
||||
while (n--) {
|
||||
|
||||
adc1_reading[0] = adc1_get_raw(ADC1_CHANNEL_2);
|
||||
adc1_reading[1] = adc1_get_raw(ADC1_CHANNEL_3);
|
||||
adc1_reading[2] = adc1_get_raw(ADC1_CHANNEL_4);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ESP_LOGI(TAG_CH[i], "%x", adc1_reading[i]);
|
||||
}
|
||||
|
||||
ret = adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &adc2_reading[0]);
|
||||
assert(ret == ESP_OK);
|
||||
ESP_LOGI(TAG_CH[3], "%x", adc2_reading[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
single_read(NULL);
|
||||
continuous_read(NULL);
|
||||
}
|
Reference in New Issue
Block a user