|
楼主 |
发表于 2008-5-11 11:56:53
|
显示全部楼层
参考电压对于每个板子来说确实不相同,也无法保证能精确到2.5V,比如我目前的板子上电后测量该参考电压上2.376V(我假设该值应该波动不大),因为AIN1+输入是经过一级放大,所以可以调整满量程输入时AIN1+的电压能调整到参考电压(2.376V)差不多,不知道我这样的思路是否合理。
现在我的问题是通过ATmega64(外部时钟16M)的SPI无法正确读取到AD7705通道1的AD转换值,以下代码均来自ouravr网站。
PORTB = 0x08; //PORTB初始化 MISO输入加上拉电阻
DDRB = 0x17; // SS 输出,SCK输出,MOSI 输出,MISO输入 7705 ret 输出
//SPI初始化
SPCR = 0x5F; //使能SPI,MSB先发送,主机,SCK空闲高,模式三,128分频
//SPI写寄存器函数
void WriteToReg_ADC(UINT8 Data)
{
AD7705_CS = 0; //使能SPI器件
SPDR = Data; //发送数据
while(!(SPSR & (1<<SPIF))); //等待发送完毕
AD7705_CS = 1; //禁止SPI器件
}
//SPI读函数
UINT8 Read_Byte_SPI(void)
{
SPDR = 0x00; //启动SPI,SPDR给任意值
while (!(SPSR &( 1 << SPIF)));
return SPDR;
}
//SPI读数据寄存器函数
UINT16 Read_ADC16BitValue(void)
{
UINT16 DataL = 0;
UINT16 DataH = 0;
UINT16 Ret = 0;
AD7705_CS = 0; //使能SPI器件
DataH = Read_Byte_SPI();
DataH = DataH << 8;
DataL = Read_Byte_SPI();
Ret = DataH | DataL;
AD7705_CS = 1; //禁止SPI器件
return Ret;
}
/*********** SPI 相关 ***************************************/
void AD7705Init(void)
{
UINT8 i = 0;
AD7705_RET = 0;
delay_us(500);
AD7705_RET = 1;
for(i = 0; i < 30; i++)
{
WriteToReg_ADC(0xFF); //持续DIN高电平写操作,恢复AD7705接口
}
WriteToReg_ADC(0x20); //通道1,下一个写时钟寄存器
WriteToReg_ADC(0x04); //写时钟寄存器设置更新速率为50hz
WriteToReg_ADC(0x10); //通道1,下一个写设置寄存器
WriteToReg_ADC(0x44); //自校准,增益1,单极,无缓冲
delay_us(500); //延时
}
//读取AD7705第一通道数据
UINT16 ReadAD7705(void)
{
UINT16 Ret = 0;
WriteToReg_ADC(0x38); //下一操作为读数据寄存器1
Ret = Read_ADC16BitValue();
return Ret;
}
=========================================================================================
===================================以下是问题具体描述====================================
AD7705中断DRDY后调用函数ReadAD7705读取AD转换值,请看下表
编号 AIN1+电压值 ReadAD7705返回值
1 0.048V 1399 <-- 65535*0.048/2.376 = 1323 与1399接近
2 0.288V 8010 <-- 65535*0.288/2.376 = 7943 与8010接近
3 0.528V 6419 <-- 不正常
4 0.768V 4831 <-- 不正常
第1,2次的数据看似正确,因为AIN1+满量程调整有可能不准确,但是第3,4次数据怎么越来越小呢?
所以我不确定以上原理图是否有问题。 |
|