📄 ad._c
字号:
/********************************
ATMega8 查询方式 A/D转换测试程序
文件名:main.c
编译:WinAVR-20070122
外部4MHz晶振
*******************************/
#include "confg.h"
#define _BV(n) (1<<n)
static unsigned int g_aAdValue[8]; //A/D转换缓冲区
//AD转换8次去掉最高和最低后取平均值返回
unsigned int AdcConvertStd(void)
{
char i;
unsigned int ret;
char max_id,min_id,max_value,min_value;
ADMUX=0X45;//参考电压VCC
ADCSRA=_BV(ADEN);//使能ADC,单次转换模式
//连续转换8次
for(i=0;i<8;i++)
{
ADCSRA|=_BV(ADSC);
delay_us(30);
while(ADCSRA&_BV(ADSC))
delay_us(30);
ret=ADCL;
ret|=(unsigned int)(ADCH<<8);
g_aAdValue[i]=ret;
}
ret=0;
for(i=1;i<8;i++)
ret+=g_aAdValue[i];
//找到最大和最小值索引
ret/=7;
max_id=min_id=1;
max_value=min_value=0;
for(i=1;i<8;i++)
{
if(g_aAdValue[i]>ret)
{
if(g_aAdValue[i]-ret>max_value)
{
max_value=g_aAdValue[i]-ret;
max_id=i;
}
}
else
{
if(ret-g_aAdValue[i]>min_value)
{
min_value=ret-g_aAdValue[i];
min_id=i;
}
}
}
//去掉第一个和最大最小值后的平均值
ret=0;
for(i=1;i<8;i++)
{
if((i!=min_id)&&(i!=max_id))
ret+=g_aAdValue[i];
}
if(min_id!=max_id)
ret/=5;
else
ret/=6;
ADCSRA=0;//关闭ADC
return ret;
}
void adinit()
{
//ad转换相关的寄存器的初始化
//ACSR=0x80; //别忘了关掉模拟比较器的电源哦
// SFIOR=0x00;
//IO初始化
DDRB|=_BV(DDB0);
PORTB|=~_BV(PB0);
//ad转换相关的寄存器的初始化
// ACSR=0x80; //别忘了关掉模拟比较器的电源哦
// SFIOR=0x00;
}
//AD转换8次去掉最高和最低后取平均值返回
unsigned int AdcConvertDin(void)
{
char i;
unsigned int ret;
char max_id,min_id,max_value,min_value;
ADMUX=0X44;//参考电压VCC
ADCSRA=_BV(ADEN);//使能ADC,单次转换模式
//连续转换8次
for(i=0;i<8;i++)
{
ADCSRA|=_BV(ADSC);
delay_us(30);
while(ADCSRA&_BV(ADSC))
delay_us(30);
ret=ADCL;
ret|=(unsigned int)(ADCH<<8);
g_aAdValue[i]=ret;
}
ret=0;
for(i=1;i<8;i++)
ret+=g_aAdValue[i];
//找到最大和最小值索引
ret/=7;
max_id=min_id=1;
max_value=min_value=0;
for(i=1;i<8;i++)
{
if(g_aAdValue[i]>ret)
{
if(g_aAdValue[i]-ret>max_value)
{
max_value=g_aAdValue[i]-ret;
max_id=i;
}
}
else
{
if(ret-g_aAdValue[i]>min_value)
{
min_value=ret-g_aAdValue[i];
min_id=i;
}
}
}
//去掉第一个和最大最小值后的平均值
ret=0;
for(i=1;i<8;i++)
{
if((i!=min_id)&&(i!=max_id))
ret+=g_aAdValue[i];
}
if(min_id!=max_id)
ret/=5;
else
ret/=6;
ADCSRA=0;//关闭ADC
return ret;
}
int vcon(long a)
{
return (a*1235)/AdcConvertStd();
}
//进行温度转换
long temperature(long r)//温度都乘上了10的5次
{
long temper;
if(r>908300||r<2500)
temper=0xffffffff;
else
if(r>580450)
temper=-2*r-1121800;
else if(r>325400)
temper=-4*r-4840;
else if(r>189400)
temper=-8*r+1113900;
else if(r>146350)
temper=-10*r+1674800;
else if(r>70670)
temper=-20*r+3068600;
else if(r>36415)
temper=-40*r+4771000;
else if(r>19855)
temper=-90*r+6482000;
else if(r>11370)
temper=-180*r+8199400;
else if(r>5786)
temper=-360*r+10213000;
else
temper=-890*r+13095000;
return temper;
}
//AD转换
void ad_convert(void)
{
int i=0,vcc,vdin,temp;
long r;
adinit();
vcc=vcon(1024);//获得Vcc真实电压
vdin=vcon((long)AdcConvertDin());//获得ACD5的电压值
//热敏电阻Rf阻值的计算:(R0是测量端的电阻,是4.7k)
//根据Vin/R0=(Avcc-Vin)/Rf得出
//Rf=(Avcc-Vin)*R0/Vin
r=((((long)vcc-(long)vdin)*47000)/(long)vdin)/10;
temp=temperature(r)/10000;
// printf("vcc value is %d\r\n",vcc);
//printf("temp value is %d\r\n",temp);
Tx_Buf[2]=temp;
Tx_Buf[3]=temp>>8;
Tx_Buf[4]=vcc;
Tx_Buf[5]=vcc>>8;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -