非DMA,连续转换,扫描模式,双通道

This commit is contained in:
dufresne 2025-09-13 18:04:22 +08:00
parent 0a2a72d64a
commit a134a33ed5
4 changed files with 49 additions and 112 deletions

View File

@ -4,6 +4,8 @@
"drv_usart.h": "c", "drv_usart.h": "c",
"rtservice.h": "c", "rtservice.h": "c",
"gd32f4xx_adc.h": "c", "gd32f4xx_adc.h": "c",
"drv_adc.h": "c" "drv_adc.h": "c",
"gd32f4xx.h": "c",
"gd32f4xx_dma.h": "c"
} }
} }

View File

@ -42,6 +42,7 @@ OF SUCH DAMAGE.
float voltage; float voltage;
float current; float current;
float current_origin; float current_origin;
float adc_value;
/*! /*!
\brief main function \brief main function
@ -60,9 +61,9 @@ int main(void)
{ {
// voltage = ptz_Voltage_collect_adc1_task(); // voltage = ptz_Voltage_collect_adc1_task();
// current = ptz_Current_collect_adc1_task(); // current = ptz_Current_collect_adc1_task();
ptz_adc1_collect_task(); adc_value = ptz_adc1_collect_task();
current_origin = current*0.132 + 3.3/2; // current_origin = current*0.132 + 3.3/2;
rt_thread_mdelay(500); rt_thread_mdelay(500);
// 主循环代码... // 主循环代码...
} }

View File

@ -7,10 +7,12 @@
#include "rtthread.h" #include "rtthread.h"
/* 自定义宏,方便修改通道和引脚 */
uint16_t buff[2] = {0}; void init_data_collect_module(void)
float curadc[ADC_CHANNEL_NUM]; {
adc_gpio_config();
adc_config();
}
void adc_gpio_config(void) void adc_gpio_config(void)
{ {
@ -19,110 +21,60 @@ void adc_gpio_config(void)
/* 启用ADC0时钟 */ /* 启用ADC0时钟 */
rcu_periph_clock_enable(RCU_ADC1); rcu_periph_clock_enable(RCU_ADC1);
adc_clock_config(ADC_ADCCK_PCLK2_DIV4);
/* 配置ADC引脚为模拟输入模式 */ /* 配置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, VOLTAGE_ADC_PIN);
gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, CURRENT_ADC_PIN); gpio_mode_set(ADC_GPIO_PORT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, CURRENT_ADC_PIN);
} }
void adc_config(void) void adc_config(void)
{ {
/* ########## ADC 基础配置 ########## */
// 复位ADC配置可选但建议初始化时做一次 // 复位ADC配置可选但建议初始化时做一次
adc_deinit(); adc_deinit();
// 配置数据对齐方式为右对齐 // 配置数据对齐方式为右对齐
adc_data_alignment_config(TEST, ADC_DATAALIGN_RIGHT); adc_data_alignment_config(ADCX, ADC_DATAALIGN_RIGHT);
// 配置ADC分辨率12位 // 配置ADC分辨率12位
adc_resolution_config(TEST, ADC_RESOLUTION_12B); adc_resolution_config(ADCX, ADC_RESOLUTION_12B);
/* ########## 设置转换通道序列 ########## */ /* ########## 设置转换通道序列 ########## */
// 配置规则序列的长度2个通道 // 配置规则序列的长度2个通道
// adc_channel_length_config(TEST, ADC_INSERTED_CHANNEL, 2); adc_channel_length_config(ADCX, ADC_ROUTINE_CHANNEL, ADC_CHANNEL_NUM);
adc_channel_length_config(TEST, ADC_ROUTINE_CHANNEL, ADC_CHANNEL_NUM);
// 配置规则序列序号0是电压通道序号1是电流通道 // 配置规则序列序号0是电压通道序号1是电流通道
adc_routine_channel_config(ADCX, 0, VOLTAGE_ADC_CHANNEL, ADC_SAMPLETIME_480);
adc_routine_channel_config(TEST, 0, VOLTAGE_ADC_CHANNEL, ADC_SAMPLETIME_480); adc_routine_channel_config(ADCX, 1, CURRENT_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_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); adc_special_function_config(ADCX, ADC_CONTINUOUS_MODE, ENABLE);
// DMA
adc_dma_request_after_last_enable(ADC0);
adc_dma_mode_enable(ADC0);
/* ########## 其他设置 ########## */
// 使能外部触发:这里使用软件触发,所以先禁用硬件触发 // 使能外部触发:这里使用软件触发,所以先禁用硬件触发
adc_external_trigger_config(TEST, ADC_ROUTINE_CHANNEL, DISABLE); adc_external_trigger_config(ADCX, ADC_ROUTINE_CHANNEL, DISABLE);
// adc_external_trigger_config(TEST, ADC_INSERTED_CHANNEL, DISABLE);
// 开启ADC // 开启ADC
adc_enable(TEST); adc_enable(ADCX);
// 等待ADC稳定 // 等待ADC稳定
rt_thread_mdelay(100); rt_thread_mdelay(100);
// 执行ADC自校准 // 执行ADC自校准
adc_calibration_enable(TEST); adc_calibration_enable(ADCX);
adc_clock_config(ADC_ADCCK_PCLK2_DIV4); // 软件触发使能
adc_software_trigger_enable(ADCX, ADC_ROUTINE_CHANNEL);
adc_software_trigger_enable(TEST, 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采集 // adc采集
float ptz_adc1_collect_task() float ptz_adc1_collect_task()
@ -130,28 +82,18 @@ float ptz_adc1_collect_task()
// static float adc1_v[LB_TIMES]; // static float adc1_v[LB_TIMES];
// static float curadc1_out; // static float curadc1_out;
// static uint8_t adc1_num = 0; // static uint8_t adc1_num = 0;
// int j,k; int j,k;
// float tem; float tem;
// float curadc1; float curadc1;
// uint16_t value_V = 0; uint16_t value_V = 0;
while(adc_flag_get(ADCX, ADC_FLAG_EOC) == RESET); // 等待转换结束
value_V = adc_routine_data_read(ADCX); // 读取规则组数据寄存器
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); // 读取规则组数据寄存器
// ... 后面的中位值平均滤波处理保持不变 ... // ... 后面的中位值平均滤波处理保持不变 ...
// *11硬件需要 // *11硬件需要
// adc1_v[adc1_num] = (float)value_V / 4096.0 * 3.3; // 间接测量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 快速清零 // memset(adc1_v, 0, sizeof(adc1_v));//adc1_v 快速清零
// curadc1_out = curadc1; // curadc1_out = curadc1;
// } // }
// return curadc1_out; // return curadc1_out;
return curadc1;
} }
// //电流采集 // //电流采集
@ -194,15 +138,15 @@ float ptz_adc1_collect_task()
// float curadc0; // float curadc0;
// uint16_t value_I; // uint16_t value_I;
// adc_software_trigger_enable(TEST,ADC_ROUTINE_CHANNEL); // adc_software_trigger_enable(ADCX,ADC_ROUTINE_CHANNEL);
// // adc_software_trigger_enable(TEST,ADC_INSERTED_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_routine_data_read(ADCX); // 读取规则组数据寄存器
// // value_I = adc_inserted_data_read(TEST, CURRENT_ADC_CHANNEL); // 读取规则组数据寄存器 // // 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 ++; // adc0_num ++;
// if(adc0_num >= LB_TIMES) // 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();
}

