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

📄 ad_contrl.c

📁 AD7841模数转化程序
💻 C
字号:
/******************************************************************************
*
** 函数原型:unsigned int ADS7841_Read_Data(unsigned char Channel);
** 功    能:SPI总线的A/D ADS7841 驱动程序
** 入口参数:unsigned char Channel   表示选择读取通道
** 出口参数:unsigned int   返回所读取得12位数据。
** 说    明:ADS7841为12位A/D,先对其进行设置:数据位D0---D7,其中D0---D1是
**           设置ADC的功耗模式,D2是模拟输入通道设置,H为4个单通道,L为两个
**           差分输入,D3为mode,当mode(pin)接地时为12位采样方式,接高电平时
**           mode为1时8位采集,为0时12位采集,D4---D6为输入通道选择,D7为起始位
*
*******************************************************************************/

#include "SPCE061A.h"
#include "AD_Contrl.h"

void Init_IOA_IOB(void)
{
	*P_IOA_Dir|=0xe400;               //设置IOA15(DCLK)=(1,1,0),IOA14(CS)=(1,1,1)
	*P_IOA_Dir&=0xe7ff;               //IOA13(DIN)=(1,1,0)IOA12(BUSY)=(0,0,0)
	                                  //IOA11(DOUT)=(0,0,0),IOA10(MODE)=(1,1,0)
	*P_IOA_Attrib|=0xe400;            //其他位不变
	*P_IOA_Attrib|=0xe7ff;
	
	*P_IOA_Data|=0x4000;
	*P_IOA_Data&=0x41ff;
	
	*P_IOB_Dir=0xffff;                //设置IOB口为同相低电平输出口
	*P_IOB_Attrib=0xffff;
	*P_IOB_Data=0x0000; 
}
							




unsigned int AD7841_Read_Data(void)
{
	unsigned int AD_Result=0,a=0,b;
    unsigned char i,DataInput=0;
    

	
	*P_IOA_Dir |= 0x2000;			    //DIN(IOA13)为带数据缓存器的低电平输出。
	*P_IOA_Attrib |= 0x2000;
	*P_IOA_Data &= 0xdfff;
    
    DataInput=0x0094;                   //S=1;A2A1A0=001(CH1);MODE=0(12位采集);SGL/DIF=1(4个单通道);PD1PD0=00
    DataInput=DataInput<<6;
    
    *P_IOA_Data &= 0xbfff;			    // CS(IOA14)为低电平
    delay(1);
    *P_IOA_Data &= 0x5fff;			    // DCLK(IOA15)为低电平	 DIN(IOA13)为低电平
    delay(3);
	
	for(i=0; i<8; i++)
	{
		a = DataInput;
		a &= 0x2000;                    //保留DataInput的13位,其他的全为零
		*P_IOA_Data &= 0xdfff;	        // IOA13 = 0,其他的不变。
		*P_IOA_Data |= a;               //将DataInput的13位送给IOA13,并不影响IOA的其他位。
			
		*P_IOA_Data &= 0x7fff;	        // clk low		产生高电平宽度为delay(3)的脉冲,供CLK(8次)。	
		delay(3);                       //延迟,清看门狗???			
		*P_IOA_Data |= 0x8000;	        // clk high			

		DataInput = DataInput << 1;
	}
    delay(1);
    *P_IOA_Data &= 0x7fff;	            // clk low
        
    while(*P_IOA_Data&0x1000)       
	{
		delay(1);		
		*P_IOA_Data |= 0x8000;	        // clk high			
		delay(1);			
		*P_IOA_Data &= 0x7fff;	        // clk low		产生高电平宽度为delay(3)的脉冲。
	    
	    *P_Watchdog_Clear = 0x0001;
	}                                   //当BUSY脚由高变为低时,则开始数据输出
	delay(1);	
	

	for(i=0;i<12;i++)                   //读取12位AD转换值
	{
		*P_IOA_Data |= 0x8000;	        // clk high
		delay(1);
		
		b=0x0800;
		b &= *P_IOA_Data;               //取出DOUT (IOA11)的数据。
		b=b>>11;
		
		a |= b;
		AD_Result=a;
	    a=a<<1;
	    
	    *P_IOA_Data &= 0x7fff;	        // clk low
	}

	for(i=0;i<4;i++)                    //滤掉多余的4个时钟
	{
		*P_IOA_Data |= 0x8000;          // clk high将CLK置1。且不影响其他位,
		delay(1);
		*P_IOA_Data &= 0x7fff;	        // clk low
		delay(1);
	}
	*P_IOA_Data |= 0x4000;			    // CS(IOA14)为高电平,禁止芯片
    AD_Result&=0x0fff;                  //屏蔽高4 位 	
    return AD_Result;
}


void delay(unsigned int i)
{
	for(;i>0;i--);
}
	



