yanniwang

利用ADuC7026读取AD7192模数转换器数据

0
阅读(6423)

AD7192是一款适合高精密测量应用的低噪声完整模拟前端。它集成一个低噪声、24位Σ-Δ型模数转换器(ADC)。片内低噪声增益级意味着可直接输入小信号。

这款器件可配置为两路差分输入或四路伪差分输入。片内通道序列器可以使能多个通道,AD7192按顺序在各使能通道上执行转换,这可以简化与器件的通信。片内4.92 MHz时钟可以用作ADC的时钟源;或者,也可以使用外部时钟或晶振。该器件的输出数据速率可在4.7 Hz至4.8 kHz的范围内变化。

这款器件提供两种数字滤波器选项。滤波器的选择会影响以编程输出数据速率工作时的均方根噪声和无噪声分辨率、建立时间以及50 Hz/60 Hz抑制。针对要求所有转换均需建立的应用,AD7192具有零延迟特性。

这款器件的工作电源电压为3 V至5.25 V,功耗为4.35 mA,采用24引脚TSSOP封装。

AD7192的串行接口包含四个信号:CS、DIN、SCLK和DOUT/RDY。DIN线路用于将数据传输至片内寄存器中,DOUT/RDY则用于从片内寄存器中获取数据。SCLK是器件的串行时钟输入,所有数据传输(无论是DIN上还是DOUT/RDY上)均相对于SCLK信号进行。
DOUT/RDY引脚也可用作数据就绪信号;当输出寄存器中有新数据字可用时,该线路变为低电平。对数据寄存器的读操作完成时,该线路复位为高电平。数据寄存器更新之前,该线路也会变为高电平,以提示此时不应读取器件,确保寄存器正在更新时不会发生数据读取操作。CS用于选择器件。在多个器件与串行总线相连的系统中,可以用CS对AD7192进行解码。
下面是通过ADUC7026实现对AD7192数据的读取的示例程序,主要利用ADUC7026的GPIO端口模拟实现SPI功能。

/********************************************************************************
 Author : CAC (China Applications Support Team) 

 Date :   January, 2012

 File name :   ADuC7026Driver.c

 Description :   Use the GPIO to simulate the SPI communication of AD7192

 Hardware plateform :   ADuC7026 and AD7190/92EBZ
********************************************************************************/

#include "ADuC7026.h"
#include "ADuC7026Driver.h"
#include "stdio.h"

#pragma import(__use_no_semihosting_swi)

/*    Function Pointers for Interrupts  */
// Copied from irq_arm.c in Keil uV4, required 
tyVctHndlr    IRQ     = (tyVctHndlr)0x0;
tyVctHndlr    SWI     = (tyVctHndlr)0x0;
tyVctHndlr    FIQ     = (tyVctHndlr)0x0;
tyVctHndlr    UNDEF   = (tyVctHndlr)0x0;
tyVctHndlr    PABORT  = (tyVctHndlr)0x0;
tyVctHndlr    DABORT  = (tyVctHndlr)0x0;

void    IRQ_Handler   (void) __irq;
void    SWI_Handler   (void) __irq;
void    FIQ_Handler   (void) __irq;
void    Undef_Handler (void) __irq;
void    PAbt_Handler  (void) __irq;
void    DAbt_Handler  (void) __irq;

void    IRQ_Handler(void) __irq
{
    if ( *IRQ !=0x00)
    {
        IRQ();
    }
}

void    FIQ_Handler(void) __irq
{
    if ( *FIQ !=0x00)
    {
        FIQ();
    }
}

void    SWI_Handler(void) __irq
{
    if ( *SWI !=0x00)
    {
        SWI();
    }
}

void    Undef_Handler(void)__irq 
{
    if ( *UNDEF !=0x00)
    {
        UNDEF();
    }
}

void    PAbt_Handler(void) __irq
{
    if ( *PABORT !=0x00)
    {
        PABORT();
    }
}

void    DAbt_Handler(void) __irq
{
    if ( *DABORT !=0x00)
    {
        DABORT();
    }
}
/*    Function Pointers for Interrupts  */

/* GPIO Control */
unsigned char ADuC7026InputBit(unsigned char GPIONum)
{
    unsigned long int Temp;
    unsigned char Data;

    Temp=0xFFFFFFFF-(1<<((GPIONum&0x0F)+24));

    switch(GPIONum>>4)
    {
        case	0:
            GP0DAT&=Temp;
            Data=GP0DAT;		
            break;
        case	1:
            GP1DAT&=Temp;
            Data=GP1DAT;
            break;
        case	2:
            GP2DAT&=Temp;
            Data=GP2DAT;
            break;
        case	3:
            GP3DAT&=Temp;
            Data=GP3DAT;
            break;
        case	4:
            GP4DAT&=Temp;
            Data=GP4DAT;
            break;
    }
    if((Data&(1<<(GPIONum&0x0F)))==(1<<(GPIONum&0x0F)))
    {
        Data=1;
    }
    else
    {
        Data=0;
    }

    return Data;
}

