AD7705 16-bit Delta-Sigma AD 转换器

这款 AD7705 来自于 Analog Devices 公司的一款Sigma-Delta ADC。具有两路差分输入ADC通道,本文记录利用STC8H1K28单片机开发该芯片组成双通道AD转换芯片应用过程。

▲ AD7705内部功能框图与参考设计电路

▲ AD7705内部功能框图与参考设计电路

相关应用:

01实验模块设计


1.器件库建立

▲ AD元器件以及TSSOP-16封装

▲ AD元器件以及TSSOP-16封装

2.电路设计1

在设计中,AD7705的时钟信号来自于STC8H1K的主时钟的分频输出。具体设置可以参见STC8H1K的MCLKOCR寄存器的设置。

▲ STC8H1K281K主时钟分频输出

▲ STC8H1K281K主时钟分频输出

  • 电路模块接口管脚功能定义:
PIN1 PIN2 PIN3 PIN4 PIN5 PIN6 PIN7 PIN8
+5V GND AGND AIN1+ AIN1- AIN2+ AIN2- ADC0
  • 测量参考电压: 2.53V。
    注:地线的电压浮动:0.03V。

3.单片机软件2

  • MCU OSC: 35MHz; UART 460800bps

(1) MCLK的输出设置


#if MCLKOUT_EN
void MClkOutInit(void) {
    _push_(P_SW2);
    P_SW2 = 0x80;
    MCLKOCR = MCLKOUT_DIVIDE | MCLKOS_1;
    PM_PP(MCLKOUT_PIN);
    _pop_(P_SW2);
}
#endif // MCLKOUT_EN

测量P5.4(MCLK)的波形,频谱为5MHz。

(2) SPI设置

  • 设置:MCLK_DIV=35:求得输出的MCLK的频率为1MHz

02 AD7705读写子程序


1.初始化中的特殊语句

根据AD7705的数据手册以及其中的范例,编写了对于AD7705的初始化程序。但是!不知为什么始终无法进行正常的初始化和得到转化结果。

直道在 电赛总结(二)–AD芯片总结 博文中,看到在它的初始化程序中有这么一段程序:

