#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(); } }