void ADuC7026OutputBit(unsigned char GPIONum, unsigned char Data)
{
    unsigned long int Temp;

    Temp=1<<(GPIONum&0x0F);



    switch(GPIONum>>4)
    {
        case	0:
            GP0DAT|=(Temp<<24);
            if(Data==0)
    		{
                GP0CLR=(Temp<<16);
    		}
        	else
    		{
                GP0SET=(Temp<<16);	
    		}
            break;
        case	1:
            GP1DAT|=(Temp<<24);
            if(Data==0)
    		{
                GP1CLR=(Temp<<16);
    		}
        	else
    		{
                GP1SET=(Temp<<16);	
    		}
            break;
        case	2:
            GP2DAT|=(Temp<<24);
            if(Data==0)
    		{
                GP2CLR=(Temp<<16);
    		}
        	else
    		{
                GP2SET=(Temp<<16);	
    		}
            break;
        case	3:
            GP3DAT|=(Temp<<24);
            if(Data==0)
    		{
                GP3CLR=(Temp<<16);
    		}
        	else
    		{
                GP3SET=(Temp<<16);	
    		}
            break;
        case	4:
            GP4DAT|=(Temp<<24);
            if(Data==0)
    		{
                GP4CLR=(Temp<<16);
    		}
        	else
    		{
                GP4SET=(Temp<<16);	
    		}
            break;
    }
}
/* GPIO Control */

// add the c file here
void ADuC7026InitializePll(void)
{   
    //41.78MHz
    POWKEY1 = 0x01;             //Start PLL setting,changeless
    POWCON=0x00;
    POWKEY2 = 0xF4;             //Finish PLL setting,changeless
}

void ADuC7026InitializeUart(void)
{
    // Setup tx & rx pins on SPM 0 and SPM 1
    GP1CON |= 0x11;
 
    //Initiate the UART Port to 115200bps
    // CD = 0 !		 
    COMCON0 = 0x80;                 // Setting DLAB
    COMDIV0 = 0x0B;                 // Setting DIV0 and DIV1 to DL calculated
    COMDIV1 = 0x00;

    COMCON0 = 0x07;                 // Clearing DLAB
    // fractional divider
    COMDIV2 = 0x883E;             	// M=1
                                	// N=01101010101  =853
                                	// M+N/2048	 =1.4165
                                    //41.78MHz/(16*2*2^CD*DL*(M+N/2048))	 //CD=0  DL=0B=11
                                    //115.2Kbps  M+N/2048 =1.0303   M=1, N=	 62=0x3EH=000 0011 1110
                            		//comdiv2=0x883E
    	
}

void ADuC7026InitializeInterrupt(void)
{
    // disable all FIQs and IRQs
    FIQEN=0x00;
    IRQEN=0x00;
}

void ADuC7026Initialization(void)
{
    ADuC7026InitializePll();
    ADuC7026InitializeInterrupt();
    ADuC7026InitializeUart();

    /* */

    ADuC7026OutputBit(CS, 1);
    ADuC7026OutputBit(SYNC, 1);
    ADuC7026OutputBit(SCLK, 1);
    ADuC7026OutputBit(SDI, 1);
    ADuC7026InputBit(SDO);
}

// delay for Time*1ms, at 41.78MHz CLK.     41.78M / 256 / 163 = 1K
void ADuC7026DelayMs( unsigned int TimeMs)  	
{           					 
    unsigned int i;     		 

    for(i=0; i1) {}
        T1CON = 0x48;       // Disabled, Non-periodic,Binary and CLK/256
    }	
}

// delay for Time*1us, at 41.78MHz CLK.     41.78M  / 42 = 1M
void ADuC7026DelayUs( unsigned int TimeUs)  	
{           					 
    unsigned int i;     		 

    for(i=0; i1) {}
        T1CON = 0x48;       // Disabled, Non-periodic,Binary and CLK / 1
    }	
}

void ADuC7026SpiOperation(unsigned char* WriteBuffer, unsigned char *ReadBuffer, unsigned char NumberOfByte)
{
    unsigned    char    WriteData, ReadData;
    unsigned    char    i, j;

//  ADuC7026OutputBit(CS,0);

    ADuC7026OutputBit(SCLK,1);	
    for(i=0; i