您的位置:首页 > 汽车 > 新车 > RP2040 C SDK ADC功能使用

RP2040 C SDK ADC功能使用

2025/1/6 17:37:15 来源:https://blog.csdn.net/weixin_42880082/article/details/142094344  浏览:    关键词:RP2040 C SDK ADC功能使用

RP2040 C SDK ADC功能使用


  • 🌿RP2040 ADC功能说明文档:https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#hardware_adc

📗RP2040 ADC介绍

  • SAR ADC
  • 500 kS/s (Using an independent 48MHz clock)
  • 12 bit (RP2040 8.7 ENOB, RP2350 9.2 ENOB)
  • RP2040 5 input mux:
  • 4 inputs that are available on package pins shared with GPIO[29:26]
  • 1 input is dedicated to the internal temperature sensor
  • 4 element receive sample FIFO。
  • One input dedicated to the internal temperature sensor (see Section 12.4.6)
  • Interrupt generation
  • DMA interface
  • 🍁相关电路:
    在这里插入图片描述

📑RP2040 ADC API相关函数介绍

  • 🌿static inline void adc_select_input(uint input):配置输入通道:0 - 3分别对应GPIO26 - GPIO29。
  • 🌿static inline uint16_t adc_read(void):读取对应通道ADC转换结果。
  • 🌿static inline void adc_set_temp_sensor_enabled(bool enable):内部温度传感器使能位
  • 🌿static inline void adc_gpio_init(uint gpio):配置gpio模式作为ADC模拟输入模式。
  • 🌿static inline void adc_set_round_robin(uint input_mask) :ADC通道选择位:0 - 4bit,值:0 - 1f,分别对应通道0-3,4:内部温度

如果需要配置adc下一个转换通道为3(GPIO29),那么adc_set_round_robin(0x08);等同于adc_select_input(3)效果。

📜ADC通道和输入引脚
  • 用户ADC输入在0-3(GPIO 26-29)上,共用一个ADC模数转换器,在多通道读取轮流读取。内部温度传感器在输入4通道上。
  • CMakeLists.txt配置文件中需要引入adc外设:
# Add the standard library to the build
target_link_libraries(RP2040_ADCpico_stdlibhardware_adc)

📘内部温度读取

/*CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_ADC.elf verify reset exit"jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_ADC.elf verify reset exit"*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/adc.h"
#include "hardware/clocks.h"#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25/* Choose 'C' for Celsius or 'F' for Fahrenheit. */
#define TEMPERATURE_UNITS 'C'static void measure_freqs(void);
/* References for this implementation:* raspberry-pi-pico-c-sdk.pdf, Section '4.1.1. hardware_adc'* pico-examples/adc/adc_console/adc_console.c */
float read_onboard_temperature(const char unit)
{/* 12-bit conversion, assume max value == ADC_VREF == 3.3 V */const float conversionFactor = 3.3f / (1 << 12);float adc = (float)adc_read() * conversionFactor;float tempC = 27.0f - (adc - 0.706f) / 0.001721f;if (unit == 'C'){return tempC;}else if (unit == 'F'){return tempC * 9 / 5 + 32;}return -1.0f;
}int main()
{stdio_init_all();sleep_ms(2500);printf("adc test!\n");set_sys_clock_khz(133000, true); // 325us// GPIO initialisation.gpio_init(BUILTIN_LED);gpio_set_dir(BUILTIN_LED, 1);gpio_pull_up(BUILTIN_LED);adc_init();// 使能温度传感器adc_set_temp_sensor_enabled(true);adc_select_input(4);while (true){// Read the temperature from the onboard temperature sensor.float temperature = read_onboard_temperature(TEMPERATURE_UNITS);printf("Onboard temperature = %.02f %c\n", temperature, TEMPERATURE_UNITS);sleep_ms(1000);gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED// tight_loop_contents();measure_freqs();}return 0;
}static void measure_freqs(void) {uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);printf("pll_sys  = %dkHz\n", f_pll_sys);printf("pll_usb  = %dkHz\n", f_pll_usb);printf("rosc     = %dkHz\n", f_rosc);printf("clk_sys  = %dkHz\n", f_clk_sys);printf("clk_peri = %dkHz\n", f_clk_peri);printf("clk_usb  = %dkHz\n", f_clk_usb);printf("clk_adc  = %dkHz\n", f_clk_adc);printf("clk_rtc  = %dkHz\n", f_clk_rtc);// Can't measure clk_ref / xosc as it is the ref
}

