⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad._c

📁 嵌入式单片机控制温度传感的无线收发方案!
💻 _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 + -