#include "adc.h"
AdcObj::AdcObj(void) { Init(); }
/*---------------------------------------------------- R0 = 10K, R1 = 51K, Vref = 2.50V 公式:Vx = Vref * (R0 + R1) / R0
V0 =2.5*(61/10)=15.25V V1 =2.5*(61/10)=15.25V V23=2.5*(85/10)=21.25V Ak = Vx / 1024 -----------------------------------------------------*/ void AdcObj::Init(void) { unsigned char i; AdcChNum = 0; ADCSRA = 0x00; ADMUX = 0;//选择外部2.50为基准 ACSR = (1 << ACD);//关闭模拟比较器 SetAdcChNum(AdcChNum);//设置新通道 for (i = 0; i < 4; i ++) { AdcVal = 0; AdcCount = 0; } AdcSum[1] = 0; AdcMax[1] = 0; AdcMin[1] = 0x1ff;//9位ADC
AdcSum[2] = 0; AdcMax[2] = 0; AdcMin[2] = 0x3ff;//10位ADC
AdcSum[3] = 0; AdcMax[3] = 0; AdcMin[3] = 0x3ff;//10位ADC /*---------------------------------------------------- R0 = 10K, R1 = 51K, Vref = 2.50V, Vk = 10, N = 9, 10 公式:Vx = Vref * (R0 + R1) / R0 Ak = Vx * / 2 ^ n Ak0 = 15250 / 512 (N = 9) = 30500 / 1024 Ak1 = 15250 / 1024 Ak2 = 21250 / 1024 Ak3 = 21250 / 1024 -----------------------------------------------------*/
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频,启动AD转换 }
inline unsigned char AdcObj::GetAdcChNum(unsigned char ChNum) { __root __flash static const unsigned char AdcChNumTab[4] = {//ADC通道变换表 0x09,//0b00001001,//差分测试,*10,ADC1-ADC0 0x09,//0b00001001,//差分测试,*10,ADC1-ADC0 0x02,//0b00000010,//单端测试,*1,ADC2 0x00//0b00000000,//单端测试,*1,ADC0 // 0x03//0b00000011,//电压,单端测试,*1,ADC3 }; return AdcChNumTab[ChNum & 0x03];//返回ADC通道变换号 }
inline void AdcObj::SetAdcChNum(unsigned char ChNum)//设置ADC通道变换号 { // ADMUX = (1 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择内部2.56为基准 ADMUX = (0 << REFS1) | (1 << REFS0) | GetAdcChNum(ChNum);//选择外部2.50为基准 }
void AdcObj::Exec(void) { //volatile unsigned int AdcResult; //volatile unsigned long val; AdcResult = ADC & 0x3ff;//取ADC转换电压,并保存 SetAdcChNum(AdcChNum + 1);//设置新通道 if (AdcChNum > 0) { /*----------------------------------------------------------- 求累加和 ------------------------------------------------------------*/ AdcSum[AdcChNum] += AdcResult;//存累加和 /*----------------------------------------------------------- 求最大值 ------------------------------------------------------------*/ if (AdcResult > AdcMax[AdcChNum]) { AdcMax[AdcChNum] = AdcResult;//最大值 } /*----------------------------------------------------------- 求最小值 ------------------------------------------------------------*/ if (AdcResult <= AdcMin[AdcChNum]) { AdcMin[AdcChNum] = AdcResult;//存最小值 } AdcCount[AdcChNum] ++; if (AdcCount[AdcChNum] >= 18)//每点测试18次,滤波 { /*----------------------------------------------------------- 求平均值 ------------------------------------------------------------*/ /*---------------------------------------------------- V0 =2.5*(61/10)=15.25V V1 =2.5*(61/10)=15.25V V23=2.5*(85/10)=21.25V -----------------------------------------------------*/ val = AdcSum[AdcChNum] - AdcMax[AdcChNum] - AdcMin[AdcChNum]; val *= AdcAkVal[AdcChNum]; val >>= 14;//18中取16后除以1024 AdcVal[AdcChNum] = val; /*----------------------------------------------------------- 初始化 ------------------------------------------------------------*/ AdcSum[AdcChNum] = 0; AdcMax[AdcChNum] = 0; if (AdcChNum == 1) { AdcMin[AdcChNum] = 0x1ff;//9位ADC } else { AdcMin[AdcChNum] = 0x3ff;//10位ADC } AdcCount[AdcChNum] = 0; } AdcChNum ++;//准备下个通道 AdcChNum &= 3; ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1);//64分频 } |