本帖最后由 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);// 软件触发一次
}
}
|