SY8837_Demo_For_OurSelf/UsrSrc/adc/adc.c
rb_peng c743af0aa6 1、将双向通信的具体场景提到vox_Comm_Handle函数中
2、增加VOX持续输出0V以唤醒耳机的情况;
3、解决超长按后,双向通讯一直发码的问题;(松开按键后Key_Press_ll_irq设为FALSE)
4、解决关盖上电时,不亮灯和不发码的问题(即把Hall_Sta_bk初始化);
5、长按发配对码时,主副耳的选择提取到config.h中;
2025-02-21 17:24:44 +08:00

267 lines
7.3 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 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 修调。每一个位为 10mV1000 对应 offset 误差为 0mV1001 对应 offset误差为 10mV0111 对应 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