|
adc.cpp(略)
hotpower 發表于 2007-8-23 02:26 AVR 單片機 ←返回版面 舉報該貼
#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[i] = 0;
AdcCount[i] = 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分頻
} |
|