ll7705.c

来自「7705驱动程序图3-2 AD7705电路 AD7705的串行数据接口包括5个」· C语言 代码 · 共 249 行

C
249
字号
#include <reg52.h>
#include <MATH.H>
#include <string.h>
#include"0801.h"
#include"key.h"
#include"cepinlv.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit ad_sclk=P1^0;   
sbit ad_cs=P1^1;	 //AD转换器AD7705硬件I/O定义
sbit ad_reset=P1^2;      //AD7705复位                       
sbit ad_din=P1^3;         //AD输入输出I/O
sbit ad_dout=P1^4;       //AD输入输出I/O
sbit ad_drdy=P1^5;       //AD7705
sbit resa=P2^0;
sbit resb=P2^1;
sbit resc=P2^2;
sbit resd=P2^3;
sbit aa=P2^5;
sbit bb=P2^6;
data unsigned int lsb;
data unsigned long voltage;
unsigned char tongdao=1;
bit jzh_flag;                      //校准标志,此时不处理采样
bit ready_flag;                    //AD转换结束标志
bit fuhao;                 //极性正负标志位
float f;
/*AD转换器命令写函数,标准移位寄存器方式,高位在前,每次8位*/
void ad_write(unsigned char command)
{
data unsigned char i;
        ad_sclk=1;
        ad_cs=0;
        i=8;
	while(i!=0)
	        {
                ad_sclk=0;
	        ad_din=command&0x80;
	        ad_sclk=1;
	        command=command<<1;
	        i--;
	        }
        ad_din=1;					//送完命令置'1',准备输入数据
        ad_cs=1;
}
//设置A/D转换模式.然后可以连续读出结果.
//***************AD设置增益,gain=0,1,2,3,4,5,6,7 分别代表1,2,4,8,16,32,64,128倍放大
//***********jixing=0,为双极性,=1 为单极性

//设置A/D转换模式.然后可以连续读出结果.
void ad_set(unsigned char ch,unsigned char gain)   //ch=1,2;gain=0,1,2,3(1,2,4,8,16,32,64,128)
{  // data unsigned char i=0x46;             //单极性,加缓冲器
    data unsigned char i=0x42;             //双极性,加缓冲器
   data unsigned char j=gain;
        j=j<<3;
        i=i|j;
        ad_write(0x0f+ch);      //写通讯寄存器,选择通道1,2,并建立下一个操作为写设置寄存器
        ad_write(i);            //写设置寄存器,清除FSYNC,建立增益等运行条件
                                //初始化被选通道为自校准模式,有缓冲器
}
//A/D转换结果读取函数.
unsigned int ad_pro()
{  data unsigned int j,k=0;
   data unsigned char kk;
    while(ad_drdy==1);
   ad_write(0x38);		//读通讯寄存器,选择通道1,2,并建立下一个操作位读数据寄存器???
   //ad_write(0x39);     //读通道2
   ad_sclk=1;              //读取结果
   ad_cs=0;
   kk=16;
   while(kk!=0)
  {  k=k<<1;
     ad_sclk=0;
     j=ad_dout;
     ad_sclk=1;
     k=k|j;
     kk--;
   }
     ad_cs=1;
     ad_dout=1;
     return(k);            
}
//AD初始化复位,50赫兹输出速率
ad_init()
{
 data unsigned int i;
 data unsigned char j;
 ad_reset=1;                //复位AD转换器1--0--1脉冲,100ms
 j=2;
 while(j!=0)
     {
      ad_reset=!ad_reset;
      i=13000;
      while(i!=0)
          {
           i--;
          }
      j--;
     }
 ad_write(0x20);            //写通讯寄存器,选择通道1,并建立下一个操作为写时钟寄存器
 ad_write(0x00);            //写时钟寄存器,设时钟信号位于使用的主时钟信号(2.4576MHz)
}
void ad_jiaozhun()                //初始化A/D,校准两个通道.在通道一上持续工作.
  {  ad_init();
  /////////
     ad_set(1,0);
    while(ad_drdy==0);
    while(ad_drdy==1);
    while(ad_drdy==0);
    while(ad_drdy==1);
    //  ad_write(0x20);            //写通讯寄存器,选择通道1,并建立下一个操作为写时钟寄存器,掉电.
    //  ad_write(0x14);           //A/D基准断电.
     }


