Files
checker_slave/source/elec_det/hardware/adc_cfg.c

636 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "adc_cfg.h"
#include "gpio_cfg.h"
#include "base/delay.h"
#include "timer_cfg.h"
#include "base/utility.h"
#include "power.h"
volatile uint16_t ad0_adc_sample[AD_SCAN_SAMPLE*AD_SCAN_COUNT];
#define ADC1_SAMPLE_BUF_LEN 200
#define ADC1_SAMPLE_BUF_LEN2 20
volatile uint16_t FireBus_ADC_Buf[FIREBUS_ADC_BUF_LEN];
volatile uint16_t adc1_sample_buf[ADC1_SAMPLE_BUF_LEN];
void AdcDef_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE );
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //12MHz
//GPIO 配置
GPIO_InitStructure.GPIO_Pin= VCC_2V5_Pin | VCC_1V25_Pin | V_LA_M_Pin | V_LA_H_Pin | R_AD_01_Pin;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_Write(GPIOA,GPIO_InitStructure.GPIO_Pin);
//GPIO 配置
GPIO_InitStructure.GPIO_Pin= AD_OUTA_Pin | AD_OUTB_Pin | AN_UA_Pin | AN_MAL_Pin | AN_CAP_AD_Pin;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_Write(GPIOC,GPIO_InitStructure.GPIO_Pin);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = AD_SCAN_SAMPLE;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_TempSensorVrefintCmd(ENABLE);
ADC_RegularChannelConfig(ADC1, VCC_2V5_CH, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, VCC_1V25_CH, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, V_LA_M_CH, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, V_LA_H_CH, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, AD_OUTA_CH, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, AD_OUTB_CH, 6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 7, ADC_SampleTime_71Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 8, ADC_SampleTime_71Cycles5);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ad0_adc_sample;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = AD_SCAN_SAMPLE*AD_SCAN_COUNT;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DISABLE;
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_DMACmd(ADC1,ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_DeInit(ADC2);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC2, &ADC_InitStructure);
ADC_Cmd(ADC2, ENABLE);
ADC_ResetCalibration(ADC2);
while(ADC_GetResetCalibrationStatus(ADC2));
ADC_StartCalibration(ADC2);
while(ADC_GetCalibrationStatus(ADC2));
ADC_DMACmd(ADC2,ENABLE);
ADC_SoftwareStartConvCmd(ADC2, ENABLE);
}
void StartADC2Channel(uint32_t channel, uint32_t speed)
{
ADC_RegularChannelConfig(ADC2,channel,1,speed);
ADC_SoftwareStartConvCmd(ADC2,ENABLE);
delay_us(100);
}
void StartADC1Channel(uint32_t channel)
{
ADC_RegularChannelConfig(ADC1,channel,1,ADC_SampleTime_71Cycles5);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
delay_us(100);
//adc_calibration_enable(ADC0);
}
/*
使用该函数对ADC2触发一次采样到用该函数前应调用一次StartADC1Channel(ch)
*/
uint32_t GetADC2_Fast(void)
{
uint16_t time_out = 10000;
uint16_t temp = 0;
ADC_ClearFlag(ADC2,ADC_FLAG_EOC);//清除转换结束标志
ADC_SoftwareStartConvCmd(ADC2,ENABLE);//启动转换
while((time_out > 0) && ( ADC_GetFlagStatus(ADC2,ADC_FLAG_EOC) == RESET))
{
time_out--;
}
temp = ADC_GetConversionValue(ADC2) & 0x0FFF;
return temp;
}
/*
使用该函数对ADC触发一次采样到用该函数前应调用一次StartADC0Channel(ch)
*/
uint16_t GetADC_Fast(ADC_TypeDef* adc_periph)
{
uint16_t time_out = 10000;
uint16_t temp = 0;
ADC_ClearFlag(adc_periph,ADC_FLAG_EOC);//清除转换结束标志
ADC_SoftwareStartConvCmd(adc_periph,ENABLE);//启动转换
while((time_out > 0) && ( ADC_GetFlagStatus(adc_periph,ADC_FLAG_EOC) == RESET))
{
time_out--;
}
temp = ADC_GetConversionValue(adc_periph) & 0x0FFF;
return temp;
}
uint32_t GetADC1_Fast(void)
{
return GetADC_Fast(ADC1);
}
uint32_t GetADC2_Value(uint32_t channel)
{
StartADC2Channel(channel,ADC_SPEED_MIDLE);
return GetADC2_Fast();
}
/*
ADC_RegularChannelConfig(ADC1, VCC_2V5_CH, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, VCC_1V25_CH, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, V_LA_M_CH, 3, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, V_LA_H_CH, 4, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, AD_OUTA_CH, 5, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, AD_OUTB_CH, 6, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 7, ADC_SampleTime_71Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 8, ADC_SampleTime_71Cycles5);
*/
void GetADC1_Value(uint32_t channel,uint16_t* buf,uint16_t len)
{
uint8_t i = 0;
volatile uint16_t* buf_head = 0;
switch(channel)
{
case VCC_2V5_CH: buf_head = ad0_adc_sample;break;
case VCC_1V25_CH: buf_head = ad0_adc_sample+1;break;
case V_LA_M_CH: buf_head = ad0_adc_sample+2;break;
case V_LA_H_CH: buf_head = ad0_adc_sample+3;break;
case AD_OUTA_CH: buf_head = ad0_adc_sample+4;break;
case AD_OUTB_CH: buf_head = ad0_adc_sample+5;break;
case ADC_Channel_16:buf_head = ad0_adc_sample+6;break;
case ADC_Channel_17:buf_head = ad0_adc_sample+7;break;
default:buf_head = 0;break;
}
if(buf_head == 0)
return;
if(len > AD_SCAN_COUNT)
len = AD_SCAN_COUNT;
for(i=0; i < len ; i++)
{
buf[i] = buf_head[i*AD_SCAN_SAMPLE];
}
}
float Get_Temperature(void)
{
uint32_t ad_v;
GetADC1_Value(ADC_Channel_16,(uint16_t*)&ad_v,1);
float temper = (1.43f - ad_v*3.3f/4096) * 1000 / 4.3f + 25;
return temper;
}
/*************************ADC App****************************************/
/*
@brief 稳定获取总线电流
@rtv 返回电流值 0.1uA
*/
uint16_t ADC_GetBaseStableCur(void)
{
uint16_t us_count = 0;
uint16_t us_temp = 0;
uint32_t ul_base;
StartADC2Channel(AN_UA_CH,ADC_SPEED_SLOW);
Power_SetSampleCurrentRange(R100_0uA_160uA_UC);
delay_ms(100);
while(us_count < ADC1_SAMPLE_BUF_LEN)
{
adc1_sample_buf[us_count] = GetADC_Fast(ADC_CURR_DE);
delay_us(20);
if(us_count == 0)
{
ul_base = adc1_sample_buf[us_count] ;
}else{
ul_base += adc1_sample_buf[us_count] ;
ul_base >>= 1;
}
us_count++;
}
for(us_count = 0; us_count < ADC1_SAMPLE_BUF_LEN; us_count++)
{
ul_base = (ul_base*8 + adc1_sample_buf[us_count]*2 )/10;
adc1_sample_buf[us_count] = ul_base;
}
Bubble_Sort_u16((uint16_t *)adc1_sample_buf,us_count);
us_count = (ADC1_SAMPLE_BUF_LEN>>2);
us_temp = ADC1_SAMPLE_BUF_LEN - (ADC1_SAMPLE_BUF_LEN>>2);
while(us_count < us_temp)
{
ul_base += adc1_sample_buf[us_count++];
}
us_temp -= (ADC1_SAMPLE_BUF_LEN>>2);
ul_base = ul_base / us_temp;
ul_base = Power_ConvCur(ul_base,R100_0uA_160uA_UC);
return ul_base;
}
/*
@brief 稳定获取总线电流
@rtv 返回电流值 0.1uA
*/
uint16_t ADC_Comm1p6mA_EndCur(void)
{
uint16_t us_count = 0;
uint16_t us_temp = 0;
uint32_t ul_base;
StartADC2Channel(AN_UA_CH,ADC_SPEED_SLOW);
Power_SetSampleCurrentRange(R10_0p1mA_1p6mA_UC);
delay_ms(1);
while(us_count < ADC1_SAMPLE_BUF_LEN2)
{
adc1_sample_buf[us_count] = GetADC_Fast(ADC_CURR_DE);
delay_us(1);
if(us_count == 0)
{
ul_base = adc1_sample_buf[us_count] ;
}else{
ul_base += adc1_sample_buf[us_count] ;
ul_base >>= 1;
}
us_count++;
}
for(us_count = 0; us_count < ADC1_SAMPLE_BUF_LEN2; us_count++)
{
ul_base = (ul_base*8 + adc1_sample_buf[us_count]*2 )/10;
adc1_sample_buf[us_count] = ul_base;
}
Bubble_Sort_u16((uint16_t *)adc1_sample_buf,us_count);
us_count = (ADC1_SAMPLE_BUF_LEN2>>2);
us_temp = ADC1_SAMPLE_BUF_LEN2 - (ADC1_SAMPLE_BUF_LEN2>>2);
while(us_count < us_temp)
{
ul_base += adc1_sample_buf[us_count++];
}
us_temp -= (ADC1_SAMPLE_BUF_LEN2>>2);
ul_base = ul_base / us_temp;
ul_base = Power_ConvCur(ul_base,R10_0p1mA_1p6mA_UC);
return ul_base;
}
/*
@brief 电流降到指定电流下的时间
@param 执行时间 单位0.1ms
@rtv 最大波动AD值
*/
uint16_t AD_CurMonitor(uint32_t ul_times)
{
uint32_t ul_count = 0, ul_count2;
uint16_t us_count = 0;
uint16_t aus_adc[20];
uint16_t us_maxadv,us_minadv = 0;
uint16_t ul_shake = 0;
LED1_Out = 0;
for(ul_count2 =0; ul_count2 < 20;ul_count2++)
{
aus_adc[ul_count2] = ADC_GetCurADCFast();
}
LED1_Out = 1;
ul_count2 = 0;
while(ul_times > 0)
{
ul_count = 0;
Get100usCount();
while(ul_count< 50000 && ul_count < ul_times)
{
us_maxadv = 0;
us_minadv = 0xFFF;
for(us_count = 0; us_count < 20;us_count++)
{
if(aus_adc[us_count] > us_maxadv)
{
us_maxadv = aus_adc[us_count];
}
if(aus_adc[us_count] < us_minadv)
{
us_minadv = aus_adc[us_count];
}
}
ul_count2 %= 20;
aus_adc[ul_count2++] = ADC_GetCurADCFast();
if(us_maxadv < us_minadv)
{
us_minadv = 4096;
}else{
us_minadv = us_maxadv - us_minadv;
}
if(ul_shake < us_minadv)
{
ul_shake = us_minadv;
if(ul_shake > 500){
LED1_Out = 0;
delay_us(50);
LED1_Out = 1;
}
}
delay_us(40);
ul_count = GET_COUNTTIM_VAL();
}
if(ul_count >= ul_times)
{
LED1_Out = 0;
return ul_shake;
}
ul_times -= ul_count;
}
LED1_Out= 0;
return ul_shake;
}
/*
@brief 电流降到指定电流下的时间
@param 采样超时
@param end_adv 检测启动和结束判线
@param 最大电流ad
@param 电流下降过程中最大向上波动
@rtv 时间采集值0.1ms
*/
uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max_cul,uint16_t *shake_adv)
{
uint16_t aus_adc_v[5];
uint16_t aus_adv_shake[20];
uint16_t time_out;
uint16_t us_count = 0;
uint16_t us_shake_count = 0;
uint16_t us_shake_minadc,us_shake_maxadc;
uint8_t start_flag = 0,shake_flag = 0;
Get100usCount();
ADC_ClearFlag(ADC_CURR_DE,ADC_FLAG_EOC);//清除转换结束标志
ADC_SoftwareStartConvCmd(ADC_CURR_DE, ENABLE); //启动转换
aus_adc_v[4] = 0xFFFF;
*max_cul = 0;
*shake_adv = 0;
LED1_Out = 0;
if(end_adv == 0 || end_adv == 0xFFFF)
{
return 0;
}
while(GetCountTimerCnt() < sample_timeout)
{
time_out = 2000;
while((time_out > 0) && ( ADC_GetFlagStatus(ADC_CURR_DE,ADC_FLAG_EOC) == RESET))
{
time_out--;
}
aus_adc_v[us_count] = ADC_GetConversionValue(ADC_CURR_DE) & 0x0FFF;
aus_adv_shake[us_shake_count] = aus_adc_v[us_count];
ADC_ClearFlag(ADC_CURR_DE,ADC_FLAG_EOC);//清除转换结束标志
ADC_SoftwareStartConvCmd(ADC_CURR_DE, ENABLE); //启动转换
us_count++;
us_shake_count++;
us_count %= 5;
us_shake_count %= 20;
if((us_shake_count == 0) && (start_flag > 0))
{
shake_flag ++;
}
if(shake_flag == 2)
{
LED1_Out = 1;
shake_flag = 1;
time_out = 0;
us_shake_maxadc = 0;
us_shake_minadc = 0x0FFF;
while(time_out < 20)
{
if(aus_adv_shake[time_out] > us_shake_maxadc)
{
us_shake_maxadc = aus_adv_shake[time_out];
}
if(aus_adv_shake[time_out] < us_shake_minadc)
{
us_shake_minadc = aus_adv_shake[time_out];
}
time_out++;
}
us_shake_minadc = us_shake_maxadc - us_shake_minadc;
if(us_shake_minadc > 900)
{
us_shake_minadc = 0;
}
if(*shake_adv < us_shake_minadc)
{
*shake_adv = us_shake_minadc;
}
}
if(us_count == 0)
{
Bubble_Sort_u16(aus_adc_v,5);
if((aus_adc_v[0] > end_adv) && start_flag == 0)
{
start_flag = 1;
Get100usCount();//未启动重新设置计数器
}
//连续5个都大于判线值
else if(start_flag >0 )
{
if(*max_cul < aus_adc_v[2])
{
*max_cul = aus_adc_v[2];
}
if(aus_adc_v[4] < end_adv)
{
LED1_Out = 0;
return Get100usCount();
}
}else if(start_flag == 0)
{
if(GetCountTimerCnt() > 10000)
{
return 0;
}
}
}
}
return 40000;
}
/*获取桥丝电阻*/
void AD_SampleResistor(uint16_t* channels_re)
{
uint16_t aus_sample[32];
uint8_t uc_index = 0;
const static float resistor_cur = 2.49f;
const static float res_mutli = RES_MULTIPLE;
/*
Gpio_ResistorSwitch
@param 0 全关
1 通道1-4通过桥丝
2 通道2-3通过桥丝
3 通道1-3通测阻抗
4 通道2-4通测阻抗
*/
float f_r1,f_r2,f_r3,f_r4;
ADC_ResistorChannelSet(ADC_SPEED_MIDLE);
Gpio_ResistorSwitch(1);
delay_ms(50);
for(uc_index = 0; uc_index < 32; uc_index++)
{
aus_sample[uc_index] = ADC_GetResistorADCFast();
}
Bubble_Sort_u16(aus_sample,uc_index);
f_r1 = 0;
for(uc_index = 8; uc_index < 24; uc_index++)
{
f_r1 += aus_sample[uc_index];
}
f_r1 = (((f_r1 /res_mutli)*1000)/4096)*3.3f/resistor_cur/16;
Gpio_ResistorSwitch(2);
delay_ms(50);
for(uc_index = 0; uc_index < 32; uc_index++)
{
aus_sample[uc_index] = ADC_GetResistorADCFast();
}
Bubble_Sort_u16(aus_sample,uc_index);
f_r2 = 0;
for(uc_index = 8; uc_index < 24; uc_index++)
{
f_r2 += aus_sample[uc_index];
}
f_r2 = (((f_r2 /res_mutli)*1000)/4096)*3.3f/resistor_cur/16;
Gpio_ResistorSwitch(3);
delay_ms(50);
for(uc_index = 0; uc_index < 32; uc_index++)
{
aus_sample[uc_index] = ADC_GetResistorADCFast();
}
Bubble_Sort_u16(aus_sample,uc_index);
f_r3 = 0;
for(uc_index = 8; uc_index < 24; uc_index++)
{
f_r3 += aus_sample[uc_index];
}
f_r3 = (((f_r3 /res_mutli)*1000)/4096)*3.3f/resistor_cur/16;
Gpio_ResistorSwitch(4);
delay_ms(50);
for(uc_index = 0; uc_index < 32; uc_index++)
{
aus_sample[uc_index] = ADC_GetResistorADCFast();
}
Bubble_Sort_u16(aus_sample,uc_index);
f_r4 = 0;
for(uc_index = 8; uc_index < 24; uc_index++)
{
f_r4 += aus_sample[uc_index];
}
f_r4 = (((f_r4 /res_mutli)*1000)/4096)*3.3f/resistor_cur/16;
Gpio_ResistorSwitch(0);
channels_re[0] = (uint16_t) (((f_r1+f_r2-f_r3-f_r4)/2+0.005f)*100);
channels_re[1] = (uint16_t) ((f_r1+0.005f)*100);
channels_re[2] = (uint16_t) ((f_r2+0.005f)*100);
channels_re[3] = (uint16_t) ((f_r3+0.005f)*100);
channels_re[4] = (uint16_t) ((f_r4+0.005f)*100);
}
/*测量电容电压*/
uint16_t AD_SampleCap(uint16_t delay)
{
uint32_t ul_ad = 0,ul_ad2 = 0;
uint8_t uc_index = 0;
uint16_t aus_sample[32];
Gpio_CAPSwitch(1);
ADC_CAPVolChannelSet(ADC_SPEED_MIDLE);
delay_ms(1500);
for(uc_index = 0; uc_index < 32; uc_index++)
{
aus_sample[uc_index] = ADC_GetCAPVolADCFast();
}
Bubble_Sort_u16(aus_sample,uc_index);
ul_ad = 0;
for(uc_index = 8; uc_index < 24; uc_index++)
{
ul_ad += aus_sample[uc_index];
}
//
ul_ad >>= 4;
while(delay > 0)
{
delay_os_ms(100);
delay--;
}
for(uc_index = 0; uc_index < 32; uc_index++)
{
aus_sample[uc_index] = ADC_GetCAPVolADCFast();
}
Bubble_Sort_u16(aus_sample,uc_index);
ul_ad2 = 0;
for(uc_index = 8; uc_index < 24; uc_index++)
{
ul_ad2 += aus_sample[uc_index];
}
//ul_ad2 = ((ul_ad2 *25*11*100/board_st.v2p5_adc/16)+5)/10;
ul_ad2 >>= 4;
if(ul_ad < ul_ad2)
{
ul_ad = 0;
}else{
ul_ad = ul_ad - ul_ad2;
ul_ad = ((Power_ADVGetCalVal_106(ul_ad)*11)/100+5)/10 ;//((ul_ad *25*11*1000/board_st.v2p5_adc )+5)/10;
}
Gpio_CAPSwitch(0);
return ul_ad;
}