- 打卡等级:初来乍到
- 打卡总天数:1
- 最近打卡:2023-12-25 15:38:27
高级会员
- 积分
- 651
|
发表于 2023-3-3 19:40:21
|
显示全部楼层
梁工,贴代码出来了,我没看懂,没办法模仿
/******************************************************************************/
/** \file adc_detection.c
**
** ADC detection.
**
** - 2019-08-2 1.0 By Johnny.Cai
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "adc_detection.h"
extern type_stc_user_system_t gb_user_system;
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
const uint16_t bat_gauge_level[11] = {
3300, 3488, 3536, 3571, 3603, 3643, 3701, 3777, 3867, 3966, 4098
};/*3401*/ //20200928
const uint16_t bat_gauge_level2[11] = {
3614, 3671, 3702, 3733, 3766, 3814, 3842, 3971, 4072, 4187, 4210 //20201105
};
uint32_t sum_bat_adc;
uint16_t gauge_buffer[BUFFER_NUM], gauge_buffer_count = 0;
uint8_t bat_adc_initial = 0;
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern') *
******************************************************************************/
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
type_stc_adc_detection lc_adc_detection;
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/******************************************************************************
** \brief AdcInit
**
** \param [in] null
**
** \return null
******************************************************************************/
void AdcInit(void)
{
stc_adc_cfg_t stcAdcCfg;
stc_adc_cont_cfg_t stcAdcContCfg;
DDL_ZERO_STRUCT(stcAdcCfg);
DDL_ZERO_STRUCT(stcAdcContCfg);
Gpio_SetAnalog(CURRENT_RIGHT_PORT, CURRENT_RIGHT_PIN, TRUE);
Gpio_SetAnalog(CURRENT_LEFT_PORT, CURRENT_LEFT_PIN, TRUE);
Gpio_SetAnalog(VOLTAGE_BAT_PORT, VOLTAGE_BAT_PIN, TRUE);
Adc_Enable();
M0P_BGR->CR_f.BGR_EN = 0x1u; //BGR enable
M0P_BGR->CR_f.TS_EN = 0x0u; //internal temperature disable
delay100us(1);
stcAdcCfg.enAdcOpMode = AdcContMode; //continue mode
stcAdcCfg.enAdcClkSel = AdcClkSysTDiv4; //PCLK/4
stcAdcCfg.enAdcSampTimeSel = AdcSampTime12Clk; //12 clocks for sample
stcAdcCfg.enAdcRefVolSel = RefVolSelInBgr1p5; //refrence: internal 2.5V(avdd>3V,SPS<=200kHz)
//stcAdcCfg.enAdcRefVolSel = RefVolSelAVDD; //refrence: AVDD
stcAdcCfg.bAdcInBufEn = FALSE; //voltage follower enable, SPS(sample rate) must <=200K
stcAdcCfg.enAdcTrig0Sel = AdcTrigDisable;
stcAdcCfg.enAdcTrig1Sel = AdcTrigDisable;
Adc_Init(&stcAdcCfg);
stcAdcContCfg.enAdcContModeCh = VOLTAGE_BAT_CHN; //channel BAT
stcAdcContCfg.u8AdcSampCnt = 0x0Fu; //sample timers(timers = 0x0F+1)
stcAdcContCfg.bAdcResultAccEn = TRUE; //enable ACC
Adc_ConfigContMode(&stcAdcCfg, &stcAdcContCfg);
}
void AdcUninit(void)
{
M0P_BGR->CR_f.BGR_EN = 0x0u;
Adc_Disable();
}
/******************************************************************************
** \brief ADCSample
**
** \param [in] ch sample channel
**
** \return u32adcresult ADC result
******************************************************************************/
uint32_t ADCSample(en_adc_samp_ch_sel_t ch)
{
uint32_t u32adcresult;
M0P_ADC->CR2 &= 0xFFFFFF00;
M0P_ADC->CR2 |= 1 << ch;
M0P_ADC->CR0_f.SEL = ch;
delay100us(1);
Adc_Start(); //ADC start
while(FALSE == M0P_ADC->IFR_f.CONT_INTF); //wait for ADC complete
M0P_ADC->ICLR_f.CONT_INTC = 0; //clear the flag
Adc_GetAccResult(&u32adcresult);
Adc_ClrAccResult();
return u32adcresult;
}
/******************************************************************************
** \brief HandsetLCurrent
**
** \param null
**
** \return current max=255mA
******************************************************************************/
uint8_t HandsetLCurrent(void)
{
uint32_t temp;
temp = ADCSample(CURRENT_LEFT_CHN);
temp *= REFERENCE_ADC;
temp /= CURRENT_RESISTANCE;
temp /= 65536;
return (uint8_t)temp;
}
/******************************************************************************
** \brief HandsetRCurrent
**
** \param null
**
** \return current max=255mA
******************************************************************************/
uint8_t HandsetRCurrent(void)
{
uint32_t temp;
temp = ADCSample(CURRENT_RIGHT_CHN);
temp *= REFERENCE_ADC;
temp /= CURRENT_RESISTANCE;
temp /= 65536;
return (uint8_t)temp;
}
/******************************************************************************
** \brief BatGauge
**
** \param null
**
** \return gauge max=100
******************************************************************************/
uint8_t BatGauge(uint8_t charge)
{
uint32_t temp;
uint8_t level;
const uint16_t *vaule_level;
if(charge)
{
vaule_level = bat_gauge_level2;
}
else
{
vaule_level = bat_gauge_level;
}
temp = ADCSample(VOLTAGE_BAT_CHN);
temp *= REFERENCE_ADC / 4;
temp *= VOLTAGE_DIVIDE_TOTAL;
temp /= VOLTAGE_DIVIDE_MODULUS;
temp /= 16384;
if(temp < vaule_level[0])
temp = vaule_level[0];
gauge_buffer[gauge_buffer_count++] = temp; //递推滤波算法 191226f
if(gauge_buffer_count == BUFFER_NUM)
{
gauge_buffer_count = 0;
}
sum_bat_adc = 0;
for(uint8_t loop = 0; loop < BUFFER_NUM; loop++)
{
sum_bat_adc += gauge_buffer[loop];
}
temp = sum_bat_adc / BUFFER_NUM;
if(temp < vaule_level[0])
temp = vaule_level[0];
/****************************************************/
for(level = 1; level <= 10; level++)
{
if(temp < vaule_level[level])
{
temp = vaule_level[level] - temp;
temp = temp * 10 / (vaule_level[level] - vaule_level[level - 1]);
temp = level * 10 - temp;
return (uint8_t)temp;
}
}
return 100;
}
/******************************************************************************
** \brief BatDetect
**
** \param charge TRUE:battery charging
**
** \return gauge of battery max=100
******************************************************************************/
uint8_t BatDetect(uint8_t charge)
{
uint8_t gauge = BatGauge(charge); //get the bat gauge
if(charge)
{
lc_adc_detection.flag_f.bat_low = 0;
lc_adc_detection.flag_f.bat_none = 0;
lc_adc_detection.bat_low_cnt = 0;
lc_adc_detection.bat_none_cnt = 0;
if(gb_user_system.bat_th_gauge < 80)
{
if(gb_user_system.bat_th_gauge < gauge)
{
if(gauge > 80)
{
gb_user_system.bat_th_gauge = 80;
}
else
{
gb_user_system.bat_th_gauge = gauge;
}
}
}
if(gb_user_system.bat_th_gauge < 90)
{
if(++lc_adc_detection.gauge_charge_cnt >= GAUGE_LOW_CHARGE_UP_TIME)
{
lc_adc_detection.gauge_charge_cnt = 0;
gb_user_system.bat_th_gauge++;
}
}
else
{
if(++lc_adc_detection.gauge_charge_cnt >= GAUGE_HIGH_CHARGE_UP_TIME)
{
lc_adc_detection.gauge_charge_cnt = 0;
if(gb_user_system.bat_th_gauge < 98)
{
gb_user_system.bat_th_gauge++;
}
}
}
}
// else if(gb_user_system.flag_f.adc_init_finish) //adc初始化完成之后才判断低电量
else
{
if(gauge < gb_user_system.bat_th_gauge) //充电时电量只能增加,放电时电量只能减小 200108f
{
gb_user_system.bat_th_gauge = gauge;
}
//if(gauge <= BAT_GAUGE_LOW)
if(gb_user_system.bat_th_gauge <= BAT_GAUGE_LOW)
{
if(lc_adc_detection.bat_low_cnt >= 5)
{
lc_adc_detection.flag_f.bat_low = 1;
}
else
{
lc_adc_detection.bat_low_cnt++;
}
}
else
{
lc_adc_detection.bat_low_cnt = 0;
}
if(gb_user_system.bat_th_gauge <= BAT_GAUGE_NONE)
{
if(lc_adc_detection.bat_none_cnt >= 5)
{
lc_adc_detection.flag_f.bat_none = 1;
}
else
{
lc_adc_detection.bat_none_cnt++;
}
}
else
{
lc_adc_detection.bat_none_cnt = 0;
}
}
return gb_user_system.bat_th_gauge;
}
/******************************************************************************
** \brief Bat Flag Get
**
** \param null
**
** \return flag
******************************************************************************/
_Bool BatLowFlagGet(void)
{
return lc_adc_detection.flag_f.bat_low;
}
_Bool BatNoneFlagGet(void)
{
return lc_adc_detection.flag_f.bat_none;
}
|
|