You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Pico 2 ADC最大采样:替换ADS1263的代码修改咨询

树莓派Pico 2 ADC采样代码改造(适配原ADS1263逻辑)

需求对应

原Python代码核心逻辑:

  • 持续监听串口,收到start指令后启动ADC采样
  • 采样过程中仅记录与上一次不同的ADC值到缓冲区
  • 采样最长持续0.4秒,或收到stop指令立即停止
  • 采样结束后将缓冲区数据通过串口发送,随后等待下一次start指令

以下是基于Pico SDK改造main.c的具体实现:

改造步骤与代码实现

1. 引入必要头文件与定义常量

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "hardware/uart.h"

// 配置参数
#define ADC_CHANNEL 0          // 对应原代码的采样通道0
#define MAX_SAMPLE_DURATION_US 400000  // 最长采样时长0.4秒
#define BUFFER_SIZE 200000     // 缓冲区大小(适配500kSPS最大采样量)
#define UART_ID uart0          // 使用UART0通信
#define BAUD_RATE 115200
#define UART_TX_PIN 0
#define UART_RX_PIN 1

2. 初始化外设

void init_peripherals() {
    // 初始化UART
    uart_init(UART_ID, BAUD_RATE);
    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
    uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);

    // 初始化ADC(配置最高500kSPS采样率)
    adc_init();
    adc_gpio_init(26 + ADC_CHANNEL);  // ADC通道0对应GPIO26
    adc_select_input(ADC_CHANNEL);
    adc_set_clkdiv(0);  // 关闭时钟分频,对应48MHz ADC时钟,达到500kSPS采样率
}

3. 串口指令接收函数

// 从UART读取指令,返回是否匹配目标指令
bool check_command(const char *target) {
    static char rx_buf[10];
    static int rx_idx = 0;

    while (uart_is_readable(UART_ID)) {
        char c = uart_getc(UART_ID);
        if (c == '\n' || c == '\r') {
            rx_buf[rx_idx] = '\0';
            bool match = strcmp(rx_buf, target) == 0;
            rx_idx = 0;
            return match;
        } else if (rx_idx < sizeof(rx_buf)-1) {
            rx_buf[rx_idx++] = c;
        }
    }
    return false;
}

4. 主逻辑实现

int main() {
    stdio_init_all();
    init_peripherals();

    int32_t buffer[BUFFER_SIZE];
    int buf_idx = 0;
    int32_t last_value = -1;  // 初始值设为无效值,确保第一个采样被记录

    while (true) {
        // 等待start指令
        while (!check_command("start")) {
            tight_loop_contents();
        }

        // 重置采样状态
        buf_idx = 0;
        last_value = -1;
        absolute_time_t start_time = get_absolute_time();
        bool running = true;

        // 采样循环
        while (running) {
            // 检查超时
            if (absolute_time_diff_us(start_time, get_absolute_time()) >= MAX_SAMPLE_DURATION_US) {
                running = false;
                continue;
            }

            // 检查stop指令
            if (check_command("stop")) {
                running = false;
                continue;
            }

            // 读取ADC值并去重存入缓冲区
            int32_t current_value = adc_read();
            if (current_value != last_value && buf_idx < BUFFER_SIZE) {
                buffer[buf_idx++] = current_value;
                last_value = current_value;
            }
        }

        // 发送缓冲区数据
        uart_puts(UART_ID, "DATA_START\n");
        for (int i = 0; i < buf_idx; i++) {
            char val_str[10];
            snprintf(val_str, sizeof(val_str), "%d\n", buffer[i]);
            uart_puts(UART_ID, val_str);
        }
        uart_puts(UART_ID, "DATA_END\n");
    }

    return 0;
}

关键说明

  • 采样率保证:通过adc_set_clkdiv(0)配置ADC最高采样率(500kSPS),轮询读取方式在RP2350上可满足速率要求;若需更稳定采样,可改用定时器中断触发ADC采样。
  • 指令处理:check_command函数支持换行/回车作为指令结束符,避免指令截断。
  • 缓冲区安全:设置足够大的缓冲区并加入边界检查,防止数据溢出。

内容的提问来源于stack exchange,提问作者Marianna Kalwat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 13:05:02