void voltagedisplay(unsigned long dat)
{  bit xianshi;
  unsigned char aa;
 xianshi=1;          //为1不显示
 if(fuhao)
 l_data[0]=16;          //无显示
 else l_data[0]=18;      //显示 -
 l_data[1]=dat/1000000;
 if(l_data[1]>1)
 {for(aa=1;aa<8;aa++)
  l_data[aa]=15;  }
  else{xianshi=0;
  if(l_data[1]==0)
    { l_data[1]=16;xianshi=0;}  
 l_data[2]=dat%1000000/100000;
   
 if(l_data[2]==0&&xianshi)
  { l_data[2]=16;xianshi=1;}
  else  xianshi=0;
 l_data[3]=dat%100000/10000;  
 if(l_data[3]==0&&xianshi)
  { l_data[3]=16;xianshi=1;}
  else xianshi=0;
 l_data[4]=dat%10000/1000;
 if(l_data[4]==0&&xianshi)
  { l_data[4]=16;xianshi=1;}
  else xianshi=0;
 l_data[5]=dat%1000/100;
 l_data[6]=dat%100/10;
 l_data[7]=dat%10;}
 lcdwd1();
   }
void voltagetest()
{ unsigned char gain=0;
  ad_set(1,0);
  lsb=ad_pro();
 if(gain==0)
{
//电压增益为1时    //最大1.7v
 if(lsb>=32782)
  {fuhao=1;
//  voltage=(lsb-32782)*6250/1639;}    //没有放大的时候 
   voltage=(lsb-32782)*4195/100;}
   else {fuhao=0;
	 voltage=(32782-lsb)*4195/100;}
 	 if(voltage<100000)
    {   gain=3;
      ad_set(1,gain);
	  lsb=ad_pro();}	 
 }
if(gain==3)
{
//电压增益为8时    //最大能测到正负310mv
   if(lsb>=32878)
   {fuhao=1;
    voltage=(lsb-32878)*20000/3813-10;}    //
	else 
	{fuhao=0;
	 voltage=(32878-lsb)*20000/3813-10;}
  //  if(voltage<1000)
   // { ch=6;  ad_set(1,ch);}
	 if(voltage>90000)
	{ gain=0;  ad_set(1,gain);}
	voltagedisplay(voltage);
  }
}
  void currenttest()
  { unsigned int currentvalue; 
    voltagetest();                 //零偏值可能不一样   要另外确定
	currentvalue=voltage/100;    //具体值不确定  
      }


 //resa.b.c.d都为1111时为零输入,0111切换到1k档
 //1011切换到10k档,1101切换到100k档,1110切换到1M档 
  void restest()       ///每一档的 Vo=k*Rx系数都不一样 要具体再测量
  { float resvaule;
    unsigned int vau;   
  resa=1;resb=1;resc=1;resd=0;
    voltagetest(); //零偏值可能不一样   要另外确定  
    vau=1;
     if(voltage<1042)               //  当电压在1m档太小时换成100k档   具体值不确定
  {resa=1;resb=1;resc=0;resd=1;
    voltagetest();
	  vau=10;}                 //零偏值可能不一样   要另外确定  
   if(voltage<1042)               //  当电压在100k档太小时换成10k档   具体值不确定
{   resa=1;resb=0;resc=1;resd=1;
    voltagetest(); 
	   vau=100;   }                //零偏值可能不一样   要另外确定  
   if(voltage<1042)               //  当电压在10k档太小时换成1k档   具体值不确定
 { resa=0;resb=1;resc=1;resd=1;
    voltagetest();//零偏值可能不一样   要另外确定  
     vau=1000;}
    resvaule=(float)voltage*(1000000/vau)/100000;    //Vo=k*Rx  k系数不确定              
        
	  }

  void temdisplay()
  {}
void main()
{   

ad_init();                  //复位并初始化AD
ad_set(1,0);
while(1)                    //未加显示部分
{judge_key();
//keyvalue=0x04;
if(keyvalue==0x01)
{
  currenttest();
}
if(keyvalue==0x02)
{  aa=1;     //电压
   bb=0;
   voltagetest();

    }
 if(keyvalue==0x03)
 { 
 restest();
    }
  if(keyvalue==0x04)  
 {   Frequency_Measure();
      lsb=f*100;
//	   display(lsb);
}
  	}
if(keyvalue==0x00)
{  
  temdisplay();  
  }
    }

⌨️ 快捷键说明

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