STM8L之ADC


/*******************************************************************************
*名 称: Hal_Comm_GetBatADC
*功 能: 获取电池电量信息
*入口参数: 无
*出口参数: 电量AD值
*说 明:
*******************************************************************************/
unsigned int Hal_Comm_GetBatADC(void)
{
unsigned int Result = 0, value_adc = 0;
unsigned char index = 0;
GPIO_Init(VOL_ADC_PORT,VOL_ADC_PIN,GPIO_Mode_In_FL_No_IT);//VOL_ADC
ADC1->CR1 |= 0x01;//使能AD
ADC1->CR3 &= ~0x1F;// 选择采样时间 384 周期 通道清空
ADC1->CR3 |= 0x00; // channel 0 is selected
ADC1->SQR[0] = ADC1->SQR[1] = ADC1->SQR[2] = ADC1->SQR[3] = 0x00;
ADC1->SQR[3] = 0x01;// 选择通道0扫描
ADC1->SR &= 0x00;// conversion not complete
ADC1->SR = 0; // conversion 标识清空
ADC1->CR1 |= 0x03;//使能AD并开始转换
while(!(ADC1->SR & 0x01)); //waitloop bit0: 1 complete 0 not complete
for(index = 0; index < 10; index++)
{
ADC1->SR = 0; // conversion 标识清空
ADC1->CR1 |= 0x03;//使能AD 开始转换
while(!(ADC1->SR & 0x01));//waitloop conversion complete
Result = ADC1->DRH; //总共计算16bit的值,但ADC为12 bit 长度
Result <<= 8; //ADC1->DRH为高8位,
Result += ADC1->DRL; //ADC1->DRL为低8位
value_adc += Result;
if(index != 0)value_adc = value_adc/2; //获取多次数据,计算平均值
index++;
}
ADC1->CR1 &= 0xFE;//关闭AD
ADC1->CR3 &= ~0x1F;//选择通道
ADC1->CR3 |= 0x11;
return value_adc;
}
我们一般在设计原理图的时候会把ADC的输入电压范围设定在:0~3.3v,如果设置ADC为12位的,那么12位满量程对应的就是3.3V,12位满量程对应的数字值是:2^12。数值0对应的就是0V。如果转换后的ADC数值为X,X对应的模拟电压为Y,那么会有这么一个等式成立:2^12/3.3=X/Y,=>Y=(3.3*X)/2^12
在我们的智能锁项目中,满量程Vref为3.31V,总电压(M6V)/测试电压(VOL_ADC) = 3
4096/3.31 = value_adc/Va
Va = value_adc * 3.31 / 4096
总电压 = Va * 3
即程序中的vin = value_adc * 3.31 * 3 / 4096