1.直接来上参考代码
#include "STC8Axx.h"
u16 xdata adc0;
u8 xdata Adc0Finish;
u16 xdata AdcBuff[10];
u8 xdata AdcTimes;
void adc_init(void);
void BatteryVoltage_ADC_ON(void);
u16 GetBatteryVoltage(void);
//*********************************初始化A/D转换*************************************************
void adc_init(void)
{
//ADC输入通道选择P1.2
P1M0 &= ~(1<<2);
P1M1 |= (1<<2);
ADC_CONTR = 0x02;
ADCCFG = 0x20; //右对齐
EADC = 1; //使能ADC中断
EA = 1;
adc0 = 0;
AdcTimes = 0;
Adc0Finish = 0;
}
void ADC_Isr() interrupt 5 using 1
{
EADC = 0;
ADC_CONTR &= ~0x20; //清中断标志
adc0 = ( (u16)ADC_RES * 256 + (u16)ADC_RESL );
ADC_RES = 0;
ADC_RESL = 0;
Adc0Finish = 1;
EADC = 1;
}
//**********************************ADC采集处理***************************************
//返回值 0xff 采集到0电压
// 0 采集未结束
// XX 电压值 单位0.01V
u16 GetBatteryVoltage(void)
{
u32 tempdata;
if (Adc0Finish)
{
Adc0Finish = 0;
AdcBuff[AdcTimes++] = adc0;
if(AdcTimes>=9)
{
tempdata=CalAverageValue(AdcBuff,AdcTimes);
AdcTimes=0;
ADC_CONTR &= ~ (1<<7); //关闭ADC电源
ADC_CONTR &= ~ (1<<6); //停止ADC采集
if(tempdata==0 ) return 0xff; //采集到0V 特殊处理
return (u16)(500*tempdata/4095); //计算5V电压值 单位为0.01V
}
else
{
ADC_CONTR |= (1<<6); //启动ADC采集
return 0;
}
}
return 0;
}
void BatteryVoltage_ADC_ON(void)
{
ADC_CONTR |= (1<<7); //打开ADC电源
delayNnop(20); //ADC打开电源到稳定可以工作需要等待一点时间,否则第一个数据可能存在异常,可以利用中值滤波的方法消除
ADC_CONTR |= (1<<6); //启动ADC采集
EADC = 1;
}
void ADC_Task (void)
{
while(1)
{
BatteryTemp=0;
BatteryTemp =GetBatteryVoltage();
if(0xff==BatteryTemp)
{
//采集到电压0V
UartSendStr(UART1SW,"The BatteryVoltage is: \r\n");
Tx_DEC_U16((u16)0);
}
else if(0!=BatteryTemp)
{
// 采集到电压值
UartSendStr(UART1SW,"The BatteryVoltage 0.01V is: \r\n");
Tx_DEC_U16( BatteryTemp );
}
//电压采集通过串口发送数据
if(++TimeCnt1>=50)
{
TimeCnt1 =0;
BatteryVoltage_ADC_ON(); //启动一次电压采集
//UartSendStr(UART1SW,"The BatteryVoltage open : \r\n");
}
break;
}
}
2. ADC采集数据转换
转换电压方法
0---4095(右对齐)
0----5V
3.注意
如果想要采集的电压比较稳定,多次采样数据后,考虑去掉最大值与最小值,然后取平均值。 同时注意在开启ADC模块后不要那么快的启动ADC运行采集数据,会出现不稳定现象,可以延时一段时间启动。