AD7705 性价比比较高的 16位 ad 使用比较简单
用做单通道的时候 基本不怎么需要设置
做双通道的时候,发现的点问题 ,而这几点问题在网上的前辈那也没有特别说明
这里提出来供用的着 AD7705 的参考下
1. 关于时钟寄存器 AD7705 只有一个时钟寄存器 而不是两个。 2.4576MHZ 是标准频率 ,如果用 4.9152MHZ的时候,要将 CLKDIV位置位
也就是 2 分频到 2.4576 具体设置看手册
2. 关于数据寄存器 AD7705 也只有一个数据寄存器 ,一段时间内只能对一路 AD输入做数据转换 。数据转换范围
单极性 0 -- Vref/Gain 对应 0 -- 0xffff(65535)
双极性 -Vref/Gain -- 0 对应 0 -- 0x8000(32768) 0 - Vref/Gain 对应 0x8000(32768) -- 0xffff(65535)
3. 关于设置寄存器 同样也只有一个 ,要用哪个通道 就要先设置这个通道对应的寄存器值
4. 校准寄存器 虽然有 4对 但只是对应外部校准的 所以在用自校准,通道切换的时候也要重新自校准一下,校准的时候 DRDY 为高电平,校准完后 为低电平
校准完后 第一次读的数据 不怎么准 应该读第二次转换出来的数据。
下边是我单通道切换转换的程序:
#include <iom16v.h>
//SPI 引脚定义 PB 口
#define CS_DRDY 3
#define CS_CS 4
#define CS_MOSI 5
#define CS_MISO 6
#define CS_SCK 7
extern void SpiInit(void); // SPI 初始化 M16
extern void InitAD7705(void); // AD7705 初始化
extern unsigned int ReadDataCH1(void); //读取转换数据
extern unsigned int ReadDataCH2(void); //读取转换数据
#include \\\\\\\"AD7705.H\\\\\\\"
//定义位操作
#define SET_BIT(x,y) ((x) |= (0x0001 << (y)))
#define CLR_BIT(x,y) ((x) &= ~(0x0001 <<(y)))
#define CPL_BIT(x,y) ((x) ^= (0x0001 << (y)))
#define GET_BIT(x,y) (((x) & (1 << (y))) == 0? 0:1)
#define LET_BIT(x,y,z) ((x) = (x) & (~(1 << (y))) | ((z) << (y)))
//**********************短延时程序50us**************************//
void delay50us(unsigned int t)
{
unsigned int j;
for(;t>0;t--)
for(j=0;j<70;j++);
}
// SPI 初始化 M16
void SpiInit(void)
{
//cs 置为输出 方可不影响 SPI 总线
DDRB|=(1<<CS_MOSI)|(1<<CS_SCK)|(1<<CS_CS);
//使能 spi 设置为主机 时钟极性为空闲时高平 上升沿采样下降沿设置 分频系数为128分频
SPCR|=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
SPSR = 0x00; //setup SPI
SET_BIT(PORTB,CS_DRDY); //设置 REDY 信号输入端口上拉电阻使能
SET_BIT(PORTB,CS_MISO); //设置 MISO 信号输入端口上拉电阻使能
}
// SPI 发送接收数据
unsigned char TransmitterSpi(unsigned char cData)
{
SPDR = cData;
while(!(SPSR&(1<<SPIF)));
return SPDR;
}
//复位 AD7705
void ResetAD(void)
{
unsigned char i ;
for(i = 10;i>0;i--) //持续DIN高电平写操作,恢复AD7705接口
{
TransmitterSpi(0xff);
}
}
// AD7705 初始化
void InitAD7705(void)
{
CLR_BIT(PORTB,CS_CS); //CS置为输出低电平,使能 AD7705
ResetAD() ;
TransmitterSpi(0x20); //通讯寄存器 //通道 1,下一个写时钟寄存器 自校准
TransmitterSpi(0x00); //时钟寄存器 //写时钟寄存器设置 2.459Mhz更新速率为20hz
TransmitterSpi(0x10); //通讯寄存器 //通道 1,下一个写设置寄存器
TransmitterSpi(0x48); //设置寄存器 //自校准,增益 1,双极 ,缓冲
delay50us(100); //延时
TransmitterSpi(0x21); //通讯寄存器 //通道 2,下一个写时钟寄存器 自校准
TransmitterSpi(0x00); //时钟寄存器 //写时钟寄存器设置 2.459Mhz更新速率为20hz
TransmitterSpi(0x11); //通讯寄存器 //通道 2,下一个写设置寄存器
TransmitterSpi(0x48); //设置寄存器 //自校准,增益 1,双极,缓冲
delay50us(100);
}
//*************************** 按照通道 1 读取 ****************************//
unsigned int ReadDataCH1(void)
{
unsigned int getData = 0;
unsigned char bufR[5];
TransmitterSpi(0x10); //通讯寄存器 //通道 1,下一个写设置寄存器
TransmitterSpi(0x48); //设置寄存器 //自校准,增益 1,双极 ,缓冲
while(PINB&(1<<CS_DRDY)); //等待校准完成 READY 信号变为低电平
TransmitterSpi(0x38); //发送 0x38 读取 CH1 数据寄存器
while(PINB&(1<<CS_DRDY)); //等待 READY 信号变为低电平
bufR[0]=TransmitterSpi(0xff); //转换结果高位
bufR[1]=TransmitterSpi(0xff); //转换结果低位
getData=(bufR[0]<<8)|bufR[1]; //获得数据 16 位
return getData ; //返回数据
}
//***************************按照通道 2 读取****************************//
unsigned int ReadDataCH2(void)
{
unsigned int getData = 0;
unsigned char bufR[5];
TransmitterSpi(0x11); //通讯寄存器 //通道 1,下一个写设置寄存器
TransmitterSpi(0x48); //设置寄存器 //自校准,增益 1,双极 ,缓冲
while(PINB&(1<<CS_DRDY)); //等待校准完成 READY 信号变为低电平
TransmitterSpi(0x39); //发送 0x01 读取 AD7705 数据寄存器
while(PINB&(1<<CS_DRDY)); //等待 READY 信号变为低电平
bufR[0]=TransmitterSpi(0xff); //转换结果高位
bufR[1]=TransmitterSpi(0xff); //转换结果低位
getData=(bufR[0]<<8)|bufR[1]; //读取数据前 16 位
return getData ;
}
void main(void)
{
unsigned char adi ;
unsigned int getData,getData2;
SpiInit();
InitAD7705();
while(1)
{
if(adi++ >=1) adi = 0;
if(adi == 0) getData = ReadDataCH1();
if(adi == 1) getData2 = ReadDataCH2();
}
}