#include "adc.h"
/*********************************************************
*name: ADC_Init
*input: no
*output: no
*return: no
*explain: ADC初始化,ADC1 IN1 PA1 规则通道
********************************************************/
void ADC_Init(void)
{
//初始化IO
RCC->APB2ENR |= 1<<2; //使能GPIOA时钟
GPIOA->CRL &= 0XFFFFFF0F; //模拟输入模式
//ADC配置
RCC->APB2ENR |= 1<<9; //使能ADC1时钟
RCC->APB2RSTR |= 1<<9; //ADC1复位
RCC->APB2RSTR &= ~(1<<9); //结束复位
RCC->CFGR &= ~(3<<14); //清除分频配置
RCC->CFGR |= 2<<14; //设置ADC分频,12M,ADC最大时钟不能超过14M,否则不精准
ADC1->CR1 &= 0XFFF0FFFF; //清除配置模式
ADC1->CR1 |= 0<<16; //独立模式
ADC1->CR1 &= ~(1<<8); //非扫描模式
ADC1->CR2 &= ~(1<<1); //单次转换
ADC1->CR2 &= ~(7<<17); //清除配置
ADC1->CR2 |= 7<<17; //SWSTART外部事件
ADC1->CR2 |= 1<<20; //使用外部事件启动转换
ADC1->CR2 &= ~(1<<11); //右对齐
ADC1->CR2 |= 1<<23; //使能内部温度传感器
ADC1->SQR1 &= ~(15<<20); //清除SQR1的20-23位的配置
ADC1->SQR1 |= 0<<20; //规则通道序列长度为1个转换
//设置通道1的采样时间
ADC1->SMPR2 &= ~(7<<3); //清除SMP1[2:0]的配置
ADC1->SMPR2 |= 7<<3; //239.5个采样周期,提高采样时间,提供精准度
//设置通道16采样时间
ADC1->SMPR1 &= ~(7<<18); //清除SMP2[20:18]的配置
ADC1->SMPR1 |= 7<<18; //239.5个采样周期
ADC1->CR2 |= 1<<0; //开启ADC转换
//校准,ADC1_CR2寄存器中2和3位由软件置位,使能校准,硬件清零完成校准
ADC1->CR2 |= 1<<3; //使能复位校准
while(ADC1->CR2 & 1<<3); //等待复位校准已初始化
ADC1->CR2 |= 1<<2; //使能AD校准
while(ADC1->CR2 & 1<<2); //等待AD校准完成
printf("ADC初始化完成!\r\n");
}
/*********************************************************
*name: Get_ADC
*input: u8 ch 通道选择 0-16
*output: no
*return: u16 返回ADC的值
*explain: 获取ADC转换后的值
********************************************************/
u16 Get_ADC(u8 ch)
{
ADC1->SQR3 &= 0XFFFFFFE0; //清除序列寄存器3的SQ1[4:0]的配置
ADC1->SQR3 |= ch;
ADC1->CR2 |= 1<<22; //开始转换规则通道
while(!(ADC1->SR & 1<<1)); //等待转换完成
return ADC1->DR;
}
/*********************************************************
*name: Get_ADC_Average
*input: u8 ch 通道选择 0-16,u8 times 取平均的次数
*output: no
*return: u16 返回ADC的值
*explain: 获取ADC转换后的值,然后进行平均,以提高精度
********************************************************/
u16 Get_ADC_Average(u8 ch, u8 times)
{
u16 temp_val = 0;
u8 t;
for(t=0; t<times; t++)
{
temp_val += Get_ADC(ch);
delay_ms(5);
}
return temp_val/times;
}