采样PA0,PA1,内部温度传感器,内部基准参考,其中PA0接VCC,PA1悬空.
代码如下:
#include "stm32l0xx.h" __IO uint32_t uwTick; uint16_t pdata[100][4] = {0x00}; void DMA1_Channel1_IRQHandler(void) { if( (DMA1->ISR & (0x00000002U)) != RESET) /* DMA_FLAG_TC1 */ { if((DMA1_Channel1->CCR & DMA_CCR_TCIE) != RESET) { if((DMA1_Channel1->CCR & DMA_CCR_CIRC) == 0U) { DMA1_Channel1->CCR &= ~(DMA_CCR_TCIE); } /* 清除中断标志位 */ DMA1->IFCR = 0x00000002U; /* DMA_FLAG_TC1 */ CLEAR_BIT(ADC1->CR, ADC_CR_ADEN); if(pdata[0][0] == 0xFFFF) { pdata[0][0] = 0xFFFF;/* UNUSED */ } } } } 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; */ } void ADC_GetVDD_Voltage(void) { /* 初始化时钟 */ SET_BIT(RCC->APB2ENR, (RCC_APB2ENR_ADC1EN)); SET_BIT(RCC->AHBENR, (RCC_AHBENR_DMAEN)); SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); DMA1_Channel1->CCR = 0x00000580; DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S; DMA1_CSELR->CSELR |= 0x00000000U; /* DMA_REQUEST_0 */ /* 上电没配置过,默认除了JTAG外引脚都是模拟引脚,所以懒得配置了. */ /* 初始化相关寄存器 */ ADC1->CFGR1 = 0x0000A000; /* DMA 允许 + AUTO OFF(自动降低功耗) */ ADC1->CFGR2 = 0x00002000; /* 连续采样模式,这样就不用每次都Start. */ ADC->CCR = 0x00C00000; /* Vref + Temp Sensor */ ADC1->SMPR = 0x00000007; /* 采样时间寄存器,0 = 1.14Msps,1 = 1Msps,2 = 800Ksps,3 = 640Ksps,4 = 500Ksps,5 = 308Ksps,6 = 174Ksps,7 = 92ksps, @ 16MHz */ ADC1->CHSELR = 0x00060003; /* PA0 + PA1 + Temp + Vref,其中PA0通过短路帽接到了VCC. */ /* 采样时间和结果区别: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)); SET_BIT(ADC1->CR, ADC_CR_ADEN); SET_BIT(ADC1->CFGR1, ADC_CFGR1_DMAEN); CLEAR_BIT(DMA1_Channel1->CCR, DMA_CCR_EN); DMA1_Channel1->CNDTR = 400; DMA1_Channel1->CMAR = (uint32_t)&pdata; DMA1_Channel1->CPAR = (uint32_t) & (ADC1->DR); SET_BIT(DMA1_Channel1->CCR, DMA_CCR_TCIE); SET_BIT(DMA1_Channel1->CCR, DMA_CCR_EN); SET_BIT(ADC1->CR, ADC_CR_ADSTART); NVIC_SetPriority(DMA1_Channel1_IRQn, 0); NVIC_EnableIRQ(DMA1_Channel1_IRQn); } int main(void) { RCC_Init(); ADC_GetVDD_Voltage(); while (1) { SysTick_Delay(1000); SET_BIT(ADC1->CR, ADC_CR_ADEN); CLEAR_BIT(DMA1_Channel1->CCR, DMA_CCR_EN); DMA1_Channel1->CNDTR = 400; DMA1_Channel1->CMAR = (uint32_t)&pdata; DMA1_Channel1->CPAR = (uint32_t) & (ADC1->DR); SET_BIT(DMA1_Channel1->CCR, DMA_CCR_TCIE); SET_BIT(DMA1_Channel1->CCR, DMA_CCR_EN); SET_BIT(ADC1->CR, ADC_CR_ADSTART); } }