From a134a33ed5082892f48d6e1ed50af4eeab06371e Mon Sep 17 00:00:00 2001 From: dufresne <1625800082@qq.com> Date: Sat, 13 Sep 2025 18:04:22 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9D=9EDMA=EF=BC=8C=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=EF=BC=8C=E6=89=AB=E6=8F=8F=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E5=8F=8C=E9=80=9A=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 4 +- applications/main/main.c | 7 +- drivers/drv_adc.c | 141 +++++++++++---------------------------- drivers/drv_adc.h | 9 +-- 4 files changed, 49 insertions(+), 112 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index dd889a0..8ce71ce 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,8 @@ "drv_usart.h": "c", "rtservice.h": "c", "gd32f4xx_adc.h": "c", - "drv_adc.h": "c" + "drv_adc.h": "c", + "gd32f4xx.h": "c", + "gd32f4xx_dma.h": "c" } } \ No newline at end of file diff --git a/applications/main/main.c b/applications/main/main.c index e1f8b9f..3e35bc2 100644 --- a/applications/main/main.c +++ b/applications/main/main.c @@ -42,6 +42,7 @@ OF SUCH DAMAGE. float voltage; float current; float current_origin; +float adc_value; /*! \brief main function @@ -60,9 +61,9 @@ int main(void) { // voltage = ptz_Voltage_collect_adc1_task(); // current = ptz_Current_collect_adc1_task(); - ptz_adc1_collect_task(); - - current_origin = current*0.132 + 3.3/2; + adc_value = ptz_adc1_collect_task(); + + // current_origin = current*0.132 + 3.3/2; rt_thread_mdelay(500); // 主循环代码... } diff --git a/drivers/drv_adc.c b/drivers/drv_adc.c index c489a6e..3c84776 100644 --- a/drivers/drv_adc.c +++ b/drivers/drv_adc.c @@ -7,10 +7,12 @@ #include "rtthread.h" -/* 自定义宏,方便修改通道和引脚 */ -uint16_t buff[2] = {0}; -float curadc[ADC_CHANNEL_NUM]; +void init_data_collect_module(void) +{ + adc_gpio_config(); + adc_config(); +} void adc_gpio_config(void) { @@ -19,110 +21,60 @@ void adc_gpio_config(void) /* 启用ADC0时钟 */ rcu_periph_clock_enable(RCU_ADC1); + adc_clock_config(ADC_ADCCK_PCLK2_DIV4); + + /* 配置ADC引脚为模拟输入模式 */ gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, VOLTAGE_ADC_PIN); gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, CURRENT_ADC_PIN); } + + void adc_config(void) { - /* ########## ADC 基础配置 ########## */ // 复位ADC配置(可选,但建议初始化时做一次) adc_deinit(); // 配置数据对齐方式为右对齐 - adc_data_alignment_config(TEST, ADC_DATAALIGN_RIGHT); + adc_data_alignment_config(ADCX, ADC_DATAALIGN_RIGHT); // 配置ADC分辨率:12位 - adc_resolution_config(TEST, ADC_RESOLUTION_12B); + adc_resolution_config(ADCX, ADC_RESOLUTION_12B); /* ########## 设置转换通道序列 ########## */ // 配置规则序列的长度:2个通道 - // adc_channel_length_config(TEST, ADC_INSERTED_CHANNEL, 2); - adc_channel_length_config(TEST, ADC_ROUTINE_CHANNEL, ADC_CHANNEL_NUM); + adc_channel_length_config(ADCX, ADC_ROUTINE_CHANNEL, ADC_CHANNEL_NUM); // 配置规则序列:序号0是电压通道,序号1是电流通道 - - adc_routine_channel_config(TEST, 0, VOLTAGE_ADC_CHANNEL, ADC_SAMPLETIME_480); - adc_routine_channel_config(TEST, 1, CURRENT_ADC_CHANNEL, ADC_SAMPLETIME_480); - - // adc_inserted_channel_config(TEST, 0, CURRENT_ADC_CHANNEL,ADC_SAMPLETIME_480);//电流 - // adc_inserted_channel_config(TEST, 1, VOLTAGE_ADC_CHANNEL,ADC_SAMPLETIME_480);//电压 + adc_routine_channel_config(ADCX, 0, VOLTAGE_ADC_CHANNEL, ADC_SAMPLETIME_480); + adc_routine_channel_config(ADCX, 1, CURRENT_ADC_CHANNEL, ADC_SAMPLETIME_480); // 打开扫描模式 - adc_special_function_config(TEST, ADC_SCAN_MODE, ENABLE); + adc_special_function_config(ADCX, ADC_SCAN_MODE, ENABLE); // 禁止连续模式 -> 单次转换模式 - adc_special_function_config(TEST, ADC_CONTINUOUS_MODE, DISABLE); - - // DMA - adc_dma_request_after_last_enable(ADC0); - adc_dma_mode_enable(ADC0); + adc_special_function_config(ADCX, ADC_CONTINUOUS_MODE, ENABLE); - - /* ########## 其他设置 ########## */ // 使能外部触发:这里使用软件触发,所以先禁用硬件触发 - adc_external_trigger_config(TEST, ADC_ROUTINE_CHANNEL, DISABLE); - // adc_external_trigger_config(TEST, ADC_INSERTED_CHANNEL, DISABLE); + adc_external_trigger_config(ADCX, ADC_ROUTINE_CHANNEL, DISABLE); // 开启ADC - adc_enable(TEST); + adc_enable(ADCX); // 等待ADC稳定 rt_thread_mdelay(100); // 执行ADC自校准 - adc_calibration_enable(TEST); + adc_calibration_enable(ADCX); - adc_clock_config(ADC_ADCCK_PCLK2_DIV4); - - adc_software_trigger_enable(TEST, ADC_ROUTINE_CHANNEL); + // 软件触发使能 + adc_software_trigger_enable(ADCX, ADC_ROUTINE_CHANNEL); } -static void DMA_config() -{ - uint32_t dmax = DMA1; - uint32_t dmax_rcu = RCU_DMA1; - uint32_t dmax_ch = DMA_CH0; - uint32_t damx_sub = DMA_SUBPERI0; - uint32_t dmax_dirction = DMA_PERIPH_TO_MEMORY; - uint32_t dmax_src = (uint32_t)(&ADC_RDATA(ADC1)); - uint32_t dmax_src_inc = DMA_PERIPH_INCREASE_DISABLE; - uint32_t dmax_src_width = DMA_PERIPH_WIDTH_16BIT; - uint32_t dmax_src_len = 2; - uint32_t dmax_dst = (uint32_t)(buff); - uint32_t dmax_dst_inc = DMA_MEMORY_INCREASE_ENABLE; - /**************** DMA p2m *******************/ - // 时钟 - rcu_periph_clock_enable(dmax_rcu); - // 重置dma - dma_deinit(dmax, dmax_ch); - //////// dma 配置 - dma_single_data_parameter_struct dsdps; - dma_single_data_para_struct_init(&dsdps); - // 方向 - dsdps.direction = DMA_PERIPH_TO_MEMORY; - // 内存: dst - dsdps.memory0_addr = dmax_dst; - dsdps.memory_inc = dmax_dst_inc; - // 外设: src - dsdps.periph_addr = dmax_src; - dsdps.periph_inc = dmax_src_inc; - // 数据长度 - dsdps.number = dmax_src_len; - // dst数据宽度 - dsdps.periph_memory_width = dmax_src_width; - // 传输优先级 - dsdps.priority = DMA_PRIORITY_ULTRA_HIGH; - dma_single_data_mode_init(dmax, dmax_ch, &dsdps); - //////// 配置 dma 子连接 - dma_channel_subperipheral_select(dmax, dmax_ch, damx_sub); - dma_circulation_enable(dmax, dmax_ch); - // 默认开启接收 - dma_flag_clear(dmax, dmax_ch, DMA_FLAG_FTF); - dma_channel_enable(dmax, dmax_ch); -} + + // adc采集 float ptz_adc1_collect_task() @@ -130,28 +82,18 @@ float ptz_adc1_collect_task() // static float adc1_v[LB_TIMES]; // static float curadc1_out; // static uint8_t adc1_num = 0; - // int j,k; - // float tem; - // float curadc1; - // uint16_t value_V = 0; + int j,k; + float tem; + float curadc1; + uint16_t value_V = 0; - - - uint16_t value = buff[0]; - curadc[0] = (float)buff[0] / 4096.0 * 3.3; - curadc[1] = (float)buff[1] / 4096.0 * 3.3; - - //软件触发使能 - // adc_software_trigger_enable(TEST, ADC_ROUTINE_CHANNEL); - // adc_software_trigger_enable(TEST, ADC_INSERTED_CHANNEL); - - // while(adc_flag_get(TEST, ADC_FLAG_EOC) == RESET); // 等待转换结束 - // value_V = adc_routine_data_read(TEST); // 读取规则组数据寄存器 - // value_V = adc_inserted_data_read(TEST, VOLTAGE_ADC_CHANNEL); // 读取规则组数据寄存器 + while(adc_flag_get(ADCX, ADC_FLAG_EOC) == RESET); // 等待转换结束 + value_V = adc_routine_data_read(ADCX); // 读取规则组数据寄存器 // ... 后面的中位值平均滤波处理保持不变 ... // *11,硬件需要 // adc1_v[adc1_num] = (float)value_V / 4096.0 * 3.3; // 间接测量,11倍分压/放大 + curadc1 = (float)value_V / 4095.0 * 3.3; // 间接测量,11倍分压/放大 // ... @@ -180,7 +122,9 @@ float ptz_adc1_collect_task() // memset(adc1_v, 0, sizeof(adc1_v));//adc1_v 快速清零 // curadc1_out = curadc1; // } + // return curadc1_out; + return curadc1; } // //电流采集 @@ -194,15 +138,15 @@ float ptz_adc1_collect_task() // float curadc0; // uint16_t value_I; -// adc_software_trigger_enable(TEST,ADC_ROUTINE_CHANNEL); -// // adc_software_trigger_enable(TEST,ADC_INSERTED_CHANNEL); +// adc_software_trigger_enable(ADCX,ADC_ROUTINE_CHANNEL); +// // adc_software_trigger_enable(ADCX,ADC_INSERTED_CHANNEL); -// // while(adc_flag_get(TEST, ADC_FLAG_EOC) == RESET); // 等待转换结束 +// // while(adc_flag_get(ADCX, ADC_FLAG_EOC) == RESET); // 等待转换结束 -// value_I = adc_routine_data_read(TEST); // 读取规则组数据寄存器 -// // value_I = adc_inserted_data_read(TEST, CURRENT_ADC_CHANNEL); // 读取规则组数据寄存器 +// value_I = adc_routine_data_read(ADCX); // 读取规则组数据寄存器 +// // value_I = adc_inserted_data_read(ADCX, CURRENT_ADC_CHANNEL); // 读取规则组数据寄存器 -// adc1_i[adc0_num] = (((float)value_I / 4096.0 * 3.3)-3.3/2) / 0.132;//(float)value_I;// +// adc1_i[adc0_num] = (((float)value_I / 4095.0 * 3.3)-3.3/2) / 0.132;//(float)value_I;// // adc0_num ++; // if(adc0_num >= LB_TIMES) @@ -232,10 +176,3 @@ float ptz_adc1_collect_task() // } - -void init_data_collect_module(void) -{ - adc_gpio_config(); - adc_config(); - DMA_config(); -} diff --git a/drivers/drv_adc.h b/drivers/drv_adc.h index 73ff474..f450e50 100644 --- a/drivers/drv_adc.h +++ b/drivers/drv_adc.h @@ -1,19 +1,16 @@ #ifndef __DRV_ADC_H_ #define __DRV_ADC_H_ -#define TEST ADC1 +/* 自定义宏,方便修改通道和引脚 */ +#define ADCX ADC1 #define VOLTAGE_ADC_CHANNEL ADC_CHANNEL_12 #define CURRENT_ADC_CHANNEL ADC_CHANNEL_13 #define ADC_GPIO_PORT GPIOC #define VOLTAGE_ADC_PIN GPIO_PIN_2 #define CURRENT_ADC_PIN GPIO_PIN_3 -#define ADC_CHANNEL_NUM 2 // 规则组通道数量 +#define ADC_CHANNEL_NUM 2 // 规则组配置规则序列的通道:2个通道 #define LB_TIMES 5 - -extern float curadc[ADC_CHANNEL_NUM]; - - // float ptz_Voltage_collect_adc1_task(); // float ptz_Current_collect_adc1_task(); float ptz_adc1_collect_task();