#include #include "ADC.h" #include "gd32e23x.h" #include "SysTick.h" #include "Timer.h" #include "math.h" #include "common.h" #include "IM1253E.h" uint32_t DCPDU_Iin_Zero = 0; uint32_t DCPDU_Win_Zero = 0; bool adc_data_ok_flag = false; bool Init_IM1253E_flag = false; bool Start_Read_Flag = false; bool IM1253E_OK_flag = false; bool Read_IM1253E_flag = false; #define UART1_BUF_SIZE 64 extern unsigned char u8_TX_Length; extern unsigned char RX_Length; extern unsigned char u8_RX_Index; extern unsigned char B_Rx_Data_ING; extern unsigned char B_Rx_Finish; extern unsigned char u8_RxBuf[UART1_BUF_SIZE]; uint8_t adc_sample_n; //采样次数 #if SUPPORT_2_V_GA_CHN uint16_t adc_original_value[ADC_CH_N+ADC_V_CHN]={0}; uint16_t adc_calc_value[ADC_Avg_N][ADC_CH_N+ADC_V_CHN]; uint32_t adc_Avg_value[ADC_CH_N+ADC_V_CHN]; extern uint16_t adc_data_zero[ADC_CH_N+ADC_V_CHN]; #else uint16_t adc_original_value[ADC_CH_N]={0}; uint16_t adc_calc_value[ADC_Avg_N][ADC_CH_N]; uint32_t adc_Avg_value[ADC_CH_N]; extern uint16_t adc_data_zero[ADC_CH_N]; #endif #if SUPPORT_2_V_GA_CHN uint16_t adc_data_zero[ADC_CH_N+ADC_V_CHN]= {0}; #else uint16_t adc_data_zero[ADC_CH_N]= {0}; #endif void Init_ADC(void) { board_t *board = get_board(); adc_sample_n = 0; ConfigADCGPIO(); while(!dma_flag_get(DMA_CH0,DMA_FLAG_FTF)); dma_flag_clear(DMA_CH0,DMA_FLAG_FTF); for(int i = 0;i < 8;i++) { adc_data_zero[i] = 0x149; } #if (SUPPORT_IM1253E == 0) #if SUPPORT_ADC_GATHER_V adc_data_zero[ADC_VOL] = adc_original_value[ADC_VOL] = 0x01; #endif #else Init_IM1253E_flag = true; uint8_t temp1 = 0; uint8_t temp2 = 0; uint32_t temp0 = 0; while(Init_IM1253E_flag) { if(Read_IM1253E_flag) { Read_IM1253E_flag = false; Read_IM1253E_REG(Device_addr_IM1253E,V_REG_ADDR,8);//Device_addr_IM1253E } if(B_Rx_Finish) { uint32_t temp_da[8] = {0}; B_Rx_Finish = false; for(int j = 0;j < 8;j++) { temp_da[j] = 0; for(int i = 0;i < 4;i++) { temp1 = 8 * i; temp1 = 24 - temp1; temp2 = 4 * j; temp2 += 3; temp2 += i; temp0 = u8_RxBuf[temp2] << temp1; temp_da[j] += temp0; } } DCPDU_Iin_Zero = temp_da[1] / 10; DCPDU_Win_Zero = temp_da[2] / 10; board->md_data.r_data.input.voltage = temp_da[0] / 10; for(int i = 0;i < RelaySlaveChaNum;i++) { board->md_data.r_data.output[i].voltage = board->md_data.r_data.input.voltage; } Init_IM1253E_flag = false; IM1253E_OK_flag = true; } } #endif } void ConfigADCGPIO(void) { //使能RCU相关时钟 rcu_periph_clock_enable(ADC_0_5_RCU); //使能GPIOA的时钟 rcu_periph_clock_enable(ADC_67_RCU); //使能GPIOB的时钟 //使能ADC时钟 rcu_periph_clock_enable(RCU_ADC); //使能DMA的时钟 rcu_periph_clock_enable(RCU_DMA); //配置ADC时钟 rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); //设置GPIO为ADC接口 #if SUPPORT_2_V_GA_CHN gpio_mode_set(ADC_0_5_IO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_ch0|ADC_ch1|ADC_ch2|ADC_ch3|ADC_ch4|ADC_ch5|ADC_Vol_ch1|ADC_Vol_ch2); #else gpio_mode_set(ADC_0_5_IO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_ch0|ADC_ch1|ADC_ch2|ADC_ch3|ADC_ch4|ADC_ch5); #endif gpio_mode_set(ADC_67_IO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_ch6|ADC_ch7); //复位ADC外设 adc_deinit(); //配置DMA ADC_dma_config(); //内部ADC配置 adc_special_function_config(ADC_SCAN_MODE,ENABLE); //配置ADC扫描转换模式 adc_special_function_config(ADC_CONTINUOUS_MODE,ENABLE); //配置ADC连续转换模式 adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_NONE); //配置ADC外部触发是软件触发 adc_data_alignment_config(ADC_DATAALIGN_RIGHT); //配置ADC数据对齐方式是右对齐 adc_resolution_config(ADC_RESOLUTION_12B); //配置ADC为12位 #if SUPPORT_2_V_GA_CHN adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_CH_N+ADC_V_CHN); adc_regular_channel_config(8U, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(9U, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5); #else adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_CH_N); //配置ADC规则通道组成或注入通道组的长度,因为用到8个通道,所以是8 #endif adc_regular_channel_config(0U, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(1U, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(2U, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(3U, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(4U, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(5U, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(6U, ADC_CHANNEL_8, ADC_SAMPLETIME_55POINT5); adc_regular_channel_config(7U, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5); adc_enable(); adc_enable(); //delay_ms(2); adc_calibration_enable(); //校准复位 adc_dma_mode_enable(); //使能DMA adc_software_trigger_enable(ADC_REGULAR_CHANNEL); //软件触发 adc_software_trigger_enable(ADC_REGULAR_CHANNEL); //dma_interrupt_enable(DMA_CH0,DMA_INT_FTF); } void ADC_dma_config(void) { //通道参数配置 dma_parameter_struct dma_data_parameter; //使能ADC时钟 rcu_periph_clock_enable(RCU_ADC); //使能DMA的时钟 rcu_periph_clock_enable(RCU_DMA); //复位DMA通道 dma_deinit(DMA_CH0); //初始化DMA为单数据模式 dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA); //设置DMA外设地址,也是DMA数据传输的源地址,ADC单次采样转换结束后,会将数据存入ADC_RDATA地址中 dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; //设置DMA数据传输的源地址自增算法取消,ADC每次转换后数据存入地址不变 dma_data_parameter.memory_addr = (uint32_t)(adc_original_value); //设置DMA存储器地址,也是DMA数据传输的目标地址 dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //设置DMA数据传输目标地址自增算法使能,因为DMA每个周期需要传送八个数据,所以在一个周期内,目标地址要自增 dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; //设置DMA从外设中读出数据的位数,因为ADC转换后的数值是12位,用16位数值表示,所以这里设置为1字 dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT; //设置DMA存入存储器的数据位数 dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY; //设置DMA的数据传输方向 #if SUPPORT_2_V_GA_CHN dma_data_parameter.number = ADC_CH_N + ADC_V_CHN; #else dma_data_parameter.number = ADC_CH_N; //设置DMA一个周期要传输的数据个数,用了8个通道的ADC,所以在一个周期内要传输8个数据 #endif dma_data_parameter.priority = DMA_PRIORITY_HIGH; //设置DMA数据传输高优先级 dma_circulation_enable(DMA_CH0); //DMA循环模式使能,这样DMA在传输8个数据后,存储地址复位,自动开启下一轮传输 dma_init(DMA_CH0, &dma_data_parameter); //初始化DMA dma_memory_to_memory_disable(DMA_CH0); //这里用不上,所以存储器到存储器DMA传输取消 dma_channel_enable(DMA_CH0); //使能DMA通道 } uint32_t DC_I_calfunction(uint16_t da,uint8_t channel) { uint32_t temp_i = 0; uint32_t temp_v = 0; if(da > 0) { switch(channel) { #if SPPPORT_BIG_HAL case 0: case 1: case 4: case 5: { temp_v = da; if(da < 0xA) { temp_v = 0; } temp_v *= ADC_Vref; temp_v *= 1000; temp_v = temp_v >> 12; temp_v *= 2.5; temp_i = temp_v; temp_i /= 10;//去掉第3位小数 temp_i *= 10; //temp_i += 200; if(temp_i <= 80) temp_i = 0; } break; #endif default: { temp_v = da; temp_v *= ADC_Vref; temp_v *= 1000; temp_v = temp_v >> 12;//temp_v /= ADC_Fulscale; temp_v /= A_gain; temp_i = temp_v / I_sens; temp_i /= 10;//去掉第3位小数 temp_i *= 10; //temp_i += 70; if(temp_i <= 200) temp_i = 0; } } return temp_i; } else { return 0; } } static uint16_t sort_buff[ADC_CH_N][ADC_Avg_N] = {0}; static void buff_sort(uint16_t *arr,int num) { int i,j; uint16_t tmp; for(j=0; j < num;j++) { for(i =0; i < (num -j-1);i++) { if(arr[i+1] > arr[i]) { tmp = arr[i+1]; arr[i+1] = arr[i]; arr[i] = tmp; } } } } void read_adc_val(void) { int8_t i = 0; if(adc_sample_n < ADC_Avg_N) { for(i = 0;i < ADC_CH_N ;i++) { sort_buff[i][adc_sample_n] = adc_original_value[i]; } adc_sample_n++; } else { adc_sample_n = 0; for(i = 0;i < ADC_CH_N ;i++) { uint16_t *arr = &sort_buff[i][0]; buff_sort(arr,ADC_Avg_N); adc_Avg_value[i] = sort_buff[i][6]; if(adc_Avg_value[i] > adc_data_zero[i]) { adc_Avg_value[i] -= adc_data_zero[i]; } else { adc_Avg_value[i] = 0; } } adc_data_ok_flag = true; } }