📗ADC单通道读取


/*CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_ADC.elf verify reset exit"jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_ADC.elf verify reset exit"*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/adc.h"
#include "hardware/clocks.h"#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25static void measure_freqs(void);void ADC_Reading(void)
{// 12-bit conversion, assume max value == ADC_VREF == 3.3 Vconst float conversion_factor = 3.3f / (1 << 12);uint16_t result = adc_read();printf("Raw value: 0x%03x, voltage: %f V\n", result, 3 * result * conversion_factor);
}int main()
{stdio_init_all();sleep_ms(2500);printf("adc test!\n");set_sys_clock_khz(133000, true); // 325us// GPIO initialisation.gpio_init(BUILTIN_LED);gpio_set_dir(BUILTIN_LED, 1);gpio_pull_up(BUILTIN_LED);adc_init();// Make sure GPIO is high-impedance, no pullups etcadc_gpio_init(29);// Select ADC input 3 (GPIO29)adc_select_input(3);while (true){
、、sleep_ms(1000);gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED// tight_loop_contents();measure_freqs();ADC_Reading();}return 0;
}static void measure_freqs(void) {uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);printf("pll_sys  = %dkHz\n", f_pll_sys);printf("pll_usb  = %dkHz\n", f_pll_usb);printf("rosc     = %dkHz\n", f_rosc);printf("clk_sys  = %dkHz\n", f_clk_sys);printf("clk_peri = %dkHz\n", f_clk_peri);printf("clk_usb  = %dkHz\n", f_clk_usb);printf("clk_adc  = %dkHz\n", f_clk_adc);printf("clk_rtc  = %dkHz\n", f_clk_rtc);
}

在这里插入图片描述

📒多通道读取方式

由于ADC共用一个ADC模数转换器,在多通道读取时,,需要采用轮流配置通道读取方式。

void ADC_Reading(void)
{// 12-bit conversion, assume max value == ADC_VREF == 3.3 Vconst float conversion_factor = 3.3f / (1 << 12);adc_select_input(2);//设置通道2uint16_t adc_2_raw = adc_read();//读取转换通道转换结果adc_select_input(3);//设置通道3uint16_t adc_3_raw = adc_read();//读取转换通道转换结果printf("Raw1 value: 0x%03x, voltage: %f V\n", adc_2_raw, 3 * adc_2_raw * conversion_factor);printf("Raw2 value: 0x%03x, voltage: %f V\n", adc_3_raw, 3 * adc_3_raw * conversion_factor);
}

📓ADC 通过DMA方式读取

> - 🐛 目前程序有个bug问题:不管设置的dma传输字节大小为DMA_SIZE_8还是DMA_SIZE_16,DMA采样的ADC数据结果都一样。

🔰ADC通过DMA方式读取8位精度和12精度配置差异
  • 至于为什么会有8位和12位精度问题,数据手册上油说明:
Sample FIFO

The ADC samples can be read directly from the RESULT register, or stored in a local 8-entry FIFO and read out from
FIFO. FIFO operation is controlled by the FCS register.
If FCS.EN is set, the result of each ADC conversion is written to the FIFO. A software interrupt handler or the RP2040
DMA can read this sample from the FIFO when notified by the ADC’s IRQ or DREQ signals. Alternatively, software can
poll the status bits in FCS to wait for each sample to become available.
If the FIFO is full when a conversion completes, the sticky error flag FCS.OVER is set. The current FIFO contents are not
changed by this event, but any conversion that completes whilst the FIFO is full will be lost.
There are two flags that control the data written to the FIFO by the ADC:
• FCS.SHIFT will right-shift the FIFO data to eight bits in size (i.e. FIFO bits 7:0 are conversion result bits 11:4). This
is suitable for 8-bit DMA transfer to a byte buffer in memory, allowing deeper capture buffers, at the cost of some
precision.
• FCS.ERR will set the FIFO.ERR flag

  • 🌿ADC通过DMA方式读取8位精度
//ADC FIFO设置adc_fifo_setup(true,    // Write each completed conversion to the sample FIFOtrue,    // Enable DMA data request (DREQ)1,       // DREQ (and IRQ) asserted when at least 1 sample presentfalse,   // We won't see the ERR bit because of 8 bit reads; disable.//Shift each sample to 8 bits when pushing to FIFO [true] Changed to false for 12bit valuestrue// Shift each sample to 8 bits when pushing to FIFO);
  • 🌿ADC通过DMA方式读取12位精度配置
//ADC FIFO设置adc_fifo_setup(true,    // Write each completed conversion to the sample FIFOtrue,    // Enable DMA data request (DREQ)1,       // DREQ (and IRQ) asserted when at least 1 sample presentfalse,   // We won't see the ERR bit because of 8 bit reads; disable.//Shift each sample to 8 bits when pushing to FIFO [true] Changed to false for 12bit valuesfalse     // Shift each sample to 8 bits when pushing to FIFO);
  • 📝ADC通过DMA方式读取8位精度代码

/*CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_ADC_DMA.elf verify reset exit"jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_ADC_DMA.elf verify reset exit"*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/adc.h"
#include "hardware/dma.h"
#include "hardware/clocks.h"
//#include "hardware/irq.h"
#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25// Channel 0 is GPIO26
#define CAPTURE_CHANNEL 0
#define SAMPLES 10
// Ideally the signal should be bandwidth limited to sample_frequency/2
#define SAMPLING_FREQUENCY 14000 // Sampling frequency in Hzuint16_t sampleBuffer[SAMPLES];
uint16_t streamBuffer[SAMPLES]; // Scaled ADC sample working bufferdma_channel_config cfg;
int dma_chan;// const char src[] = "Hello, world! (from DMA)";
// char dst[count_of(src)];static void measure_freqs(void);void ADC_Reading(void)
{// 12-bit conversion, assume max value == ADC_VREF == 3.3 Vconst float conversion_factor = 3.3f / (1 << 12);adc_select_input(0);//设置通道2uint16_t adc_0_raw = adc_read();//读取转换通道转换结果printf("Raw1 value:%d, voltage: %f V\n", adc_0_raw,adc_0_raw * conversion_factor);}int main()
{stdio_init_all();sleep_ms(2500);printf("adc DMA test!\n");// set_sys_clock_khz(133000, true); // 325us// GPIO initialisation.gpio_init(BUILTIN_LED);gpio_set_dir(BUILTIN_LED, 1);gpio_pull_up(BUILTIN_LED);adc_init();// Init GPIO for analogue use: hi-Z, no pulls, disable digital input buffer.adc_gpio_init(26 + CAPTURE_CHANNEL);//ADC_Reading();//1983//adc_set_round_robin(ADCopen==1 ? 1 : ADCopen==2 ? 3 : ADCopen==3 ? 7 : 15);adc_select_input(CAPTURE_CHANNEL);adc_fifo_setup(true,    // Write each completed conversion to the sample FIFOtrue,    // Enable DMA data request (DREQ)1,       // DREQ (and IRQ) asserted when at least 1 sample presentfalse,   // We won't see the ERR bit because of 8 bit reads; disable.true     // Shift each sample to 8 bits when pushing to FIFO);// Divisor of 0 -> full speed. Free-running capture with the divider is// equivalent to pressing the ADC_CS_START_ONCE button once per `div + 1`// cycles (div not necessarily an integer). Each conversion takes 96// cycles, so// in general you want a divider of 0 (hold down the button// continuously) or > 95 (take samples less frequently than 96 cycle// intervals). This is all timed by the 48 MHz ADC clock.//adc_set_clkdiv((48000000/SAMPLING_FREQUENCY) - 1);adc_set_clkdiv(0);// Set up the DMA to start transferring data as soon as it appears in FIFO设置DMA,一旦数据出现在FIFO中就开始传输数据dma_chan = dma_claim_unused_channel(true);cfg = dma_channel_get_default_config(dma_chan);//获取给定通道的默认通道配置// Reading from constant address, writing to incrementing byte addresseschannel_config_set_transfer_data_size(&cfg, DMA_SIZE_16);channel_config_set_read_increment(&cfg, false);//因为就一个地址永远地写到同一个位置,目的是循环触发同一个DMA.channel_config_set_write_increment(&cfg, true);//FIFO的地址自增channel_config_set_irq_quiet(&cfg, true);//在QUIET模式下,通道不会在每个传输块结束时产生irq。channel_config_set_dreq(&cfg, DREQ_ADC); // pace data according to ADCchannel_config_set_chain_to(&cfg, dma_chan);//外设作为传输源,即ADC->DMAchannel_config_set_enable(&cfg, true);//设置DMA通道的配置,包括源地址、目的地址、传输字节数、传输方向、中断等。
//这里设置了源地址为ADC的FIFO,目的地址为streamBuffer,传输字节数为SAMPLES,传输方向为从ADC到streamBuffer,中断为DREQ_ADC。// Pace transfers based on availability of ADC samples// channel_config_set_dreq(&cfg, DREQ_ADC);dma_channel_configure(dma_chan, &cfg,(uint16_t*)sampleBuffer,   // dst 数据存储到目标缓冲区&adc_hw->fifo,  // srcSAMPLES,        // transfer count 传输数量,即采样点数true            // start immediately);
// Everything is ready to go. Tell the control channel to load the first// control block. Everything is automatic from here.dma_start_channel_mask(1u << dma_chan);// 开始传输printf("Starting capture\n");adc_run(true);// Start capturewhile (true){// Read the temperature from the onboard temperature sensor.//  float temperature = read_onboard_temperature(TEMPERATURE_UNITS);//   printf("Onboard temperature = %.02f %c\n", temperature, TEMPERATURE_UNITS);sleep_ms(1000);gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED// tight_loop_contents();measure_freqs();//ADC_Reading();// Wait for DMA to finish (may have already)dma_channel_wait_for_finish_blocking(dma_chan);// Stop and clean out FIFOadc_run(false);adc_fifo_drain();// Copy samples into buffer for approxFFT SAMPLESfor (int i = 0; i < SAMPLES; i++) {streamBuffer[i] = sampleBuffer[i];// streamBuffer[i] = (uint16_t)((sampleBuffer[i]&0x0f)<<8)+(uint16_t)sampleBuffer[i+1] ;printf("%d ",streamBuffer[i]);if (i % 10 == 9)printf("\n");// sleep_ms(100);}sleep_ms(1000);dma_channel_set_trans_count(DREQ_ADC, 10, true);//设置DMA传输的字节数,这里是10个字节,即10个采样点。// Now we have a copy of the samples we can start capture again// dma_channel_configure(dma_chan, &cfg,//                       (uint16_t*)sampleBuffer,   // dst//                       &adc_hw->fifo,  // src//                       SAMPLES,        // transfer count//                       true            // start immediately//                      );// Restart the ADC captureadc_run(true);}return 0;
}static void measure_freqs(void) {uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);printf("pll_sys  = %dkHz\n", f_pll_sys);printf("pll_usb  = %dkHz\n", f_pll_usb);printf("rosc     = %dkHz\n", f_rosc);printf("clk_sys  = %dkHz\n", f_clk_sys);printf("clk_peri = %dkHz\n", f_clk_peri);printf("clk_usb  = %dkHz\n", f_clk_usb);printf("clk_adc  = %dkHz\n", f_clk_adc);printf("clk_rtc  = %dkHz\n", f_clk_rtc);// Can't measure clk_ref / xosc as it is the ref
}

在这里插入图片描述

  • 📝ADC通过DMA方式读取12位精度代码

/*CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_ADC_DMA.elf verify reset exit"jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_ADC.elf verify reset exit"*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/divider.h"
#include "hardware/adc.h"
#include "hardware/dma.h"
#include "hardware/clocks.h"
#include "hardware/irq.h"
#define BUILTIN_LED PICO_DEFAULT_LED_PIN // LED is on the same pin as the default LED 25// Channel 0 is GPIO26
#define CAPTURE_CHANNEL 0
#define SAMPLES 10
// Ideally the signal should be bandwidth limited to sample_frequency/2
#define SAMPLING_FREQUENCY 14000 // Sampling frequency in Hzuint16_t sampleBuffer[SAMPLES];
uint16_t streamBuffer[SAMPLES]; // Scaled ADC sample working bufferdma_channel_config cfg;
int dma_chan;// const char src[] = "Hello, world! (from DMA)";
// char dst[count_of(src)];static void measure_freqs(void);void ADC_Reading(void)
{// 12-bit conversion, assume max value == ADC_VREF == 3.3 Vconst float conversion_factor = 3.3f / (1 << 12);adc_select_input(0);//设置通道2uint16_t adc_0_raw = adc_read();//读取转换通道转换结果printf("Raw1 value:%d, voltage: %f V\n", adc_0_raw,adc_0_raw * conversion_factor);}int main()
{stdio_init_all();sleep_ms(2500);printf("adc DMA test!\n");// set_sys_clock_khz(133000, true); // 325us// GPIO initialisation.gpio_init(BUILTIN_LED);gpio_set_dir(BUILTIN_LED, 1);gpio_pull_up(BUILTIN_LED);adc_init();// Init GPIO for analogue use: hi-Z, no pulls, disable digital input buffer.adc_gpio_init(26 + CAPTURE_CHANNEL);//ADC_Reading();//1983//adc_set_round_robin(ADCopen==1 ? 1 : ADCopen==2 ? 3 : ADCopen==3 ? 7 : 15);adc_select_input(CAPTURE_CHANNEL);adc_fifo_setup(true,    // Write each completed conversion to the sample FIFOtrue,    // Enable DMA data request (DREQ)1,       // DREQ (and IRQ) asserted when at least 1 sample presentfalse,   // We won't see the ERR bit because of 8 bit reads; disable.//Shift each sample to 8 bits when pushing to FIFO [true] Changed to false for 12bit valuesfalse     // Shift each sample to 8 bits when pushing to FIFO);// Divisor of 0 -> full speed. Free-running capture with the divider is// equivalent to pressing the ADC_CS_START_ONCE button once per `div + 1`// cycles (div not necessarily an integer). Each conversion takes 96// cycles, so// in general you want a divider of 0 (hold down the button// continuously) or > 95 (take samples less frequently than 96 cycle// intervals). This is all timed by the 48 MHz ADC clock.//adc_set_clkdiv((48000000/SAMPLING_FREQUENCY) - 1);adc_set_clkdiv(0);// Set up the DMA to start transferring data as soon as it appears in FIFO设置DMA,一旦数据出现在FIFO中就开始传输数据dma_chan = dma_claim_unused_channel(true);cfg = dma_channel_get_default_config(dma_chan);//获取给定通道的默认通道配置// Reading from constant address, writing to incrementing byte addresseschannel_config_set_transfer_data_size(&cfg, DMA_SIZE_16);channel_config_set_read_increment(&cfg, false);//因为就一个地址永远地写到同一个位置,目的是循环触发同一个DMA.channel_config_set_write_increment(&cfg, true);//FIFO的地址自增
//新增channel_config_set_irq_quiet(&cfg, true);//在QUIET模式下,通道不会在每个传输块结束时产生irq。channel_config_set_dreq(&cfg, DREQ_ADC); // pace data according to ADCchannel_config_set_chain_to(&cfg, dma_chan);//外设作为传输源,即ADC->DMAchannel_config_set_enable(&cfg, true);//设置DMA通道的配置,包括源地址、目的地址、传输字节数、传输方向、中断等。
//这里设置了源地址为ADC的FIFO,目的地址为streamBuffer,传输字节数为SAMPLES,传输方向为从ADC到streamBuffer,中断为DREQ_ADC。// Pace transfers based on availability of ADC samples// channel_config_set_dreq(&cfg, DREQ_ADC);dma_channel_configure(dma_chan, &cfg,sampleBuffer,   // dst (uint16_t*)数据存储到目标缓冲区&adc_hw->fifo,  // srcSAMPLES,        // transfer count 传输数量,即采样点数true            // start immediately);
// Everything is ready to go. Tell the control channel to load the first// control block. Everything is automatic from here.dma_start_channel_mask(1u << dma_chan);// 开始传输printf("Starting capture\n");adc_run(true);// Start capturewhile (true){// Read the temperature from the onboard temperature sensor.//  float temperature = read_onboard_temperature(TEMPERATURE_UNITS);//   printf("Onboard temperature = %.02f %c\n", temperature, TEMPERATURE_UNITS);sleep_ms(1000);gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED// tight_loop_contents();measure_freqs();//ADC_Reading();// Wait for DMA to finish (may have already)dma_channel_wait_for_finish_blocking(dma_chan);// Stop and clean out FIFOadc_run(false);adc_fifo_drain();// Copy samples into buffer for approxFFT SAMPLESfor (int i = 0; i < SAMPLES; i++) {// streamBuffer[i] = sampleBuffer[i]/4 - 512 + 49; // The +49 compensated for a slight DC offset from VCC/2// streamBuffer[i] = sampleBuffer[i];// streamBuffer[i] = (uint16_t)((sampleBuffer[i]&0x0f)<<8)+(uint16_t)sampleBuffer[i+1] ;printf("%-3d ",sampleBuffer[i]);if (i % 10 == 9)printf("\n");// sleep_ms(100);}// SUM_VALUE/=SAMPLES;// printf("SUM_VALUE = %d\n",SUM_VALUE);// SUM_VALUE = 0;sleep_ms(1000);// dma_channel_set_trans_count(DREQ_ADC, 10, true);//设置DMA传输的字节数,这里是10个字节,即10个采样点。//Now we have a copy of the samples we can start capture againdma_channel_configure(dma_chan, &cfg,(uint16_t*)sampleBuffer,   // dst&adc_hw->fifo,  // srcSAMPLES,        // transfer counttrue            // start immediately);// Restart the ADC captureadc_run(true);}return 0;
}static void measure_freqs(void) {uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY);uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY);uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC);uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI);uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB);uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC);uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC);printf("pll_sys  = %dkHz\n", f_pll_sys);printf("pll_usb  = %dkHz\n", f_pll_usb);printf("rosc     = %dkHz\n", f_rosc);printf("clk_sys  = %dkHz\n", f_clk_sys);printf("clk_peri = %dkHz\n", f_clk_peri);printf("clk_usb  = %dkHz\n", f_clk_usb);printf("clk_adc  = %dkHz\n", f_clk_adc);printf("clk_rtc  = %dkHz\n", f_clk_rtc);// Can't measure clk_ref / xosc as it is the ref
}

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com