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

📄 5ptwendu1.c

📁 将AD7708配置成5个差分通道
💻 C
字号:
/****************************************************************************************************************************
FILE NAME: THREEVOLTAGE.C
AUTHOR: HU HONG BO
DATE: 2008.3.6
FUNCTION: 将AD7708配置成5个差分通道,用前5个通道,测量五路电压-20~100度,并在LED上显示
*****************************************************************************************************************************/
#include<reg52.h>
#include<math.h>

#define LED_SEG P2   //段码控制
#define LED_BIT P0   //位控制
unsigned char code table[13]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0x9e,0x02,0x00};//字形表0~9,E,- ,灭
idata unsigned int  time=0;//软件计时
idata unsigned int  period=1000;//1秒计时
data unsigned char CHnum=1;//通道号
data unsigned char Vcode[7]={0,0,0,0,0,0,0};//待显示的数字存储数组,第一个和第二个是通道号或函数标志,第三个空,后4个是电压量的有效数字
data unsigned char Dis_dat[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//待显示的数字的字形,初值全灭
bit  EA_f;//用以保存EA状态
bit  nopt;//空操作位
bit  T2ms=1;//2毫秒计时
bit  opAD_flag=1;//是否操作AD7708标志
bit  rdAD=0;//是否读取AD转换结果标志
bit  v2c_flag=0;//是否需要刷新换显示内容
bit  disp_flag=0;//0为循环显示,1为单通道显示
sbit CS=P1^3;//cs of AD7708
sbit DIN=P1^1;//data in of AD7708
sbit DOUT=P1^2;//data out of AD7708
sbit DRDY=P3^2;//ready of AD7708

sbit SCLOCK=P3^3;//clock of AD7708

void delay(unsigned int );//延时函数
void writetoreg(unsigned char);//写AD7708寄存器函数
float readAD(void);//读AD7708转换结果函数
void opAD(void);//操作AD7708函数
void disbyte(void);//显示函数
void single_disp(void);//单通道显示
void circle_disp(void);//循环显示
float AD2V(float);//AD值转换为浮点数电压量
void V2CODE(float);//浮点数转换到显示缓存数组


void clock0_init() reentrant using 0//计时器0初始化函数
{
  TCON=0x00;
  TR0=0;
  TH0=0xFC;
  TL0=0x18;//1ms作为基准定时,用模式1,这样1s需要1000个定时过程
  TR0=1;
}


void main() //主函数
{
   data float ADresult=0.0;
   data float Voltage=0.0;


   TMOD=0x01;     //定时器0模式1,
   TH0=0xFC;      //T0定时1ms初始值
   TL0=0x18;

   ET0=1;//打开定时器0中断允许
   EA=1;//开总中断
   TR0=1;//开定时器0

   while(1)
   {

      if(opAD_flag){EA_f=EA;EA=0;opAD_flag=0;opAD();EA=EA_f;}//如果操作AD标志为1则去处理AD

      if(rdAD){
                  EA_f=EA;
                  EA=0;
                  ADresult=readAD();  //读取AD转换结果
                  EA=EA_f;
                  rdAD=0;
                  v2c_flag=1; //刷新显示标志置位
              }
      if(v2c_flag){
                        EA_f=EA;
                        EA=0;
	                Voltage=AD2V(ADresult);
	                V2CODE(Voltage);
                        EA=EA_f;
			v2c_flag=0;
                  }
   }

}

/*操作AD7708函数*/
void opAD()
{
       data int tim;
       data unsigned char adcon; //adcon配置AD7708的ADCON寄存器
       tim=1000;
  /* PRECONFIGURE...*/
       DRDY=1;
 
       while(tim--);

       SCLOCK=1;
       DIN=1;
       DOUT=1;
       CS=1;

       writetoreg(0x03); //write to communication register. The next step is writing to FILTER REGISTER
       writetoreg(0x45); //set the FILTER register

       switch(CHnum)//根据通道号,计算ADCON的CH5 CH4 CH3 CH2 CH1 CH0值,
       { case 1: adcon=0x87; break;
         case 2: adcon=0x97; break;
         case 3: adcon=0xa7; break;
         case 4: adcon=0xb7; break;
         case 5: adcon=0xc7; break;
         
         
       }             //确保1~5通道的adcon分别为0x8f,0x9f,0xaf,0xbf,0xcf输入范围为0~+2.56
       writetoreg(0x02); //write to communication register. The next step is writing to ADC CONTROLO register
       writetoreg(adcon); //Unipolar,
       writetoreg(0x01);//writing to communication register, the next step is write to MODE register
       writetoreg(0x13);//chopping,REFIN1,10 pseudo-differential input,continuous conversion mode
       while(DRDY);
       rdAD=1;

}

/*写AD7708寄存器*/
void writetoreg(unsigned char byteword)	 //The subroutine write byteword to the corresponding registers of AD7708
{
  data unsigned char temp,i;
  CS=0;
  temp=0x80;
  for(i=0;i<8;i++)
  {
      if((temp&byteword)==0)
           DIN=0;
      else DIN=1;
      SCLOCK=0;
      SCLOCK=1;
      temp=temp>>1;
  }
  CS=1;
}

/*读AD7708转换结果*/
float readAD()
{
        data unsigned char j;
        data float temp=0.0;
        //while(DRDY);//wating for finishing converting
	writetoreg(0x44);//write to communication register.The next step is reading data from ADC Data register
	CS=0;
        for(j=0;j<16;j++)
     	{
           SCLOCK=0;
	   SCLOCK=1;
           if(DOUT==1) temp+=pow(2,15-j);
         }
         CS=1;
         return(temp);
}

/*根据转换公式把AD转换结果转换为电压量*/
float AD2V(float ADresult)
{
	ADresult=ADresult/32768-1;
    ADresult=ADresult*2.56;
  return(ADresult);      //输入范围配置成0~+2.56时候,增益为1
}

/*显示*/
void disbyte()
{
  data unsigned char i;
  for(i=0;i<7;i++)
  {
    LED_BIT=(0x40>>i); //P0位选,选通第N个数码管7654321的顺序,P0.6~P0.0
    LED_SEG=Dis_dat[i];//从P2口输出字形码
    delay(5);
  }
  LED_SEG=0x00;//全灭
}

/*循环显示控制*/
void circle_disp()
{
  CHnum++;
  if(CHnum>5) CHnum=1;
  opAD_flag=1;

}

/*单通道显示控制*/
void single_disp()
{

}

/*浮点数转换到显示缓存数组*/
void V2CODE(float value)
{
  data int Vtemp;
  data unsigned int i;
  data unsigned char DotId;//DotId记录小数点位置
  //EA=0;
  Vcode[0]=CHnum;//通道号
  if(value<0) {Vcode[1]=11;value=-1*value;}//加负号“ -”并取其绝对值
  else Vcode[1]=12;//正数,符号位灭
  if(value<1.0) {DotId=3; Vtemp=(int)(value*1000);}
  else {
         for(i=1;i<3;i++)
		     if(value<pow(10,i))
			    {
				  Vtemp=(int)(value*pow(10,4-i));
				  DotId=i+2;
                  break;
				}
       }
  for(i=6;i>2;i--)
     {
	   Vcode[i]=Vtemp%10;
           Vtemp=Vtemp/10;
     }

  for(i=0;i<7;i++)
  {
     Dis_dat[i]=table[Vcode[i]];   //转换成字形并放入DiCATDAT[]数组
     if(i==DotId) {Dis_dat[i]|=0xFD;}//加小数点
  }
  //EA=1;
}


/*延时*/
void delay(unsigned int time)
{
  data unsigned char i;
  EA_f=EA;//保存当前EA状态
  EA=0;   //软件延时的时候关中断
  while(time--)
  {
    for(i=0;i<20;i++) {;}
  }
  EA=EA_f;
}




/*定时器0中断处理*/
void clk0_int(void) interrupt 1 using 0
{
  T2ms=!T2ms;
  if(T2ms)   disbyte();//2ms显示一次

     if(++time==period)  //1秒时间到
     {
        if(disp_flag)  single_disp();
        else circle_disp();
        time=0;//重新开始计数
     }

  clock0_init();//初始化定时器
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -