From 441153ec102cb190cee9452ae6f1e65734a02aac Mon Sep 17 00:00:00 2001 From: dufresne <1625800082@qq.com> Date: Thu, 18 Sep 2025 18:05:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E7=8B=AC=E5=B0=81=E8=A3=85=E6=BB=A4?= =?UTF-8?q?=E6=B3=A2=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- applications/main/main.c | 19 ++++-- drivers/drv_adc.c | 143 +++++++++++++++++++-------------------- drivers/drv_adc.h | 51 +++++++++++--- 3 files changed, 121 insertions(+), 92 deletions(-) diff --git a/applications/main/main.c b/applications/main/main.c index 2d51c2c..8eea169 100644 --- a/applications/main/main.c +++ b/applications/main/main.c @@ -44,7 +44,6 @@ OF SUCH DAMAGE. float voltage; float current; float current_origin; -float adc_value; char tiedian_id[3]={0}; #ifdef MDAX @@ -149,14 +148,17 @@ int main(void) rt_thread_mdelay(250); #endif - // voltage = ptz_Voltage_collect_adc1_task(); - // rt_thread_mdelay(500); + #ifndef ADC_MODE_2 + voltage = ptz_Voltage_collect_adc1_task(); + rt_thread_mdelay(500); - // current = ptz_Current_collect_adc1_task(); - // rt_thread_mdelay(500); + current = ptz_Current_collect_adc1_task(); + rt_thread_mdelay(500); + #endif + #ifdef ADC_MODE_2 adc_software_trigger_enable(ADCX, SEQUENCE_CHANNEL);// 软件触发使能 后续接读取 - + #endif //测试mb铁电读写 read_mb_id((uint8_t*)&tiedian_id);//读取铁电ID @@ -208,6 +210,8 @@ void DMA1_Channel0_IRQHandler(void) #endif + +#ifdef ADCX_IRQn void ADC_IRQHandler() { if(adc_interrupt_flag_get(ADCX, ADC_INT_FLAG_EOC)) { @@ -218,4 +222,5 @@ void ADC_IRQHandler() adc_interrupt_flag_clear(ADCX, ADC_INT_FLAG_EOC); // 处理传输完成 } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/drivers/drv_adc.c b/drivers/drv_adc.c index 7136e76..0b1d134 100644 --- a/drivers/drv_adc.c +++ b/drivers/drv_adc.c @@ -20,6 +20,14 @@ uint16_t USER_ADC_DMA_DATA_BUFF[16] = {0}; uint32_t ctl = 0; #endif +bool filter_v_flag = 0;//滤波开启标志位,全局改变一次 +bool filter_i_flag = 0;//滤波开启标志位,全局改变一次 +bool filter_t_flag = 0;//滤波开启标志位,全局改变一次 + + + +/* ---------------------------------------------------配置---------------------------------------------------- */ + void adc_init(void) { adc_rcu_config(); @@ -30,7 +38,11 @@ void adc_init(void) #endif adc_config(); + + #ifdef ADCX_IRQn adc_interrupt_int(); + #endif + #ifdef DMAX ctl = DMA_CHCTL(DMAX, USER_DMA_ADC_CHANNEL); if (ctl == 33762576) @@ -171,25 +183,25 @@ void adc_config(void) #endif } +#ifdef ADCX_IRQn void adc_interrupt_int(void) { adc_interrupt_enable (ADCX, ADC_INT_EOC); nvic_irq_enable (ADCX_IRQn, ADCX_PRIORITY_PRE, ADCX_PRIORITY_SUB); } +#endif -/* ---------------------------------------------------------------------------------------------------------------- */ +/* ---------------------------------------------------采集---------------------------------------------------- */ // adc电压采集 float ptz_Voltage_collect_adc1_task() { static float adc1_v[LB_V_TIMES]; static float curadc1_out_v; - static uint8_t adc1_v_num; - int j,k; - float tem; - float curadc1; + static uint8_t adc1_v_num = 0; uint16_t value_V = 0; + if (SEQUENCE_CHANNEL == ADC_ROUTINE_CHANNEL) { adc_routine_channel_config(ADCX, 0, VOLTAGE_ADC_CHANNEL, ADC_SAMPLETIME_480); @@ -215,28 +227,15 @@ float ptz_Voltage_collect_adc1_task() if(adc1_v_num >= LB_V_TIMES) { adc1_v_num = 0; - for(j = 0; j < LB_V_TIMES-1; j++)// 采样值由小到大排列 - { - for(k = 0; k < LB_V_TIMES-j-1; k++) - { - if(adc1_v[k] > adc1_v[k+1]) - { - tem = adc1_v[k]; - adc1_v[k] = adc1_v[k+1]; - adc1_v[k+1] = tem; - } - } - } - for(uint8_t i = LB_V_DEL; i < LB_V_TIMES - LB_V_DEL; i++) - { - curadc1 = curadc1 + adc1_v[i]; - } - curadc1 = curadc1 /((float)(LB_V_TIMES - LB_V_DEL * 2));// 去掉一个最大值和一个最小值求平均值 - // g_ptz.Voltage = curadc1; - memset(adc1_v, 0, sizeof(adc1_v));// adc1_v 快速清零 - curadc1_out_v = curadc1; + filter_v_flag = 1; } - return curadc1_out_v; + + if (filter_v_flag) + { + return Filtering(adc1_v, LB_V_TIMES, LB_V_DEL); + } + + return 0; } @@ -245,10 +244,7 @@ float ptz_Current_collect_adc1_task() { static float adc1_i[LB_I_TIMES]; static float curadc1_out_i; - static uint8_t adc1_i_num; - int j,k; - float tem; - float curadc1; + static uint8_t adc1_i_num = 0; uint16_t value_I = 0; if (SEQUENCE_CHANNEL == ADC_ROUTINE_CHANNEL) { @@ -277,28 +273,14 @@ float ptz_Current_collect_adc1_task() if(adc1_i_num >= LB_I_TIMES) { adc1_i_num = 0; - for(j = 0; j < LB_I_TIMES-1; j++)//采样值由小到大排列 - { - for(k = 0; k < LB_I_TIMES-j-1; k++) - { - if(adc1_i[k] > adc1_i[k+1]) - { - tem = adc1_i[k]; - adc1_i[k] = adc1_i[k+1]; - adc1_i[k+1] = tem; - } - } - } - for(uint8_t i = LB_I_DEL; i < LB_I_TIMES - LB_I_DEL; i++) - { - curadc1 = curadc1 + adc1_i[i]; - } - curadc1 = curadc1 /((float)(LB_I_TIMES - LB_I_DEL * 2));//去掉一个最大值和一个最小值求平均值 - // g_ptz.Voltage = curadc1; - memset(adc1_i, 0, sizeof(adc1_i));//adc1_i 快速清零 - curadc1_out_i = curadc1; + filter_i_flag = 1; } - return curadc1_out_i; + + if (filter_i_flag) + { + return Filtering(adc1_i, LB_I_TIMES, LB_I_DEL); + } + return 0; } @@ -308,34 +290,47 @@ float ptz_temperature_collect_tmp75_task() static float tmp75[5]; static unsigned char tmp75_num; static float curtmp75_out; - float curtmp75; - float tem; - int j,k; + tmp75[tmp75_num] = tmp75_read_temp(); tmp75_num ++; if(tmp75_num >= LB_T_TIMES) { tmp75_num = 0; - for(j = 0; j < LB_T_TIMES-1; j++)//采样值由小到大排列 - { - for(k = 0; k < LB_T_TIMES-j-1; k++) - { - if(tmp75[k] > tmp75[k+1]) - { - tem = tmp75[k]; - tmp75[k] = tmp75[k+1]; - tmp75[k+1] = tem; - } - } - } - for(uint8_t i = 1; i < LB_T_TIMES - 1; i++) - { - curtmp75 = curtmp75 + tmp75[i];//去掉一个最大值和一个最小值 - } - curtmp75 = curtmp75 / ((float)(LB_T_TIMES - 2)); - curtmp75_out = curtmp75; - memset(tmp75, 0, sizeof(tmp75)); + filter_t_flag = 1; } - return curtmp75_out; + if (filter_t_flag) + { + return Filtering(tmp75, LB_T_TIMES, LB_T_DEL); + } + return 0; } + + +float Filtering(float *filter, uint8_t filterlens, uint8_t filterdel) +{ + uint8_t j,k; + float tem; + float curadc = 0; + + for(j = 0; j < filterlens - 1; j++)// 采样值由小到大排列 + { + for(k = 0; k < filterlens - j - 1; k++) + { + if(filter[k] > filter[k + 1]) + { + tem = filter[k]; + filter[k] = filter[k + 1]; + filter[k + 1] = tem; + } + } + } + + for(uint8_t i = filterdel; i < filterlens - filterdel; i++) + { + curadc = curadc + filter[i]; + } + curadc = curadc / ((float)(filterlens - filterdel * 2));// 去掉一个最大值和一个最小值求平均值 + return curadc; +} + diff --git a/drivers/drv_adc.h b/drivers/drv_adc.h index 10c04cd..396c1a4 100644 --- a/drivers/drv_adc.h +++ b/drivers/drv_adc.h @@ -3,11 +3,12 @@ #include "tmp75.h" #include "stdlib.h" +#include "stdbool.h" #include "string.h" #include "gd32f4xx.h" #include "gd32f4xx_adc.h" #include "gd32f4xx_dma.h" -// #include "rtthread.h" +#include "rtthread.h" /* 自定义宏,方便修改通道和引脚 */ #define ADCX ADC1 @@ -16,23 +17,46 @@ #define ADC_GPIO_PORT GPIOC #define VOLTAGE_ADC_PIN GPIO_PIN_2 #define CURRENT_ADC_PIN GPIO_PIN_3 -#define LB_V_TIMES 7 //电压采样滤波次数 -#define LB_I_TIMES 12 //电流采样滤波次数 -#define LB_T_TIMES 7 //温度采样滤波次数 -#define LB_V_DEL 1 //电压滤波最高最低各删除个数 -#define LB_I_DEL 2 //电流滤波最高最低各删除个数 +#define LB_V_TIMES 7 //电压采样滤波次数 +#define LB_I_TIMES 12 //电流采样滤波次数 +#define LB_T_TIMES 7 //温度采样滤波次数 +#define LB_V_DEL 1 //电压滤波最高最低各删除个数 +#define LB_I_DEL 2 //电流滤波最高最低各删除个数 +#define LB_T_DEL 1 //温度滤波最高最低各删除个数 + +#define ADC_MODE_0 //规则组、单次转换、非扫描 +// #define ADC_MODE_1 //注入组、单次转换、扫描、转换结束标志位采集 +// #define ADC_MODE_2 //注入组、单次转换、扫描、中断转换结束标志位采集 /* adc模式配置参数 ENABLE DISABLE */ +#ifdef ADC_MODE_0 #define CONTINUOUS_STATUS DISABLE // 是否开启连续转换 -// #define SEQUENCE_CHANNEL ADC_ROUTINE_CHANNEL // 注入组还是规则组 -#define SEQUENCE_CHANNEL ADC_INSERTED_CHANNEL // 注入组还是规则组 +#define SEQUENCE_CHANNEL ADC_ROUTINE_CHANNEL // 规则组 +// #define SEQUENCE_CHANNEL ADC_INSERTED_CHANNEL // 注入组 +#define SCAN_STATUS DISABLE // 是否开启扫描模式 +#define CHANNEL_LENGTH 1 // 通道数量:1~16 +#endif + +#ifdef ADC_MODE_1 +#define CONTINUOUS_STATUS DISABLE // 是否开启连续转换 +// #define SEQUENCE_CHANNEL ADC_ROUTINE_CHANNEL // 规则组 +#define SEQUENCE_CHANNEL ADC_INSERTED_CHANNEL // 注入组 #define SCAN_STATUS ENABLE // 是否开启扫描模式 #define CHANNEL_LENGTH 2 // 通道数量:1~16 +#endif +#ifdef ADC_MODE_2 +#define CONTINUOUS_STATUS DISABLE // 是否开启连续转换 +// #define SEQUENCE_CHANNEL ADC_ROUTINE_CHANNEL // 规则组 +#define SEQUENCE_CHANNEL ADC_INSERTED_CHANNEL // 注入组 +#define SCAN_STATUS ENABLE // 是否开启扫描模式 +#define CHANNEL_LENGTH 2 // 通道数量:1~16 +#define ADCX_IRQn ADC_IRQn +#endif /* adc dma */ @@ -56,19 +80,24 @@ adc模式配置参数 #endif -#define ADCX_IRQn ADC_IRQn + +#ifdef ADCX_IRQn #define ADCX_PRIORITY_PRE 2U //抢占优先级 #define ADCX_PRIORITY_SUB 0U //子优先级 - +#endif void adc_init(void); void adc_rcu_config(void); void adc_gpio_config(void); void adc_config(void); -void adc_interrupt_int(void); float ptz_Voltage_collect_adc1_task(); float ptz_Current_collect_adc1_task(); float ptz_temperature_collect_tmp75_task(); +float Filtering(float *filter, uint8_t filterlens, uint8_t filterdel); + +#ifdef ADCX_IRQn +void adc_interrupt_int(void); +#endif #ifdef DMAX void adc_dma_config(void);