FM33L025 ADC REF1.2V测试不准
如题,采用FM33L025芯片,采用PC9--ADC0测量外部电压,但是测量内部1.2V电压时发现ad值不稳定,当PC9电压超过1.85V时,1.2V的电压测量值就偏差很大,偏差能达到上下一两百左右,当PC9电压低于1.85V时,1.2V的电压测量值稳定在1485,偏差就几个数。采用的FL固件库的程序移植的,希望大神解惑。系统时钟为RCHF 16MHz,测量外部电压又是比较稳定的。//adc初始化
void adcInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
//AD检测口
GPIO_InitStruct.Pin = ADC_DET_PIN;
GPIO_InitStruct.PxFCR = GPIO_FCR_ANA;
GPIO_InitStruct.PxPUEN = GPIO_PU_Dis;
GPIO_InitStruct.PxINEN = GPIO_IN_Dis;
GPIO_InitStruct.PxODEN = GPIO_OD_En;
GPIO_Init( ADC_DET_PORT, &GPIO_InitStruct );
// 模块时钟
RCC_OPC_CR2_ADCCKE_Setable(ENABLE); // ADC时钟使能
RCC_OPC_CR2_ADCPRSC_Set(RCC_OPC_CR2_ADCPRSC_DIV16); // ADC工作时钟
RCC_OPC_CR2_ADCCKS_Set(RCC_OPC_CR2_ADCCKS_RCHF); // ADC时钟 RCHF
// 电源控制
if(DISABLE == PMU_VREF_CR_EN_Getable()) //判断ref122是否使能,如果禁止需清IF,保证下次使能查到的IF正确
PMU_VREF_SR_IF_Clr();
PMU_VREF_CR_EN_Setable(ENABLE); // EN VREF1.22
while(!PMU_VREF_SR_IF_Chk());
// 复位ADC模块
RCC_PRST_EN_Write(RSTKEY0);
RCC_APBRST_CR2_ADCRST_Setable(ENABLE);// 数字部分复位
RCC_APBRST_CR2_ADCRST_Setable(DISABLE);
RCC_APBRST_CR2_ADCCRST_Setable(ENABLE); // 模拟部分复位
RCC_APBRST_CR2_ADCCRST_Setable(DISABLE);
RCC_PRST_EN_Write(RSTKEY1);
//上电校准
ADC_CR_ADEN_Setable(ENABLE); // 使能ADC
ADC_CAL_CALEN_Setable(ENABLE);// Calibration使能,软件写1启动校准周期,硬件开始校准后自动清零。软件通过EOCAL寄存器查询校准周期结束。
while(0 == ADC_ISR_EOCAL_Chk());
ADC_ISR_EOCAL_Clr(); // 清校准结束
ADC_CR_ADEN_Setable(DISABLE); // 关闭ADC
// ADC配置
ADC_CAL_CONV_CAL_Set(ADC_CAL_CONV_CAL_USE_CAL); //ADC转换使用校准寄存器里的数据
ADC_SMTR_SMTS1_Set(ADC_SMTR_SMTS1_10_5_TMCLK);//设置快速采样时间
ADC_SMTR_SMTS2_Set(ADC_SMTR_SMTS2_10_5_TMCLK);//设置快速采样时间
// ADC配置寄存器
ADC_CFGR_CKS_Set(ADC_CFGR_CKS_ADCCLK);// ADCCLK
ADC_CFGR_CONT_Setable(DISABLE); // ENABLE:连续转换, DISABLE: 单次转换
ADC_CFGR_SEMI_Set(ADC_CFGR_SEMI_AUTO); //半自动,仅单次转换有效
ADC_CFGR_OVRM_Set(ADC_CFGR_OVRM_COVER); // 当overrun发生时,覆盖上次数据
ADC_CFGR_OVSS_Set(ADC_CFGR_OVSS_R_SHIFT_4);
ADC_CFGR_OVSR_Set(ADC_CFGR_OVSR_16x);
ADC_CFGR_OVSEN_Setable(ENABLE);
ADC_CFGR_WAIT_Setable(ENABLE);
//AD检测口设置为ADC输入通道
GPIOx_ANEN_Setable(ADC_DET_PORT, ADC_DET_PIN, ENABLE);
}
//测试发现引脚电压超过1.85V,测到的1.22V的电压值就变化比较大,正常在1485
uint16_t GetVref1p22Sample(void)
{
uint8_t i = 0;
uint32_t adc_val = 0;
uint32_t result = 0;
//此处分频不能太小,否则最终测量电压会偏高
//实测,16MHz RCHF,分频8,会偏高,改到16分频,则数据正常
RCC_OPC_CR2_ADCPRSC_Set(RCC_OPC_CR2_ADCPRSC_DIV16);// ADC时钟16分频,VREF的驱动能力较弱,采样时间不能小于10.5*(1/2M)
PMU_BUF_CR_VREFBUFFER_EN_Setable(ENABLE); // 电压通道使能
RCC_OPC_CR2_ADCCKE_Setable(ENABLE); // ADC时钟使能
ADC_CHER_REFCH_Setable(ENABLE); // VREF测量通道使能
PMU_VREF_CR_EN_Setable(ENABLE); // EN VREF1.22
ADC_ISR_EOC_Clr();
ADC_CR_ADEN_Setable(ENABLE); // 启动ADC
delay_ms(5); // 软件延时至少5个ADC工作时钟
for (i = 0; i < 4; i++)
{
ADC_CR_START_Setable(ENABLE);// 开始转换
while (ADC_ISR_EOC_Chk() == RESET);
ADC_ISR_EOC_Clr();
adc_val = ADC_DR_Read();
result += adc_val;
}
result = result/4;
ADC_CR_ADEN_Setable(DISABLE); // 关闭ADC
while(ADC_ISR_BUSY_Chk());
RCC_OPC_CR2_ADCCKE_Setable(DISABLE); // ADC时钟关闭
// PMU_BUF_CR_VREFBUFFER_EN_Setable(DISABLE);// VREF BUFFER输出关闭
ADC_CHER_REFCH_Setable(DISABLE); // VREF测量通道关闭
// 返回转换结果
return (uint16_t)result;
}
没太看懂,意思是说REF1.2在测量PC9高于1.85V的时候,采样值偏差很大,但是算出的外部电压又是稳定的??那这时候的VDD电压稳定吗 我是一只鱼21 发表于 2022-1-20 10:38
没太看懂,意思是说REF1.2在测量PC9高于1.85V的时候,采样值偏差很大,但是算出的外部电压又是稳定的??那 ...
vdd电压稳定的,找到问题了。芯片用的设配器供电,pc9的电压是另一个可调电源,可调电源地接到板子上,电源正接到pc9引脚。是2个不同电源导致的
页:
[1]