/*

unsigned int ADS7841_Read_Data(unsigned char Channel)          //Channel=0:CH0;1:CH1;2:CH2;3:CH3;
{
        unsigned int ADCResult=0;
        unsigned char DataInput=0;
        unsigned char i,ADS7841_CHANNEL;
        
    switch (Channel)
    {
        case 0:ADS7841_CHANNEL=0x10;break;
        case 1:ADS7841_CHANNEL=0x50;break;
        case 2:ADS7841_CHANNEL=0x20;break;
        case 3:ADS7841_CHANNEL=0x60;break;
        default:ADS7841_CHANNEL=0x10;break;        
    }
    DataInput=ADS7841_S|ADS7841_CHANNEL|ADS7841_MODE|ADS7841_SGL_DIF|ADS7841_POWER_DOWN;

        DCLK=0;
        DIN=0;
        CS=VALID;
        for(i=0; i<8; i++)
        {
          DIN=DataInput&0x80;
          DataInput=DataInput<<1;
          DCLK=0;
          NOP;
          DCLK=1;                       //模拟SPI串行接口 发送数据
        }
   NOP;
   DCLK=0;
              while(BUSY)
              {
   NOP;
   DCLK=1;
   NOP;
   DCLK=0;
             }  //当BUSY脚由高变为低时,则开始数据输出//
              NOP;
  for(i=0;i<12;i++)
  {
   DCLK=1;
  ADCResult=(ADCResult<<1)|DOUT;    //模拟SPI串行接口 接收数据
     DCLK=0;
     NOP;
   }
   for(i=0;i<4;i++)
  {
   DCLK=1;
   NOP;
   DCLK=0;
   NOP;
  }
        CS=INVALID;
        return ADCResult;
}





#include <Reg52.h>
#include <Intrins.h>
#include <AbsAcc.h>

#include "meter.h"
////////////////////////////////////
uint ADS7841_READ(uchar CH)
{
    uchar  i, dt;
    uint   AD_RESULT=0;
      
    CS7841=0;                       // 芯片允许
                     _nop_();                        
    SCK=0;
    SDI=0;
    dt=CH;
    i=0;
    while(i<8)                      //写入8位控制字
    {
        if(dt>=0x80)  
             SDI=1;	            //时钟上升沿锁存SDI
        else 
             SDI=0;
        _nop_();
        SCK=1;                     //开始发送命令字
        _nop_();
        dt<<=1;
        SCK=0;                     //时钟脉冲,一共24个
        
        i++;
    }
                                  //等待转换完成(20us)
    for(i=0;i<20;i++)    {    _nop_();   }
    
    SCK=1;
    i=0;
    while(i<12)                     //读取12位AD转换值
    {
        AD_RESULT<<=1;    _nop_();
        SCK=0;
        if(SDO)     
            AD_RESULT|=0x0001;     //用时钟的下降沿读取
        if(i==7)        { _nop_();  _nop_(); }
        SCK=1;
        
        i++;
    }                                          
    i=0;
    while(i<4)                     //滤掉多余的4个时钟
    {
                          _nop_();
        SCK=0;           _nop_();
        SCK=1;
        
        i++;
    }
    SDI=1;
    CS7841=1;                      //禁止芯片
                                
    AD_RESULT&=0x0fff;             //屏蔽高4 bit                 

    return AD_RESULT;                        
}
///////////////////////////////////////////////////
uint ADS7841_READ(uchar CH)
{
    uchar  i;
    uchar  dt;
    uint   AD_RESULT=0;
      
    SCK=0;
    SDI=0;
    CS7841=0;                       // 芯片允许
    _nop_();                        
    
    dt=CH;
    i=0;
    while(i<8)                      //写入8位控制字
    {
        if(dt>=0x80)     SDI=1;	      //时钟上升沿锁存SDI
        else             SDI=0;
        
        SCK=1;                     //开始发送命令字
        SCK=0;                     //时钟脉冲,一共24个
        
        dt<<=1;
        i++;
    }
    SDI=0;
                                  //等待转换完成(20us)
    for(i=0;i<20;i++)    {    _nop_();   }
    
    i=0;
    SCK=1;
    while(i<12)                     //读取12位AD转换值
    {
        AD_RESULT<<=1;    
        SCK=0;
        
        if(SDO)         AD_RESULT|=0x0001;     //用时钟的下降沿读取
        if(i==7)        { _nop_(); _nop_(); }

        _nop_();        
        SCK=1;
        
        i++;
    }                                          
    i=0;
    while(i<4)                     //滤掉多余的4个时钟
    {
        SCK=0;           
        SCK=1;
        
        i++;
    }
    SCK=0;
    
    CS7841=1;                      //禁止芯片
                                    
    AD_RESULT&=0x0fff;             //屏蔽高4 bit                 

    return AD_RESULT;                        
}

*/

⌨️ 快捷键说明

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