View File

@ -1,19 +1,16 @@
#ifndef __DRV_ADC_H_ #ifndef __DRV_ADC_H_
#define __DRV_ADC_H_ #define __DRV_ADC_H_
#define TEST ADC1 /* 自定义宏,方便修改通道和引脚 */
#define ADCX ADC1
#define VOLTAGE_ADC_CHANNEL ADC_CHANNEL_12 #define VOLTAGE_ADC_CHANNEL ADC_CHANNEL_12
#define CURRENT_ADC_CHANNEL ADC_CHANNEL_13 #define CURRENT_ADC_CHANNEL ADC_CHANNEL_13
#define ADC_GPIO_PORT GPIOC #define ADC_GPIO_PORT GPIOC
#define VOLTAGE_ADC_PIN GPIO_PIN_2 #define VOLTAGE_ADC_PIN GPIO_PIN_2
#define CURRENT_ADC_PIN GPIO_PIN_3 #define CURRENT_ADC_PIN GPIO_PIN_3
#define ADC_CHANNEL_NUM 2 // 规则组通道数量 #define ADC_CHANNEL_NUM 2 // 规则组配置规则序列的通道2个通道
#define LB_TIMES 5 #define LB_TIMES 5
extern float curadc[ADC_CHANNEL_NUM];
// float ptz_Voltage_collect_adc1_task(); // float ptz_Voltage_collect_adc1_task();
// float ptz_Current_collect_adc1_task(); // float ptz_Current_collect_adc1_task();
float ptz_adc1_collect_task(); float ptz_adc1_collect_task();