188 lines
7.3 KiB
C
Executable File
188 lines
7.3 KiB
C
Executable File
#include "../main/SystemInclude.h"
|
||
|
||
////使能内部温度传感器
|
||
//pAFE->REF_CTRL |=AFE_REF_CTRL_TEMP_SENSER_EN_Msk;
|
||
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief 初始化 ADC 内部基准源配置
|
||
* @note 使用内部参考电压 VREF,可配置 VREF 和 VDRIVE 输出电压。
|
||
* @param vref: 内部基准电压选择,如 REF_INTERNAL_2P5V
|
||
* @param vdrive: VDrive 输出电压选择,如 REF_INTERNAL_1P25V 或 REF_INTERNAL_OFF
|
||
* @example ADC_REF_Init(REF_INTERNAL_2P5V, REF_INTERNAL_1P25V);
|
||
**/
|
||
void ADC_REF_Init(u8 vref,u8 vdrive)
|
||
{
|
||
REF_InitTypeDef REF_InitStructure;
|
||
|
||
REF_InitStructure.VREF = vref; // 内部基准电压
|
||
REF_InitStructure.VDRIVE = vdrive;// VDrive输出电压
|
||
REF_InitStructure.VREF_Boost = DISABLE;
|
||
LHL_REF_Init(&REF_InitStructure);
|
||
}
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief 初始化 ADC 为连续转换模式,软件触发
|
||
* @note 基准源使用内部 VREF,输出为双极性数据,使能数据就绪中断。
|
||
* @param ADCx: ADC 实例 (ADC_0 / ADC_1)
|
||
* @param SPS: 输出速率,如 SPS_977
|
||
* @param Gain: 内部 PGA 增益,如 GAIN32
|
||
* @param PChan: 正输入通道,如 ADC0_AIN0
|
||
* @param NChan: 负输入通道,如 ADC0_AIN1
|
||
* @example ADC_Init(ADC_0, SPS_977, GAIN32, ADC0_AIN0, ADC0_AIN1);
|
||
**/
|
||
void ADC_Init(ADC_ID_t ADCx ,u8 SPS ,u8 Gain, u8 PChan, u8 NChan )
|
||
{
|
||
ADC_InitTypeDef ADC_InitStructure;
|
||
ADC_InitStructure.AINP = PChan; // ADC0输入通道
|
||
ADC_InitStructure.AINM = NChan;
|
||
ADC_InitStructure.PGA = Gain; // 内部PGA增益x1
|
||
ADC_InitStructure.FS = SPS; // ADC输出速率
|
||
ADC_InitStructure.Code = ADC_CODE_BIPOLAR; // 双极性数据
|
||
ADC_InitStructure.Mode = ADC_MODE_CONTINUOUS_CONVERSION; // 连续转换模式
|
||
ADC_InitStructure.Trigger = ADC_TRIGGER_SOFTWARE; // 软件触发
|
||
ADC_InitStructure.ReferenceSelect = ADC_REF_REFP_to_REFN; // 内部基准
|
||
ADC_InitStructure.REF_BUFP = ENABLE; // 使能基准缓冲
|
||
ADC_InitStructure.REF_BUFM = ENABLE;
|
||
ADC_InitStructure.REF_Precharge= DISABLE;
|
||
// ADC_InitStructure.Reference = 1250.0f; //基准值 init没用到
|
||
LHL_ADC_Init(ADCx, &ADC_InitStructure);
|
||
LHL_ADC_ITConfig(ADCx, ADC_IT_RDY, ENABLE);
|
||
}
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief 使能或禁止 ADC0 与 ADC1 同步转换模式
|
||
* @note 同步转换要求两个 ADC 的配置(SPS、模式、触发源)完全相同,
|
||
* ADC0 的启动源将自动应用到 ADC1。
|
||
* @param NewState: ENABLE 或 DISABLE
|
||
* @example ADC_SyncCmd(ENABLE);
|
||
**/
|
||
void ADC_SyncCmd(FunctionalState NewState)
|
||
{
|
||
LHL_ADC_SetSync(NewState);
|
||
}
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief 启动指定 ADC 的转换(软件触发时立即启动)
|
||
* @param ADCx: ADC 实例 (ADC_0 / ADC_1)
|
||
* @example StartADC(ADC_0);
|
||
**/
|
||
void StartADC(ADC_ID_t ADCx)
|
||
{
|
||
(ADCx == ADC_0) ? LHL_ADC_Start(ADC_0): LHL_ADC_Start(ADC_1);
|
||
}
|
||
/**------------------------------------------------------------------------
|
||
* @brief 停止指定 ADC 的转换
|
||
* @param ADCx: ADC 实例 (ADC_0 / ADC_1)
|
||
* @example StopADC(ADC_0);
|
||
**/
|
||
void StopADC(ADC_ID_t ADCx)
|
||
{
|
||
(ADCx == ADC_0) ? LHL_ADC_Stop(ADC_0): LHL_ADC_Stop(ADC_1);
|
||
}
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief 读取 ADC 转换数据(24 位原始数据转 16 位并偏移 32768)
|
||
* @note 转换公式:((原始数据符号扩展 >> 8) + 32768) & 0xFFFF
|
||
* @param ADCx: ADC 实例 (ADC_0 / ADC_1)
|
||
* @return 16 位 ADC 值(0~65535)
|
||
* @example u32 val = ADC_ReadData(ADC_0);
|
||
**/
|
||
u32 ADC_ReadData(ADC_ID_t ADCx)
|
||
{
|
||
volatile u32 reg_data = 0;
|
||
reg_data = (ADCx == ADC_0) ? LHL_ADC_GetData(ADC_0) : LHL_ADC_GetData(ADC_1);
|
||
reg_data = ((((reg_data & 0xFFFFFF) | ((reg_data & 0x800000) ? 0xFF000000 : 0)) >> 8) + 32768) & 0xFFFF;
|
||
return reg_data ;
|
||
}
|
||
|
||
|
||
|
||
|
||
/*===========================================================================*/
|
||
|
||
/* 小睡模式自动触发转换
|
||
选择此模式,在转换开始前配置为单次转换,并且将触发方式配置为硬件触发。
|
||
在进入到休眠模式(小睡模式)后,自动启动转换。
|
||
转换结束后自动停止转换,随后进入深度睡眠模式或者核心被唤醒进入正常工作模式。
|
||
需要将SNOOZE触发信号通过交叉路径至模数转换器(ADC)硬件触发源。
|
||
*/
|
||
/**------------------------------------------------------------------------
|
||
* @brief 初始化 ADC 为低功耗模式(单次转换 + 硬件触发)
|
||
* @note 适用于 SNOOZE 模式下的自动采样,转换完成后可选择唤醒或继续睡眠。
|
||
* @param ADCx: ADC 实例 (ADC_0 / ADC_1)
|
||
* @param SPS: 输出速率,如 SPS_10
|
||
* @param Gain: 内部 PGA 增益,如 GAIN32
|
||
* @param PChan: 正输入通道,如 ADC0_AIN2
|
||
* @param NChan: 负输入通道,如 ADC0_AVSS
|
||
* @example ADC_Init_For_LowerPower(ADC_0, SPS_10, GAIN32, ADC0_AIN2, ADC0_AVSS);
|
||
**/
|
||
void ADC_Init_For_LowerPower(ADC_ID_t ADCx, u8 SPS, u8 Gain, u8 PChan, u8 NChan)
|
||
{
|
||
ADC_InitTypeDef ADC_InitStructure;
|
||
ADC_InitStructure.AINP = PChan; // ADC输入通道
|
||
ADC_InitStructure.AINM = NChan;
|
||
ADC_InitStructure.PGA = Gain; // 内部PGA增益
|
||
ADC_InitStructure.FS = SPS; // ADC输出速率
|
||
ADC_InitStructure.Code = ADC_CODE_BIPOLAR; // 双极性数据
|
||
ADC_InitStructure.Mode = ADC_MODE_SINGLE_CONVERSION; // 单次转换模式
|
||
ADC_InitStructure.Trigger = ADC_TRIGGER_HARDWARE; // 硬件触发 ADC_TRIGGER_HARDWARE ADC_TRIGGER_SOFTWARE
|
||
ADC_InitStructure.ReferenceSelect = ADC_REF_REFP_to_REFN; // 内部基准
|
||
ADC_InitStructure.REF_BUFP = ENABLE; // 使能基准缓冲
|
||
ADC_InitStructure.REF_BUFM = ENABLE;
|
||
ADC_InitStructure.REF_Precharge = DISABLE;
|
||
|
||
LHL_ADC_Init(ADCx, &ADC_InitStructure);
|
||
LHL_ADC_ITConfig(ADCx, ADC_IT_RDY, ENABLE); //RDY_INT = 1
|
||
|
||
NVIC_EnableIRQ(ADC0_IRQn);
|
||
NVIC_SetPriority(ADC0_IRQn, 0);
|
||
NVIC_EnableIRQ(ADC1_IRQn);
|
||
NVIC_SetPriority(ADC1_IRQn, 0);
|
||
}
|
||
/*===========================================================================*/
|
||
|
||
|
||
|
||
|
||
//ADC中断回调==============================================================================================================
|
||
static adc_irq_callback_t adc0_irq_callback ,adc1_irq_callback;
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief 注册 ADC 转换完成中断回调函数
|
||
* @param ADCx: ADC 实例 (ADC_0 / ADC_1)
|
||
* @param tim_irq_callback: 用户回调函数指针(无参数无返回值)
|
||
* @note 注册后自动使能对应 ADC 的 NVIC 中断 。
|
||
* @example ADC_register_irq_callback(ADC_0, my_adc_callback);
|
||
**/
|
||
void ADC_register_irq_callback(ADC_ID_t ADCx, adc_irq_callback_t tim_irq_callback)
|
||
{
|
||
if(ADCx == ADC_0) {adc0_irq_callback = tim_irq_callback; NVIC_EnableIRQ(ADC0_IRQn);NVIC_SetPriority(ADC0_IRQn, 0);}
|
||
else if(ADCx == ADC_1) {adc1_irq_callback = tim_irq_callback; NVIC_EnableIRQ(ADC1_IRQn);NVIC_SetPriority(ADC1_IRQn, 0);}
|
||
}
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief ADC0 中断服务函数
|
||
* @note 当 ADC0 数据就绪时调用已注册的回调函数(若存在)。
|
||
**/
|
||
void ADC0_IRQHandler(void)
|
||
{
|
||
if(LHL_ADC_GetPending(ADC_0, ADC_FLAG_RDY) == SET)
|
||
{
|
||
if(adc0_irq_callback != NULL) adc0_irq_callback();
|
||
}
|
||
}
|
||
|
||
/**------------------------------------------------------------------------
|
||
* @brief ADC1 中断服务函数
|
||
* @note 当 ADC1 数据就绪时调用已注册的回调函数(若存在)。
|
||
**/
|
||
void ADC1_IRQHandler(void)
|
||
{
|
||
if(LHL_ADC_GetPending(ADC_1, ADC_FLAG_RDY) == SET)
|
||
{
|
||
if(adc1_irq_callback != NULL) adc1_irq_callback();
|
||
}
|
||
|
||
}
|