STM32L011 ADC采样测试

/ 0评 / 0

换到了新的平台,因为L0以超低功耗出名,而且价格也不贵.另外因为有内部Vref.可以反推出VDD,用的也是ST的官方板子,Nucleo-F011测试的,官方板子用的LDO参数也挺不错的.
首先测试一下官方LDO的数值.

然后说明一下我的测试条件:

  1. ADC读取内部Vref的标准数值并保存.
  2. ADC读取内部Vref的参考数值,并倒推VCC电压.
  3. ADC通过改变采样率查看是否影响精度,低的采样率不能捕捉快速变化的信号,高的采样率容易产生错误.
  4. ADC通过改变输入时钟查看是否影响精度.输入时钟低时间长,功耗低,采样率也低.

测试程序提纲:

#include "stm32l0xx.h"
__IO uint32_t uwTick;
void SysTick_Delay(__IO uint32_t Delay)
{
    uint32_t tickstart = 0U;
    tickstart = uwTick;
    while((uwTick - tickstart) < Delay)
    {
    }
}
void RCC_Init(void)
{
    /* LSE OFF,LSI DEFAULT,MSI OFF,HSI ON,PLL ON,SYSCLK = 32MHz,CK_PWR = FCLK = HCLK = SysTick = APB1 = APB2 = 32MHz.*/
    FLASH->ACR = FLASH_ACR_PRE_READ | FLASH_ACR_PRFTEN;
    MODIFY_REG(PWR->CR, PWR_CR_VOS, (PWR_CR_VOS_0));
    MODIFY_REG(RCC->CR, RCC_CR_HSION | RCC_CR_HSIDIVEN , RCC_CR_HSION);
    while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET);
    MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSITRIM, (uint32_t)(16) << 8U);
    CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
    while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET);
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PLLMUL | RCC_CFGR_PLLDIV | RCC_CFGR_PLLSRC, (uint32_t)((RCC_CFGR_PLLMUL4) | (RCC_CFGR_PLLDIV2) | (RCC_CFGR_PLLSRC_HSI)));
    SET_BIT(RCC->CR, RCC_CR_PLLON);
    while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET);
    MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, (uint32_t)(0x01U));
    MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV1);
    MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
    while ((uint32_t)(RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_CFGR_PPRE1_DIV1);
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_CFGR_PPRE1_DIV1) << 3));
    CLEAR_BIT(RCC->CR, RCC_CR_MSION);
    /* SysTick CLK = 4MHz,Reload = 1kHz. */
    SysTick->LOAD  = (uint32_t)0x00000F9FUL;
    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
    SysTick->VAL   = 0UL;
    SysTick->CTRL  = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
    /* SysTick->CTRL  = SysTick_CTRL_TICKINT_Msk; */
}
uint16_t ADC_GetVDD_Voltage(void)
{
    static uint16_t vref_vol = 0;
    uint16_t vdd_vol = 0;
    /* 第一次数值,一旦VREF电压计算后,就不会为0. */
    if(vref_vol == 0)
    {
        /* 初始化时钟 */
        SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN));
        /* 初始化相关寄存器 */
        ADC1->CFGR1 = 0x00000000;
        ADC1->CFGR2 = 0x40000000;
        ADC->CCR = 0x00400000;
        ADC1->SMPR = 0x00000000;
        ADC1->CHSELR = 0x00020000;
        /* 校准ADC */
        SET_BIT(ADC1->CR, ADC_CR_ADCAL);
        while(READ_BIT(ADC1->CR, ADC_CR_ADCAL));
        /* 计算内部Vref电压(mV) */
        vref_vol =  3000.0 * (*(uint16_t *)0x1FF80078) / 4095;
    }
    /* 转换当前ADC并计算当前VDD电压 */
    SET_BIT(ADC1->CR, ADC_CR_ADEN | ADC_CR_ADSTART);
    /* 等待转换完成 */
    while(READ_BIT(ADC1->ISR, ADC_ISR_EOC));
    /* 倒推VDD电压 */
    vdd_vol = vref_vol / ((float)(ADC1->DR) / 4095);
    /* 关闭ADC节能 */
    CLEAR_BIT(ADC1->CR, ADC_CR_ADEN | ADC_CR_ADSTART);
    return vdd_vol;
}
uint16_t vdd_mv[50];
uint8_t i = 0;
int main(void)
{
    RCC_Init();
    while (1)
    {
        for(i = 0; i < 50; i++)
        {
            vdd_mv[i] = ADC_GetVDD_Voltage();
            SysTick_Delay(10);
        }
    }
}

下面固定条件是16MHz下,最短采样时间,得到1.14Msps采样率(可见电压整理偏高了).

依然是16MHz时钟,但是现在是1Msps采样率(基本上已经正确了).

但是事实上我们好像有点不理解了.现在是下面一些测试数据,因为都是这样贴图,我就不再贴了.

  1. 16MHz@1.14Msps = 3625mV
  2. 16MHz@1Msps = 3302mV
  3. 16MHz@800Ksps = 3190mV
  4. 16MHz@640ksps = 3244mV
  5. 16MHz@500Ksps = 3317mV
  6. 16MHz@308Ksps = 3302mV
  7. 16MHz@174Ksps = 3392mV
  8. 16MHz@92Ksps = 3302mV
  9. 8MHz@570Ksps = 3615mV
  10. 8MHz@500Ksps = 3302mV
  11. 8MHz@400Ksps = 3193mV
  12. 8MHz@320Ksps = 3248mV
  13. 8MHz@250Ksps = 3250mV
  14. 8MHz@154Ksps = 3316mV
  15. 8MHz@87Ksps = 3305mV
  16. 8MHz@46Ksps = 3305mV
  17. 250kHz@17Ksps = 3615mV
  18. 250kHz@1.4Ksps = 3305mV

从18个实验可以看出,不是说采样率越低准确度就越高,如果这一条件要成立,那么时钟一定要相等,比如1.14Msps和17Ksps结果都是测出了3600mV以上,这个跟万用表测试的差距太大,但是降低时钟肯定会降低功耗,如果知道自己的所需采样率,我觉得还是提高时钟然后用最接近的来采样,精度比较高,执行时间也短,执行时间短也是节省功耗的一个办法.终究没得出3307mV,有几个原因,走线损耗,无论是PCB还是芯片内部,还有可能我万用表不准了.140KHz ~ 16MHz是ADC的工作频率,推算出来,最快是1.14Msps,最慢是包含256X过采样,还有173Cycle,配140KHz,大概是3次每秒,是够慢的.
 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注