RP2040 C SDK ADC功能使用

news2025/1/1 18:58:34

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_ADC
        pico_stdlib
        hardware_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 25

static void measure_freqs(void);


void ADC_Reading(void)
{
    // 12-bit conversion, assume max value == ADC_VREF == 3.3 V
        const 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 etc
    adc_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 V
        const float conversion_factor = 3.3f / (1 << 12);
          adc_select_input(2);//设置通道2
        uint16_t adc_2_raw = adc_read();//读取转换通道转换结果
        adc_select_input(3);//设置通道3
        uint16_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 中断模式读取

ADC中断模式读取通道0(GPIO26)数据,数据存储模式和ADC DMA采集方式相同,需要建立一个ADC_FIFO缓冲区来存储。


/*
 CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_Test.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_Test.elf verify reset exit"

    ADC通道:0 - 3  =》 ADC0 - ADC3  GPIO26 - GPIO29
    4通道A内部温度

*/

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/uart.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

bool adc_irq_flag = false;
volatile uint16_t level;

#define SAMPLES 5
// Ideally the signal should be bandwidth limited to sample_frequency/2
#define SAMPLING_FREQUENCY 14000 // Sampling frequency in Hz

volatile  uint16_t sampleBuffer[SAMPLES];//ADC FIFO
static void ADC_IRQ_FIFO_Callback(void)
{
    level = adc_fifo_get_level();
    while (level-- > 0)
    {
        sampleBuffer[level] = adc_fifo_get();

    }
    adc_irq_flag = true;

}

void adc()
{
    adc_init();
    adc_gpio_init(26);
    //  adc_set_clkdiv(0); // 125kHz ADC clock
    // adc_set_temp_sensor_enabled(true);
    adc_select_input(0);
    //  adc_set_round_robin(0x0f); // ADC0, ADC1, ADC2, ADC3
    adc_set_round_robin(0b1);
    const uint32_t clock_hz = clock_get_hz(clk_adc);
    const uint32_t target_hz = 500;
    const float divider = 1.0f * clock_hz / target_hz;
    adc_set_clkdiv(divider);
 //adc_set_clkdiv((48000000/SAMPLING_FREQUENCY) - 1);
    //   sleep_ms(1000);
    irq_set_priority(ADC_IRQ_FIFO, PICO_HIGHEST_IRQ_PRIORITY); // Set the priority of the ADC IRQ
    irq_set_enabled(ADC_IRQ_FIFO, true);                       // Enable the ADC IRQ
    adc_fifo_setup(
        true,  // Write each completed conversion to the sample FIFO
        false, // Enable DMA data request (DREQ)
        SAMPLES,     // DREQ (and IRQ) asserted when at least 1 sample present
        false, // 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 values
        false // Shift each sample to 8 bits when pushing to FIFO
    );
    irq_set_exclusive_handler(ADC_IRQ_FIFO, ADC_IRQ_FIFO_Callback); // Set the callback function for the ADC IRQ
    adc_irq_set_enabled(true);
//    adc_fifo_drain();
    adc_run(true);
}

int main()
{
    stdio_init_all();
    uart_init(uart0, 115200); // 115200 baud
    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();
    while (true)
    { // Loop forever
        sleep_ms(1000);
        gpio_xor_mask(1ul << BUILTIN_LED); // Toggle the LED
        if (adc_irq_flag)
        {

    for (size_t  i = 0; i < SAMPLES; i++)
    {
       printf("  [%u]: %u", i, sampleBuffer[i]);
        if (i % SAMPLES == 4)
            printf("\n");
    }

            adc_irq_flag = false;
            //  sleep_ms(1000);
        }
    }

    return 0;
}

在这里插入图片描述

  • 🌿在RP2040 IRQ中断配置项:
  • 🔖中断优先级设置
  • 🔖中断回调函数设置。
  • 🔖在运行内核上开启对应中断。(irq_set_enabled
  • 🔖使能对应外设IRQ中断。
     irq_set_priority(ADC_IRQ_FIFO, PICO_HIGHEST_IRQ_PRIORITY); // Set the priority of the ADC IRQ
    irq_set_exclusive_handler(ADC_IRQ_FIFO, ADC_IRQ_FIFO_Callback);
    irq_set_enabled(ADC_IRQ_FIFO, true); // Enable the ADC IRQ.IRQ在执行核心上启用/禁用多个中断
    adc_irq_set_enabled(true); // Enable the ADC IRQ.

📓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 FIFO
        true,    // Enable DMA data request (DREQ)
        1,       // DREQ (and IRQ) asserted when at least 1 sample present
        false,   // 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 values
        true// 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 FIFO
        true,    // Enable DMA data request (DREQ)
        1,       // DREQ (and IRQ) asserted when at least 1 sample present
        false,   // 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 values
        false     // 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 Hz

uint16_t sampleBuffer[SAMPLES];
uint16_t streamBuffer[SAMPLES]; // Scaled ADC sample working buffer

dma_channel_config cfg;
int dma_chan;


static void measure_freqs(void);


void ADC_Reading(void)
{

    // 12-bit conversion, assume max value == ADC_VREF == 3.3 V
        const float conversion_factor = 3.3f / (1 << 12);
          adc_select_input(0);//设置通道2
        uint16_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 FIFO
        true,    // Enable DMA data request (DREQ)
        1,       // DREQ (and IRQ) asserted when at least 1 sample present
        false,   // 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 addresses
  channel_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 ADC
    channel_config_set_chain_to(&cfg, dma_chan);//外设作为传输源,即ADC->DMA
    channel_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,  // src
                        SAMPLES,        // 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 capture

    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();
        //ADC_Reading();
        // Wait for DMA to finish (may have already)
  dma_channel_wait_for_finish_blocking(dma_chan);

  // Stop and clean out FIFO
  adc_run(false);
  adc_fifo_drain();
  // Copy samples into buffer for approxFFT SAMPLES
  for (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 capture
  adc_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 Hz

uint16_t sampleBuffer[SAMPLES];
uint16_t streamBuffer[SAMPLES]; // Scaled ADC sample working buffer

dma_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 V
        const float conversion_factor = 3.3f / (1 << 12);
          adc_select_input(0);//设置通道2
        uint16_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 FIFO
        true,    // Enable DMA data request (DREQ)
        1,       // DREQ (and IRQ) asserted when at least 1 sample present
        false,   // 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 values
        false     // 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 addresses
  channel_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 ADC
    channel_config_set_chain_to(&cfg, dma_chan);//外设作为传输源,即ADC->DMA
    channel_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,  // src
                        SAMPLES,        // 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 capture

    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();
        //ADC_Reading();
        // Wait for DMA to finish (may have already)
  dma_channel_wait_for_finish_blocking(dma_chan);

  // Stop and clean out FIFO
  adc_run(false);
  adc_fifo_drain();
  // Copy samples into buffer for approxFFT SAMPLES
  for (int i = 0; i < SAMPLES; i++) {

    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 again
  dma_channel_configure(dma_chan, &cfg,
                        (uint16_t*)sampleBuffer,   // dst
                        &adc_hw->fifo,  // src
                        SAMPLES,        // transfer count
                        true            // start immediately
                       );

  // Restart the ADC capture
  adc_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 IRQ方式读取

通过DMA中断方式读取ADC采集数据。


/*
 CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_ADC_DMA_IRQ.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_ADC_DMA_IRQ.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 Hz

uint16_t sampleBuffer[SAMPLES];
uint16_t streamBuffer[SAMPLES]; // Scaled ADC sample working buffer

dma_channel_config cfg;
volatile int dma_chan;

volatile bool dma_done = false; // Flag to indicate DMA transfer is complete

// 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 V
        const float conversion_factor = 3.3f / (1 << 12);
          adc_select_input(0);//设置通道2
        uint16_t adc_0_raw = adc_read();//读取转换通道转换结果
        printf("Raw1 value:%d, voltage: %f V\n", adc_0_raw,adc_0_raw * conversion_factor);

}

void dma_handler() {

    dma_done = true;
      // Stop and clean out FIFO
  adc_run(false);
  adc_fifo_drain();

//   Clear the interrupt request.
  dma_hw->ints0 = 1u << dma_chan; // Clear the interrupt request.

   // dma_channel_set_read_addr(dma_chan, &sampleBuffer, true);
  //  dma_channel_set_trans_count(dma_chan, SAMPLES, true);


}

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 FIFO
        true,    // Enable DMA data request (DREQ)
        1,       // DREQ (and IRQ) asserted when at least 1 sample present
        false,   // 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 values
        false     // 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 addresses
  channel_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_irq_quiet(&cfg, false);在非QUIET模式下,通道在每个传输块结束时产生irq。

  // Tell the DMA to raise IRQ line 0 when the channel finishes a block
dma_channel_set_irq0_enabled(dma_chan, true);
     // Configure the processor to run dma_handler() when DMA IRQ 0 is asserted
    irq_set_exclusive_handler(DMA_IRQ_0, dma_handler);
    irq_set_enabled(DMA_IRQ_0, true);

    channel_config_set_dreq(&cfg, DREQ_ADC); // pace data according to ADC
    channel_config_set_chain_to(&cfg, dma_chan);//外设作为传输源,即ADC->DMA
    channel_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,  // src
                        SAMPLES,        // 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 capture

    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();
        //ADC_Reading();
        // Wait for DMA to finish (may have already)
 // dma_channel_wait_for_finish_blocking(dma_chan);

if (dma_done) {
    dma_done = false;
    // Stop and clean out FIFO
    adc_run(false);
    adc_fifo_drain();
    // Read the ADC samples from the DMA channel

  for (int i = 0; i < SAMPLES; i++) {

    printf("%-3d ",sampleBuffer[i]);
     if (i % 10 == 9)
            printf("\n");
   // sleep_ms(100);

  }
    //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 capture
  adc_run(true);
}
  sleep_ms(1000);

    }

    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
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2140607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

建筑资质与劳务资质的区别

在建筑行业&#xff0c;资质就像是企业的“身份证”&#xff0c;它证明了企业具备承接相应工程的能力和条件。对于刚入行的小白来说&#xff0c;可能会对建筑资质和劳务资质的区别感到困惑。别担心&#xff0c;今天我们就来聊聊这两者之间的不同。 什么是建筑资质&#xff1f; …

git push : RPC failed; HTTP 400 curl 22 The requested URL returned error: 400

git push 出现RPC failed; HTTP 400 curl 22 The requested URL returned error: 400 问题 git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (10/10), done. error: RPC …

分布式训练:(Pytorch)

分布式训练是将机器学习模型的训练过程分散到多个计算节点或设备上&#xff0c;以提高训练速度和效率&#xff0c;尤其是在处理大规模数据和模型时。分布式训练主要分为数据并行和模型并行两种主要策略&#xff1a; 1. 数据并行 (Data Parallelism) 数据并行是最常见的分布式…

数据结构之树的常用术语

二叉树的常用术语 前言 由于数组在插入、删除上的缺点和链表在查询上的缺点&#xff0c;出现了树的数据结构&#xff0c;可以在增删改查中弥补数组和链表的缺陷。 常用数据 节点&#xff1a;每个节点根节点&#xff1a;最上层的节点&#xff0c;Root节点父节点&#xff1a;相…

基于SSM的宿舍管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的宿舍管理系统拥有两种角色&#xff0c;分别为管理员和宿管&#xff0c;具体功能如下&#xff1a; 管理员&#xff1a;学生管理、班级管理、宿舍管理、卫生管理、访客管理、用户…

SOT23封装1A电流LDO具有使能功能的 1A、低 IQ、高精度、低压降稳压器系列TLV757P

前言 SOT23-5封装的外形和丝印 该LDO适合PCB空间较小的场合使用&#xff0c;多数SOT23封装的 LDO输出电流不超过0.5A。建议使用时输入串联二极管1N4001,PCB布局需要考虑散热&#xff0c;参考文末PCB布局。 1 特性 • 采用 SOT-23 (DYD) 封装&#xff0c;具有 60.3C/W RθJA •…

双指针算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 想要了解双指针算法的介绍&#xff0c;可以去看下面的博客&#xff1a;双指针算法的介绍 目录 611.有效三角形的个数 LCR 1…

【天池比赛】【零基础入门金融风控 Task2赛题理解】实战进行中……20240915更新至2.3.4.3 查看训练集测试集中特征属性只有一值的特征

2.3 代码示例 2.3.1 导入数据分析及可视化过程需要的库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import datetime import warnings warnings.filterwarnings(ignore) 2.3.2 读取文件 #读取数据时相对路径载入报错时…

【Redis】之Geo

概述 Geo就是Geolocation的简写形式&#xff0c;代表地理坐标。在Redis中&#xff0c;构造了能够存储地址坐标信息的一种数据结构&#xff0c;帮助我们根据经纬度来检索数据。 命令行操作方法 GEOADD 可以用来添加一个或者多个地理坐标。 GEODIST 返回一个key中两个成员之…

AgentTuning:提升大型语言模型的通用Agent能力

人工智能咨询培训老师叶梓 转载标明出处 大模型被用作现实中复杂任务的Agent时&#xff0c;它们的表现往往不如商业模型&#xff0c;如ChatGPT和GPT-4。这些任务要求LLMs作为中央控制器&#xff0c;负责规划、记忆和工具利用&#xff0c;这就需要精巧的提示方法和鲁棒性强的LL…

华为的仓颉和ArkTS这两门语言有什么区别

先贴下官网&#xff1a; ArkTs官网 仓颉官网 ArkTS的官网介绍说&#xff0c;ArkTS是TypeScript的进一步强化版本&#xff0c;简单来说就是包含了TS的风格&#xff0c;但是做了一些改进。 了解TypeScript的朋友都应该知道&#xff0c;其实TypeScript就是JavaScript的改进版本&…

基于springboot 自习室预订系统 前后端分离

基于springboot 自习室预订系统 前后端分离 目 录 摘 要 I Abstract II 第1章 前 言 2 1.1 研究背景 3 1.2 研究现状 3 1.3 系统开发目标 3 第2章 系统开发环境 5 2.1 java技术 5 2.2 Mysql数据库 6 2.3 B/S结构 7 2.4 springboot框架 7 2.5 ECLIPSE 开发环境 7 …

Redis的配置与优化

目录 一、关系数据库与非关系型数据库 1.1、关系型数据库 1.2、非关系型数据库 1.3、关系型数据库和非关系型数据库区别 数据存储方式不同 扩展方式不同 对事务性的支持不同 1.4、非关系型数据库产生背景 二、Redis简介 2.1、Redis优点 2.2、Redis为什么这么快 三、…

CefSharp_Vue交互(Element UI)_WinFormWeb应用---设置应用透明度(含示例代码)

一、界面预览 1.1 设置透明(整个页面透明80%示例) 限制输入值:10-100(数字太小会不好看见) 1.2 vue标题栏 //注册类与js调用 (async function(

速通汇编(五)认识段地址与偏移地址,CS、IP寄存器和jmp指令,DS寄存器

一&#xff0c;地址的概念 通常所说的地址指的是某内存单元在整个机器内存中的物理地址&#xff0c;把整个机器内存比作一个酒店&#xff0c;内存单元就是这个酒店的各个房间&#xff0c;给这些房间编的门牌号&#xff0c;类比回来就是内存单元的物理地址 在第一篇介绍debug的…

Scratch植物大战僵尸【机器人vs外星人版本】

小虎鲸Scratch资源站-免费少儿编程Scratch作品源码,素材,教程分享网站! 简介 在这个教学案例中&#xff0c;我们将制作一个类似《植物大战僵尸》的Scratch游戏&#xff0c;主题为“机器人对抗外星人”。这个版本将采用创新的角色设计&#xff0c;机器人将保护地球免受外星人入…

SQL题目分析:打折日期交叉问题--计算品牌总优惠天数

在电商平台的数据分析中&#xff0c;处理品牌促销活动的日期交叉问题是一个挑战。本文将介绍几种高级SQL技巧&#xff0c;用于准确计算每个品牌的总优惠天数&#xff0c;即使在存在日期交叉的情况下。 问题背景 我们有一个促销活动表 shop_discount&#xff0c;记录了不同品牌…

算法:76.最小覆盖子串

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;滑动窗口&#xff09; 还是老样子&#xff0c;连续问题&#xff0c;滑动窗口哈希表 令t用的hash表为hash1&#xff0c;s用的hash表为hash2 利用hash表统计窗口内的个字符出现的个数&#xff0c;与hash1进行比较 选…

SpringBoot 消息队列RabbitMQ在代码中声明 交换机 与 队列使用注解创建

创建Fanout交换机 Configuration public class FanoutConfig {Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("csdn.fanout");//交换机名称} }创建队列 Beanpublic Queue fanoutQueue3(){return new Queue("csdn.queue");}绑定…

Nature Climate Change | 全球土壤微生物群落调控微生物呼吸对变暖的敏感性(Q10)

本文首发于“生态学者”微信公众号&#xff01; 全球变暖将加速有机物分解&#xff0c;从而增加土壤中二氧化碳的释放&#xff0c;触发正的碳-气候反馈。这种反馈的大小在很大程度上取决于有机质分解的温度敏感性(Q10)。Q10仍然是围绕土壤碳排放到大气的预测的主要不确定性来源…