打印

GD32F10X库,ADC0+DMA0单次,供参考

[复制链接]
67|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Drencin|  楼主 | 2025-3-12 13:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Drencin 于 2025-3-12 21:02 编辑

#每日话题#
如题,使用GD32F103RGT6,主频108M,常规ADC+DMA系列操作
uint16_t adc_buf[5]; // 每个通道对应一个数组
void adc_dma_init(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_ADC0);         
    rcu_periph_clock_enable(RCU_AF);
    rcu_periph_clock_enable(RCU_TIMER1);
    rcu_periph_clock_enable(DMA0);
    gpio_init(GPIOA,GPIO_MODE_AIN,GPIO_OSPEED_50MHZ,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4);//PA0~PA4 ADC
        
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV16);


    adc_deinit(ADC0);
    adc_mode_config(ADC_MODE_FREE);// 自由运行模式
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);// 禁止连续模式,否则会停在AD0
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 5);
    for (uint8_t i = 0; i < 5; i++)// 配置规则序列
    { adc_regular_channel_config(ADC0, i + 1, ADC_CHANNEL_0 + i, ADC_SAMPLETIME_239POINT5); }
    adc_dma_mode_enable(ADC0);
    adc_enable(ADC0);
    delay_1ms(1);
    adc_calibration_enable(ADC0);

    dma_parameter_struct dma_init_struct;
    dma_deinit(DMA0, DMA_CH0);
    dma_init_struct.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
    dma_init_struct.memory_addr = (uint32_t)(&adc_buf);//数组名即为首地址
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;// 方向是从外设到内存
    dma_init_struct.number = 5;// 每次传输一个样本
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;// 外设地址不递增
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;// 内存地址递增
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.priority = DMA_PRIORITY_HIGH;
    dma_init(DMA0, DMA_CH0, &dma_init_struct);// 初始化DMA0
    dma_circulation_disable(DMA0,DMA_CH0);// 单次模式解决错位痛点
    dma_channel_enable(DMA0, DMA_CH0);// 使能DMA
    adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);// 软件触发一次
}


void TIMER1_IRQHandler(void) // 每2.5mS中断一次        
{
    if(timer_interrupt_flag_get(TIMER1,TIMER_INT_FLAG_UP)== SET)
    {
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
        dma_channel_disable(DMA0, DMA_CH0);// 禁能DMA,否则重启动不灵
        dma_interrupt_flag_clear(DMA0, DMA_CH0, DMA_INT_FLAG_FTF);
        dma_channel_enable(DMA0, DMA_CH0);// 使能DMA
        adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);// 软件触发一次
    }
}



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

5

帖子

0

粉丝