SY8837_Demo_For_OurSelf/UsrSrc/adc/adc.c

289 lines
8.0 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.

/*
******************************************************************************
*
* @file adc.c
* @brief adc module
* @ic sy8835
*
* @version 1.0
* @date 2024/11/01 15:00:40
* @author Alex Xu
*
* Copyright (c) 2013-2099,Tkplusemi Technology Co.,Ltd.
* All Rights Reserved
*
* History:
* Revision Date Author Desc
* 1.0.0 2024/11/01 Alex build this file
******************************************************************************/
/*_____ I N C L U D E S ____________________________________________________*/
#include "adc.h"
#include "system.h"
#include "sys_tim.h"
#if ADC_ENABLE
/******************************************************************************\
Macro definitions
\******************************************************************************/
#define ADC_AVERAGE_CNT 8
/******************************************************************************\
Variables definitions
\******************************************************************************/
idata int8_t ADC_Offset_Error = 0; //ADC Offset Error У׼ֵ¼Ä´æÆ÷
idata int8_t Bat_ADC_Offset_Error = 0;
idata uint8_t Vor_Isense_Gain_Error = 0;
idata uint8_t Vol_Isense_Gain_Error = 0;
idata int8_t Vor_Isense_Offset_Error = 0;
idata int8_t Vol_Isense_Offset_Error = 0;
xdata uint8_t ADC_Chn_Num = 0;
idata uint16_t g_Value_Adc = 0;
xdata uint16_t g_Value_Adc_Avg = 0;
#if 0
xdata uint16_t g_Value_Adc0 = 0;
xdata uint16_t g_Value_Adc1 = 0;
xdata uint16_t g_Vref_Adc = 0;
#endif
xdata int16_t g_Vntc_Adc = 0;
xdata int16_t g_pmu_Adc_Ivol = 0;
xdata int16_t g_pmu_Adc_Ivor = 0;
xdata int16_t g_Vbat_Adc = 0;
xdata int16_t g_pmu_Adc_Vout = 0;
xdata uint8_t g_ADC_Chn = 0;
xdata uint8_t Adc_Index = 0;
bit ADC_Cal_Over_Flag = 0;
/******************************************************************************\
Functions definitions
\******************************************************************************/
/*
*******************************************************************************
* void Adc_Init(void)
*
* Description : ADC Initialization. --- ϵͳ³õʼ»¯µ÷Óᣣ¨ ADC²ÉÑùת»»Ò»´ÎÐèÒª19¸öCLK£¬Ò»¸öCLK 4us£¬×ª»»Ò»´ÎÐèÒª76us¡££©
ADC²ÉÓÃÁ¬ÐøÄ£Ê½£¬ÔÚÖжÏÖвÉÑù8´Îºó£¬µÈ´ýÏÂÒ»¸öͨµÀʹÄÜ¡£ÔÚÇл»Í¨µÀǰȡǰһ¸öͨµÀµÄ²ÉÑùÖµ£¬½øÐÐ8´Îƽ¾ù¡£
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Adc_Init(void)
{
SFRADDR = MFP_CTL1; //Set P07 As NTC
SFRDATA |= 0x80;
SFRADDR = ADC_CTL0; //0B10111101,<0x29>--ADC EN;ADC 2.5V Enable b[4];ADC1 Pullup 100K Enable b[5]; continue mode; ADC CLK divided by 48=230k
SFRDATA = 0xB5;
ADC_CTL1 = ( ADC_NTC << 4 ) | 0x01; //Start ADC , Enable ntc Chn.
SFRADDR = IRQ_EN10; //Enable ADC Interrupt(INT6).
SFRDATA |= 0x01;
#if 1
ADC_Offset_Error = (int8_t)( ( ADC_OFFSET & 0x0F ) - 8 ); //»ñÈ¡ADC Offset ErrorУ׼ֵ¡£
Bat_ADC_Offset_Error = (int8_t)( ADC_OFFSET >> 4 );
/* »ñÈ¡Ivox¶ÔÓ¦µÄOffset Error ºÍGain Error */
Vol_Isense_Offset_Error = (int8_t)( ( IVOX_OFFSET & 0x0F ) - 8 ) * 10; //VOX µçÁ÷²ÉÑù offset ÐÞµ÷¡£Ã¿Ò»¸öλΪ 10mV£¬1000 ¶ÔÓ¦ offset Îó²îΪ 0mV£¬1001 ¶ÔÓ¦ offsetÎó²îΪ 10mV£¬0111 ¶ÔÓ¦ offset Îó²îΪ-10mV
Vol_Isense_Gain_Error = IVOL_GAIN;
Vor_Isense_Offset_Error = (int8_t)( ( IVOX_OFFSET >> 4 ) - 8 ) * 10;
Vor_Isense_Gain_Error = IVOR_GAIN;
//Vol_Isense_Offset_Error = 10;
//Vor_Isense_Offset_Error = 10;
#endif
EX6 = 1; //ADC IRQ Enable
}
/*
*******************************************************************************
* void PMU_ADC_Chn_Data(PMU_ADC_CHANNELS_E pmu_Adc_Chn)
*
* Description : ÉèÖÃÏàӦͨµÀµÄʹÄÜ¡£ÔÚÖ÷Ñ­»·Öа´Í¨µÀÉèÖø÷¸öͨµÀµÄʹÄÜ,Á¬ÐøÄ£Ê½£¬½øÖжÏ8´Îºó£¬È¡Öµ£¬ÇÐͨµÀ¡£
ÔÚÖжÏÖлñÈ¡¶ÔÓ¦µÄADCÖµ£¬¼õÉÙÖ÷º¯ÊýµÄ×èÈû£¬ÌáÉýϵͳÐÔÄÜ¡£
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void PMU_ADC_Chn_Data( PMU_ADC_CHANNELS_E pmu_Adc_Chn )
{
if( ADC_Cal_Over_Flag )
{
g_Value_Adc_Avg = g_Value_Adc_Avg >> 3;
/*»ñÈ¡xSen¶ÔÓ¦µÄADCÖµ*/
switch (g_ADC_Chn)
{
case ADC_NTC:
g_Vntc_Adc = g_Value_Adc_Avg - ADC_Offset_Error; //NTCÈ¡ÂëÖµÊÇ·ñÐèÒª´¦ÀíOffset Error¡£
if( g_Vntc_Adc < 0 )
{
g_Vntc_Adc = 0;
}
break;
case ADC_IVOL:
g_Value_Adc_Avg = ( (uint32_t)g_Value_Adc_Avg * 2500 ) >> 10 ; //ADCµÄLSB = 2500mV / 1024 = 2.44mV
g_pmu_Adc_Ivol = (int32)( (int16)( g_Value_Adc_Avg - Vol_Isense_Offset_Error ) ) * 100 / (int16)( 500 + 2 * Vol_Isense_Gain_Error ) ; //IVOLµçѹλVOLµÄµçÁ÷·Å´ó5±¶Ë͸øADC£¬ÀýÈ磺100mAµçÁ÷£¬ADC²ÉÑùµçѹΪ500mV¡£
#ifdef _DEBUG_ADC
// printf("Vol:Adc_Avg:%d,Ivol:%d,Offset_Error:%d,Gain_Error:%d,temp:%d\r\n",(u16)g_Value_Adc_Avg,(u16)g_pmu_Adc_Ivol,(u16)Vol_Isense_Offset_Error,(u16)Vol_Isense_Gain_Error,(u16)( ( g_Value_Adc_Avg - Vol_Isense_Offset_Error ) ));
#endif
if( g_pmu_Adc_Ivol < 0 ) //Ö»´¦ÀíÕýµçÁ÷
{
g_pmu_Adc_Ivol = 0;
}
break;
case ADC_IVOR:
g_Value_Adc_Avg = ( (uint32_t)g_Value_Adc_Avg * 2500 ) >> 10 ; //ADCµÄLSB = 2500mV / 1024 = 2.44mV
g_pmu_Adc_Ivor = (int32)( (int16)( g_Value_Adc_Avg - Vor_Isense_Offset_Error ) ) * 100 / (int16)( 500 + 2 * Vor_Isense_Gain_Error ) ; //IVORµçѹλVORµÄµçÁ÷·Å´ó5±¶Ë͸øADC£¬ÀýÈ磺100mAµçÁ÷£¬ADC²ÉÑùµçѹΪ500mV¡£
#ifdef _DEBUG_ADC
// printf("Vor:Adc_Avg:%d,Ivor:%d,Offset_Error:%d,Gain_Error:%d,temp:%d\r\n",(u16)g_Value_Adc_Avg,(u16)g_pmu_Adc_Ivor,(u16)Vor_Isense_Offset_Error,(u16)Vor_Isense_Gain_Error,(u16)( ( g_Value_Adc_Avg - Vor_Isense_Offset_Error ) ));
#endif
if( g_pmu_Adc_Ivor < 0 ) //Ö»´¦ÀíÕýµçÁ÷
{
g_pmu_Adc_Ivor = 0;
}
break;
case ADC_BAT:
g_Value_Adc_Avg = ((uint32_t)( g_Value_Adc_Avg ) * 2500) >> 10 ; //ADCµÄLSB = 2500mV / 1024 = 2.44mV
g_Vbat_Adc = g_Value_Adc_Avg << 1; //VBATµÄ2·Öѹ¡£
g_Vbat_Adc += (int32)( ( g_Vbat_Adc * 4 * ( Bat_ADC_Offset_Error - 8 ) ) / 1000 );
if( g_Vbat_Adc < 0 )
{
g_Vbat_Adc = 0;
}
break;
case ADC_VOUT:
g_Value_Adc_Avg = ( (int32_t)( g_Value_Adc_Avg - ADC_Offset_Error ) * 2500 ) >> 10 ; //ADCµÄLSB = 2500mV / 1024 = 2.44mV
g_pmu_Adc_Vout = g_Value_Adc_Avg << 1; //VOUTµÄ2·Öѹ¡£
if( g_pmu_Adc_Vout <0 )
{
g_pmu_Adc_Vout = 0;
}
break;
default:
break;
}
//g_Value_Adc_Avg = 0;
ADC_Cal_Over_Flag = 0;
#ifdef _DEBUG_ADC
printf("adc chn:%d,adc_value:%d,Ivol:%d,Vbat:%d,Vout:%d,Ivor:%d,Vntc:%d.\r\n",(uint16_t)ADC_Chn_Num,(uint16_t)g_Value_Adc_Avg,(uint16_t)g_pmu_Adc_Ivol,(uint16_t)g_Vbat_Adc,(uint16_t)g_pmu_Adc_Vout,(uint16_t)g_pmu_Adc_Ivor,(uint16_t)g_Vntc_Adc);
#endif
}
else
{
g_ADC_Chn = pmu_Adc_Chn;
ADC_CTL1 = ( pmu_Adc_Chn << 4 ) | 0x01; //ADC Start Enable,Set Channel N Enabel.
g_Value_Adc_Avg = 0;
Adc_Index = 0;
}
}
/*
*******************************************************************************
* void EX6_ADC_isr(void ) interrupt Interrupt_Vector_IE6
*
* Description : System External Intterupt 6 adc Interrupt.
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void EX6_ADC_isr(void) interrupt Interrupt_Vector_IE6
{
if(IRQ_FLAG10 & ADC_Data_Ready)
{
g_Value_Adc = ADC_DATL; //ÏÈÈ¡µÍ8λÊý¾Ý£¬Ëø¶¨µ±Ç°ADC²ÉÑùÖµ¡£
g_Value_Adc |= (uint16_t)( ( ADC_DATH & 0x03 ) << 8 );
if( Adc_Index < ADC_AVERAGE_CNT ) //Çó¾ùÖµ
{
g_Value_Adc_Avg += g_Value_Adc;
Adc_Index++;
}
else
{
ADC_Cal_Over_Flag = 1;
ADC_CTL1 &= ~0x01; //Disable ADC.
}
}
IRQ_FLAG10 = ADC_Data_Ready;
}
#endif