题目8:ADC采集与DAC输出

以下是针对 题目8:ADC采集与DAC输出 的详细实现方案,包含流程图和图形化展示:


流程图

DAC输出
ADC配置
触发
循环
DAC输出波形
正弦波/三角波
ADC多通道扫描
ADC1_CH0: 光敏电阻
ADC1_CH1: 电位器
DMA传输数据
数据缓冲区
信号处理

硬件连接

模块STM32引脚功能
光敏电阻PA0ADC1_IN0
电位器PA1ADC1_IN1
DAC输出PA4DAC1_OUT1
示波器/万用表PA4观测输出波形

步骤1:配置ADC多通道扫描+DMA

1.1 STM32CubeMX配置
  1. ADC1设置
    • Mode: Scan Conversion Mode(扫描模式)
    • Continuous Conversion Mode: Enabled
    • DMA Continuous Requests: Enabled
    • Number of Conversions: 2
    • Rank 1: Channel 0 (PA0), Sampling Time: 15 Cycles
    • Rank 2: Channel 1 (PA1), Sampling Time: 15 Cycles
  2. DMA配置
    • Mode: Circular
    • Data Width: Half Word(匹配ADC的12位分辨率)
1.2 关键代码
// ADC初始化(CubeMX生成)
MX_ADC1_Init();
MX_DMA_Init();

// 启动ADC+DMA传输
uint16_t adc_buffer[2]; // 存储双通道数据
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, 2);

步骤2:生成DAC波形

2.1 正弦波查表法
// 生成正弦波表(256点,12位分辨率)
#define WAVE_SIZE 256
uint16_t sine_wave[WAVE_SIZE];
for (int i = 0; i < WAVE_SIZE; i++) {
    sine_wave[i] = (uint16_t)(2048 * (1 + sin(2 * M_PI * i / WAVE_SIZE))); // 0~4095
}
2.2 DAC+DMA输出
// DAC初始化(CubeMX配置PA4为DAC_OUT1)
MX_DAC_Init();
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)sine_wave, WAVE_SIZE, DAC_ALIGN_12B_R);

步骤3:动态调整波形(基于ADC输入)

// 在ADC转换完成回调中调整波形频率
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
    uint16_t light_value = adc_buffer[0]; // 光敏电阻值
    uint16_t pot_value = adc_buffer[1];   // 电位器值

    // 根据电位器值调整波形频率
    float freq = 100 + (pot_value / 4095.0f) * 1000; // 100Hz~1100Hz
    update_dac_frequency(freq);
}

// 更新DAC输出频率(通过调整DMA传输速度)
void update_dac_frequency(float freq) {
    uint32_t update_rate = SystemCoreClock / (WAVE_SIZE * freq);
    hdac.DMA_Handle->Instance->CNDTR = WAVE_SIZE;
    hdac.DMA_Handle->Instance->CPAR = (uint32_t)&(DAC->DHR12R1);
    hdac.DMA_Handle->Instance->CMAR = (uint32_t)sine_wave;
    hdac.DMA_Handle->Instance->CCR |= DMA_CCR_EN; // 重启DMA
}

图形化信号流

ADC信号输入                 DMA传输                DAC输出
  ┌───────┐              ┌──────────┐          ┌──────────┐
  │  PA0  │─光敏电阻─→│ ADC1_IN0 │──DMA─→│  RAM缓冲区 │─→┐
  └───────┘              └──────────┘          └──────────┘  │
  ┌───────┐              ┌──────────┐                        │
  │  PA1  │─电位器──→│ ADC1_IN1 │──DMA─→│  RAM缓冲区 │─→┤
  └───────┘              └──────────┘          └──────────┘  │
                                                             ↓
                                                      ┌──────────────┐
                                                      │DAC1_OUT(PA4)│→ 波形
                                                      └──────────────┘

关键配置参数

模块参数
ADC时钟频率12MHz
采样时间15 Cycles
分辨率12-bit
DAC触发源TIM6 TRGO
输出缓冲Disabled
DMA传输模式Circular
数据对齐Right-aligned

常见问题与解决

  1. ADC采样值不稳定

    • 增加RC滤波电路(PA0对地并联0.1μF电容)
    • 软件均值滤波:adc_value = (adc_buffer[0] + adc_buffer[1]) / 2
  2. DAC输出波形失真

    • 检查DMA传输是否溢出(HAL_DMA_GetState()
    • 确保查表数据对齐(12位右对齐:DAC_ALIGN_12B_R
  3. 系统时钟冲突

    • 确认ADC/DAC时钟源与主频分频比匹配
    • 使用独立时钟源(如APB1用于DAC,APB2用于ADC)

扩展功能

  1. 双缓冲DMA

    // 定义双缓冲区
    uint16_t wave_buf1[256], wave_buf2[256];
    HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)wave_buf1, 256, DAC_ALIGN_12B_R);
    // DMA传输完成中断中切换缓冲区
    void HAL_DAC_DMAConvCpltCallback(DAC_HandleTypeDef* hdac) {
        static uint8_t buf_idx = 0;
        buf_idx ^= 1;
        HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, 
            (uint32_t*)(buf_idx ? wave_buf1 : wave_buf2), 256, DAC_ALIGN_12B_R);
    }
    
  2. 实时波形生成

    // 在DMA传输中实时计算三角波
    void generate_triangle_wave(uint16_t *buf, uint32_t len) {
        for (uint32_t i = 0; i < len; i++) {
            buf[i] = (i % 256) * 16; // 0~4095线性变化
        }
    }
    

通过此方案,可实现高速ADC信号采集与DAC波形合成的闭环系统,适用于音频处理、闭环控制等场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值