#include "stm32l0xx.h"
/* adc_cnt/(uwTick /1000) = 转换率 */
__IO uint32_t uwTick;
__IO uint32_t adc_cnt = 0; /* 转换次数 */
__IO uint16_t vdd_vol = 0;
uint16_t vref_vol = 0;
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; */
}
/* 此程序中断次数过多在所难免,所以批量数据建议使用DMA. */
void ADC1_COMP_IRQHandler(void)
{
/* 转换当前ADC并计算当前VDD电压 */
if(READ_BIT(ADC1->ISR, ADC_ISR_EOC))
{
/* 倒推VDD电压 */
vdd_vol = vref_vol / ((float)(ADC1->DR) / 65535);
adc_cnt++;
/* 关闭ADC节能 */
SET_BIT(ADC1->CR, ADC_CR_ADEN | ADC_CR_ADSTART | ADC_CR_ADVREGEN);
}
}
void ADC_GetVDD_Voltage(void)
{
/* 第一次数值,一旦VREF电压计算后,就不会为0. */
if(vref_vol == 0)
{
/* 初始化时钟 */
SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN));
/* 初始化相关寄存器 */
ADC1->CFGR1 = 0x00000000;
ADC1->CFGR2 = 0x4000009D; /* 16Bit 过采样,以 16Bit 表示. */
ADC->CCR = 0x00400000;
ADC1->SMPR = 0x00000007; /* 采样时间寄存器,0 = 1.14Msps,1 = 1Msps,2 = 800Ksps,3 = 640Ksps,4 = 500Ksps,5 = 308Ksps,6 = 174Ksps,7 = 92ksps, @ 16MHz */
ADC1->CHSELR = 0x00020000;
/* 采样时间和结果区别:0 = 3625mV 1 = 3302mV 2 = 3190mV 3 = 3244mV 4 = 3317mV 5 = 3302mV 6 = 3302mV 7 = 3302mV */
/* 校准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;
SET_BIT(ADC1->IER, ADC_IER_EOCIE);
NVIC_SetPriority(ADC1_COMP_IRQn, 0);
NVIC_EnableIRQ(ADC1_COMP_IRQn);
}
SET_BIT(ADC1->CR, ADC_CR_ADEN | ADC_CR_ADSTART | ADC_CR_ADVREGEN);
}
int main(void)
{
RCC_Init();
ADC_GetVDD_Voltage();
while (1)
{
}
}