2、增加VOX持续输出0V以唤醒耳机的情况; 3、解决超长按后,双向通讯一直发码的问题;(松开按键后Key_Press_ll_irq设为FALSE) 4、解决关盖上电时,不亮灯和不发码的问题(即把Hall_Sta_bk初始化); 5、长按发配对码时,主副耳的选择提取到config.h中;
267 lines
7.3 KiB
C
267 lines
7.3 KiB
C
/*
|
||
******************************************************************************
|
||
*
|
||
* @file adc.c
|
||
* @brief adc module
|
||
* @ic sy8837/8
|
||
*
|
||
* @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
|
||
|
||
\******************************************************************************/
|
||
|
||
static int8_t ADC_Offset_Error; //ADC Offset Error 校准值,有符号数
|
||
|
||
static int8_t Bat_ADC_Offset_Error;//电池 ADC Offset Error 校准值,有符号数
|
||
|
||
static uint8_t Vor_Isense_Gain_Error;//Vor 电流ADC GAIN Error 校准值,无符号数
|
||
|
||
static uint8_t Vol_Isense_Gain_Error;//Vol 电流ADC GAIN Error 校准值,无符号数
|
||
|
||
static int8_t Vor_Isense_Offset_Error;//Vor 电流ADC Offset Error 校准值,无符号数
|
||
|
||
static int8_t Vol_Isense_Offset_Error;//Vol 电流ADC Offset Error 校准值,无符号数
|
||
|
||
static uint8_t g_ADC_Chn;//ADC采样通道
|
||
|
||
static uint8_t Adc_Index;//ADC采样次数计数器
|
||
|
||
static bit ADC_Cal_Over_Flag;//ADC采样完成标志位
|
||
|
||
static uint16_t g_Value_Adc;//ADC采样码值
|
||
|
||
static uint16_t g_Value_Adc_Avg;//ADC多次采样值和
|
||
|
||
uint8_t ADC_Chn_Num; //ADC采样通道计数器
|
||
|
||
int16_t g_Vntc_Adc;//NTC通道ADC采样码值
|
||
|
||
int16_t g_pmu_Adc_Ivol;//Vol通道电流ADC采样码值
|
||
|
||
int16_t g_pmu_Adc_Ivor;//Vor通道电流ADC采样码值
|
||
|
||
int16_t g_Vbat_Adc;//Bat通道ADC采样码值
|
||
|
||
int16_t g_pmu_Adc_Vout;//Vout通道ADC采样码值
|
||
|
||
/******************************************************************************\
|
||
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;
|
||
|
||
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;
|
||
|
||
EX6 = 1; //ADC IRQ Enable
|
||
}
|
||
|
||
/*
|
||
*******************************************************************************
|
||
* void PMU_ADC_Chn_Data(PMU_ADC_CHANNELS_E pmu_Adc_Chn)
|
||
*
|
||
* Description : 设置相应通道的使能。在主循环中按通道设置各个通道的使能,连续模式,进中断取值8次叠加后,切通道。
|
||
在中断中获取对应的ADC值,减少主函数的阻塞,提升系统性能。
|
||
*
|
||
* Arguments : PMU_ADC_CHANNELS_E pmu_Adc_Chn
|
||
|
||
* 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。
|
||
|
||
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。
|
||
|
||
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;
|
||
}
|
||
|
||
ADC_Cal_Over_Flag = FALSE;
|
||
|
||
|
||
}
|
||
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 = TRUE;
|
||
|
||
ADC_CTL1 &= ~0x01; //Disable ADC.
|
||
}
|
||
}
|
||
|
||
IRQ_FLAG10 = ADC_Data_Ready;
|
||
|
||
}
|
||
|
||
#endif
|
||
|