void Init_AD7705(u8 chnanel) 
{
    u8 i;
    
    for(i=0;i<150;i++)
    {
        AD7705_WriteByte(0xff);
      }  
      delay_ms(1);

   。。。。。。。。。。。。。。

实在是太奇怪了。不过仿照上述的部分,在AD7705的初始化程序中总增加了下面的语句,突然,整个程序就跑通了!!!

对于这个请到现在还不知道具体的原因是什么!

 
for(i = 0; i < 10; i ++) AD7705WriteByte(0xff);     
WaitTime(2);

2.完成的程序


/*
**==============================================================================
** AD7705.H:            -- by Dr. ZhuoQing, 2020-08-02
**
**  Description:
**
**==============================================================================
*/
#ifndef __AD7705__
#define __AD7705__
//------------------------------------------------------------------------------
#ifdef AD7705_GLOBALS
   #define AD7705_EXT
#else
   #define AD7705_EXT extern
#endif // AD7705_GLOBALS
//------------------------------------------------------------------------------
//==============================================================================

//------------------------------------------------------------------------------

#define AD7705_CS           1,2
#define AD7705_RESET        1,1
#define AD7705_DRRDY        1,6
#define AD7705_CLK          1,5
#define AD7705_MOSI         1,3
#define AD7705_MISO         1,4

//------------------------------------------------------------------------------
unsigned char AD7705SPIWriteRead(unsigned char ucByte);
void AD7705SPIDelay(unsigned int nLoop);

//------------------------------------------------------------------------------
void AD7705Init(void);
#define AD7705_SETUP_DEF    0x44        // Unipolar, 
#define AD7705_CLOCK_DEF    0x02        // 100Hz, 1MHz

//------------------------------------------------------------------------------
#define MCLK_FREQUENCY      1000000

#define AD7705_COMM_DEF     0x0

AD7705_EXT unsigned char g_ucAD7705Channel;
#define AD7705_CHANNEL_1        0x0
#define AD7705_CHANNEL_2        0x1

#define AD7705_SET_CHANNEL_1    (g_ucAD7705Channel = AD7705_CHANNEL_1)
#define AD7705_SET_CHANNEL_2    (g_ucAD7705Channel = AD7705_CHANNEL_2)

//------------------------------------------------------------------------------
void AD7705WriteReg(unsigned char ucReg, unsigned char ucByte);
void AD7705WriteByte(unsigned char ucByte);

#define AD7705_REG_COMM     0x00
#define AD7705_REG_SETUP    0x10
#define AD7705_REG_CLOCK    0x20
#define AD7705_REG_DATA     0x30
#define AD7705_REG_TEST     0x40
#define AD7705_REG_NOP      0x50
#define AD7705_REG_OFFSET   0x60
#define AD7705_REG_GAIN     0x70

unsigned int AD7705ReadData(void);
unsigned char AD7705ReadReg(unsigned char ucReg);

unsigned int AD7705ReadChannel(unsigned char ucChannel);

//==============================================================================
//             END OF THE FILE : AD7705.H
//------------------------------------------------------------------------------
#endif // __AD7705__
/*
**==============================================================================
** AD7705.C:             -- by Dr. ZhuoQing, 2020-08-02
**
**==============================================================================
*/

//------------------------------------------------------------------------------
#define AD7705_GLOBALS        1              // Define the global variables
#include "AD7705.H"
#include "STC8H.H"
#include "STC8HREG.H"
#include "C51BASIC.H"
#include "INTRINS.H"
#include "STDIO.H"

//------------------------------------------------------------------------------

void AD7705Init(void) {
    unsigned int i;
    
    ON(AD7705_CS);
    ON(AD7705_RESET);
    ON(AD7705_DRRDY);
    PM_PP(AD7705_CS);
    PM_PP(AD7705_RESET);
    PM_INPUT(AD7705_DRRDY);
    
    PM_PP(AD7705_CLK);
    PM_PP(AD7705_MOSI);
    PM_BIDIR(AD7705_MISO);
    ON(AD7705_MISO);
    OFF(AD7705_CLK);
    OFF(AD7705_MOSI);
    
    g_ucAD7705Channel = AD7705_CHANNEL_1;
    
    //--------------------------------------------------------------------------
    
//    OFF(AD7705_RESET);
//    WaitTime(2);
//    ON(AD7705_RESET);

    //--------------------------------------------------------------------------    
    for(i = 0; i < 10; i ++) AD7705WriteByte(0xff);     // *******************    
    
    WaitTime(2);
    
    AD7705WriteReg(AD7705_REG_CLOCK, AD7705_CLOCK_DEF); // 100Hz, -3db Filter Cutoff 26.2
                                            // 1MHz : MCLK
    AD7705WriteReg(AD7705_REG_SETUP, AD7705_SETUP_DEF); // Gain=1, Self-Calibration, Bipolar
    
    //--------------------------------------------------------------------------
//    printf("%bx %bx \r\n", AD7705ReadReg(AD7705_REG_CLOCK), AD7705ReadReg(AD7705_REG_SETUP));
    
}

//------------------------------------------------------------------------------
unsigned char AD7705SPIWriteRead(unsigned char ucByte) {
    unsigned char i, ucMask, ucReturn;
    
    ON(AD7705_CLK);
    
    ucReturn = 0x0;
    ucMask = 0x80;
    
    for(i = 0; i < 8; i ++) {
        OFF(AD7705_CLK);
        if(ucByte & ucMask)
            ON(AD7705_MOSI);
        else OFF(AD7705_MOSI);
        
        AD7705SPIDelay(0x40);
        
        if(VAL(AD7705_MISO)) ucReturn |= ucMask;
        ON(AD7705_CLK);
        
        AD7705SPIDelay(0x40);
        ucMask >>= 1;
        
    }
    
    return ucReturn;
    
}

void AD7705SPIDelay(unsigned int nLoop) {

    while(--nLoop) {
        _nop_();
    }

}

//------------------------------------------------------------------------------
void AD7705WriteReg(unsigned char ucReg, unsigned char ucByte) {
    unsigned char ucCmd;
    
    ucCmd = g_ucAD7705Channel | ucReg;
    
    AD7705WriteByte(ucCmd);
    AD7705WriteByte(ucByte);
  
}

//------------------------------------------------------------------------------
void AD7705WriteByte(unsigned char ucByte) {
    OFF(AD7705_CS);
    AD7705SPIDelay(0x20);
    AD7705SPIWriteRead(ucByte);
    AD7705SPIDelay(0x20);
    ON(AD7705_CS);
        
}

unsigned char AD7705ReadReg(unsigned char ucReg) {
    unsigned ucByte;
    
    ucByte = ucReg | g_ucAD7705Channel | 0x8;
    AD7705WriteByte(ucByte);
    
    OFF(AD7705_CS);
    ucByte = AD7705SPIWriteRead(0x0);
    ON(AD7705_CS);
    return ucByte;
    
}

//------------------------------------------------------------------------------
unsigned int AD7705ReadData(void) {
    unsigned char ucByte, ucNum;
    unsigned int nNumber;
    
    while(VAL(AD7705_DRRDY));

    ucByte = AD7705_REG_DATA | g_ucAD7705Channel | 0x8;
    
    AD7705WriteByte(ucByte);
    
//    printf("%bx ", ucByte);
    
    OFF(AD7705_CS);
    
//    AD7705SPIWriteRead(ucByte);
    
    ucNum = AD7705SPIWriteRead(0x8);
    nNumber = ucNum;
        
    ucNum = AD7705SPIWriteRead(0x08);
    nNumber = (nNumber << 8) + ucNum;
    
    ON(AD7705_CS);
    return (unsigned int)nNumber;   
}

//------------------------------------------------------------------------------
unsigned int AD7705ReadChannel(unsigned char ucChannel) {
    g_ucAD7705Channel = ucChannel;
    
    AD7705WriteReg(AD7705_REG_SETUP, AD7705_SETUP_DEF); 
    
    WaitTime(5);
    return AD7705ReadData();
}

//==============================================================================
//                END OF THE FILE : AD7705.C
//------------------------------------------------------------------------------

03串口命令


在STC8H1K单片机中提供了串口如下的采集命令集合:

else IFARG0("ad7705c1") {
    sscanf(SDA(1), "%d", &nNumber);
    nPeriod = 0;        
    if(STD_NUM > 2) {
        sscanf(SDA(2), "%d", &nPeriod);
    }

    AD7705ReadChannel(0);
    
    while(nNumber --) {
        printf("%u ", AD7705ReadData());            
        if(nPeriod > 0) WaitTime(nPeriod);
    }
    
    printf("\r\n");

} else IFARG0("ad7705c2") {
    sscanf(SDA(1), "%d", &nNumber);
    nPeriod = 0;        
    if(STD_NUM > 2) {
        sscanf(SDA(2), "%d", &nPeriod);
    }
    AD7705ReadChannel(1);
    while(nNumber --) {
        printf("%u ", AD7705ReadData());            
        if(nPeriod > 0) WaitTime(nPeriod);
    }
    
    printf("\r\n");
    
} else IFARG0("ad7705c12") {
    nPeriod = 0;        
    if(STD_NUM > 2) {
        sscanf(SDA(2), "%d", &nPeriod);
    }

    while(nNumber --) {
        printf("%u %u ", AD7705ReadChannel(0), AD7705ReadChannel(1));
        if(nPeriod > 0) WaitTime(nPeriod);
    }
    
    printf("\r\n");
    
}

▲ 采集的正弦波信号

▲ 采集的正弦波信号

▲ 采集到三角波信号

▲ 采集到三角波信号

▲ 采集到的方波信号

▲ 采集到的方波信号

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2020-08-02
#
# Note:
#============================================================
from headm import *
from tsmodule.tsstm32       import *
stm32cmd('CLEAR')
stm32cmd('ad7705c1 1000')
while True:
    if stm32val()[12] > 0: break
data = stm32memo(1)
plt.plot(data)
plt.xlabel("Sample")
plt.ylabel("Voltage")
plt.grid(True)
plt.tight_layout()
plt.show()
#------------------------------------------------------------
#        END OF FILE : TEST1.PY
#============================================================

※ 结论


使用STC8H1K28单片机设计了基于AD7705的16bit Sigma-DeltaAD转换器。在时钟设置为0x02, MCLK 设置为1MHz的时候输出数据的频率为100Hz。这一点可以通过AD7705的DATAREADY管脚测量得到。

▲ AD7705 DRRDY管脚显示数据更新频率为100Hz

▲ AD7705 DRRDY管脚显示数据更新频率为100Hz

在调试过程中,初始化有一个往AD7705写入一连串(个数大于5个)0xff的过程。这个过程增加之后,AD7705便可以正常的完成读写操作。

那么问题是:为什么需要增加这个过程?


  1. AD设计工程文件:AD\Test\2020\AD7705\AD77058H1K.SchDoc ↩︎

  2. MCU C51工程文反面:C51\STC\Tools\2020\AD7705STC8H1K28\AD7705STC8H1K28.uvproj ↩︎

猜你喜欢

转载自blog.csdn.net/zhuoqingjoking97298/article/details/107743279
ad
今日推荐