|
发表于 2015-4-24 16:32:26
|
显示全部楼层
楼主好!
我正在用STC89C52单片机调试你们的AD7705模块。调试环境是这样:单片机晶振12MHZ ; 和模块的接口用的是P2口;P2口全部用1K排阻接5V上拉了。目前调试的情况是这样,如果只在单片机上电时对TM7705初始化一次,那AD转换读出的数据不能随输入变化,固定为一个值。如果在程序中改成每读一次AD结果后进行一次初始化,并等待约750MS后再读AD结果,那AD转换的数据能随输入变大变小,但数据极不稳定。但大多数转换结果能反映输入电压的变化。能否给一些指导意见?另我怀疑还是接口迷失原因,曾试图在初始化芯片后,读出初始化写入时钟寄存器和设置寄存器里的值,但读出的值要不发生了二进制的移位,就是缺位。综合以上分析,如果是接口迷失,或时序错误,那要从那方面检查和解决?另附上程序,请有空帮我看看有无问题,十分感谢!
#include <at89x52.h>
#include <INTRINS.h>
/* 定义GPIO端口 */
sbit CS = P2^7;
sbit DOUT = P2^6;//接模块的DIN
sbit SCLK = P2^5;
sbit DRDY = P2^4;
sbit DIN = P2^3;//接模块的DOUT
//sbit RST = P2^2;
sbit DATA=P0^0; //HD7279A 数据线
sbit CLK=P0^1; //HD7279A 时钟线
sbit CSP=P0^2; //HD7279A 片选信号
unsigned char Data_MSB,Data_LSB;
unsigned char dbuffer[3][5];//HD7279A 显示缓存
unsigned int AD_result,T_voltage;
enum
{
/* 寄存器选择 RS2 RS1 RS0 */
REG_COMM = 0x00, /* 通信寄存器 */
REG_SETUP = 0x10, /* 设置寄存器 */
REG_CLOCK = 0x20, /* 时钟寄存器 */
REG_DATA = 0x30, /* 数据寄存器 */
REG_ZERO_CH1 = 0x60, /* CH1 偏移寄存器 */
REG_FULL_CH1 = 0x70, /* CH1 满量程寄存器 */
REG_ZERO_CH2 = 0x61, /* CH2 偏移寄存器 */
REG_FULL_CH2 = 0x71, /* CH2 满量程寄存器 */
/* 读写操作 */
WRITE = 0x00, /* 写操作 */
READ = 0x08, /* 读操作 */
/* 通道 */
CH_1 = 0, /* AIN1+ AIN1- */
CH_2 = 1, /* AIN2+ AIN2- */
CH_3 = 2, /* AIN1- AIN1- */
CH_4 = 3 /* AIN1- AIN2- */
};
/* 设置寄存器bit定义 */
enum
{
MD_NORMAL = (0 << 6), /* 正常模式 */
MD_CAL_SELF = (1 << 6), /* 自校准模式 */
MD_CAL_ZERO = (2 << 6), /* 校准0刻度模式 */
MD_CAL_FULL = (3 << 6), /* 校准满刻度模式 */
GAIN_1 = (0 << 3), /* 增益 */
GAIN_2 = (1 << 3), /* 增益 */
GAIN_4 = (2 << 3), /* 增益 */
GAIN_8 = (3 << 3), /* 增益 */
GAIN_16 = (4 << 3), /* 增益 */
GAIN_32 = (5 << 3), /* 增益 */
GAIN_64 = (6 << 3), /* 增益 */
GAIN_128 = (7 << 3), /* 增益 */
/* 无论双极性还是单极性都不改变任何输入信号的状态,它只改变输出数据的代码和转换函数上的校准点 */
BIPOLAR = (0 << 2), /* 双极性输入 */
UNIPOLAR = (1 << 2), /* 单极性输入 */
BUF_NO = (0 << 1), /* 输入无缓冲(内部缓冲器不启用) */
BUF_EN = (1 << 1), /* 输入有缓冲 (启用内部缓冲器) */
FSYNC_0 = 0,
FSYNC_1 = 1 /* 不启用 */
};
/* 时钟寄存器bit定义 */
enum
{
CLKDIS_0 = 0x00, /* 时钟输出使能 (当外接晶振时,必须使能才能振荡) */
CLKDIS_1 = 0x10, /* 时钟禁止 (当外部提供时钟时,设置该位可以禁止MCK_OUT引脚输出时钟以省电 */
/*
2.4576MHz(CLKDIV=0 )或为 4.9152MHz (CLKDIV=1 ),CLK 应置 "0"。
1MHz (CLKDIV=0 )或 2MHz (CLKDIV=1 ),CLK 该位应置 "1"
*/
CLK_4_9152M = 0x08,
CLK_2_4576M = 0x00,
CLK_1M = 0x04,
CLK_2M = 0x0C,
FS_50HZ = 0x00,
FS_60HZ = 0x01,
FS_250HZ = 0x02,
FS_500HZ = 0x04,
/*
四十九、电子秤应用中提高TM7705 精度的方法
当使用主时钟为 2.4576MHz 时,强烈建议将时钟寄存器设为 84H,此时数据输出更新率为10Hz,即每0.1S 输出一个新数据。
当使用主时钟为 1MHz 时,强烈建议将时钟寄存器设为80H, 此时数据输出更新率为4Hz, 即每0.25S 输出一个新数据
*/
ZERO_0 = 0x00,
ZERO_1 = 0x80
};
/*
*********************************************************************************************************
* 函 数 名: bsp_DelayMS
* 功能说明: 延时函数。按照89C52调试, 12T指令周期, 11.0592晶振
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_DelayMS(unsigned int n)
{
/*bsp_DelayMS(500) 时,实际延迟498ms */
unsigned char k;
while(n--)
{
for (k = 0; k < 150; k++);
}
}
/******根据写周期时序,向输入移位寄存器写入指令函数******/
void AD7705_write_Reg(unsigned char data_byte)
{
unsigned char i;
CS=0;
for(i=0;i<8;i++)
{
SCLK=0;
DOUT=data_byte&0x80;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCLK=1;
data_byte<<=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
DRDY=1;
CS=1;
}
/******根据写周期时序,向输入移位寄存器写入指令函数******/
unsigned char AD7705_read_Reg()
{
unsigned char i;
unsigned char DATA_OUT;
while(DRDY);//等待完成数据更新
CS=0;
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
SCLK=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DATA_OUT=DATA_OUT|(unsigned char)DIN;
DATA_OUT=DATA_OUT<<1;
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
CS=1;
_nop_();
DRDY=1;
return (DATA_OUT);
}
/******配置AD7705函数******/
void AD7705_init()//根据具体情况,初始化AD7705
{
//RST = 1; /*模块里将此脚上拉至VCC,不需操作*/
bsp_DelayMS(1);
//RST = 0;
bsp_DelayMS(2);
//RST = 1;
bsp_DelayMS(1); /* 硬件复位 */
bsp_DelayMS(5);
/* AD7705串行接口失步后将其复位。复位后要延时500us再访问 */
CS=0;
AD7705_write_Reg(0xFF);
AD7705_write_Reg(0xFF);
AD7705_write_Reg(0xFF);
AD7705_write_Reg(0xFF);
CS=1;
bsp_DelayMS(5);
AD7705_write_Reg(REG_CLOCK | WRITE | CH_1);//写入通信寄存器;设置为写时钟寄存器
/*时钟寄存器设置*/
AD7705_write_Reg(CLKDIS_0 | CLK_4_9152M | FS_50HZ);//* 刷新速率50Hz */
AD7705_write_Reg(REG_SETUP | WRITE | CH_1);//写入通信寄存器,设置为写设置寄存器
/*设置寄存器设置*/
AD7705_write_Reg(MD_CAL_SELF |GAIN_1 | UNIPOLAR | BUF_EN| FSYNC_0);//* 启动自校准 */
while(DRDY); //等待完成
}
void delay(unsigned int k)
{
unsigned int j,i;
for(j=k;j>0;j--)
for(i=100;i>0;i--);
}
/******读出结果函数******/
void AD7705_read_result()
{
AD7705_write_Reg(0x38);//通信寄存器中,设置为读数据寄存器
/*数据寄存器为16位的只读寄存器,其包含了来自AD7705的最新转换结果*/
Data_MSB=AD7705_read_Reg();//读出高8位数据
Data_LSB=AD7705_read_Reg();//读出低8位数据
AD_result=(unsigned int)Data_MSB;
AD_result<<=8;
AD_result=AD_result | (unsigned int)Data_LSB;////位转换为数
/*转换为电压*/
T_voltage=AD_result;//*2500/65535;
}
/***************************************************以下是HD7279的操作程序****************************************/
void write7279(unsigned char hb,unsigned char lb)
{
unsigned char i;
unsigned char j;
CSP=0;
for(i=1;i<=8;i++)
{
if (hb&0x80) DATA=1;
else DATA=0;
hb=hb<<1;
CLK=1;
for(j=1;j<=128;j++);
CLK=0;
for(j=1;j<=128;j++);
}
for(i=1;i<=8;i++)
{
if (lb&0x80) DATA=1;
else DATA=0;
lb=lb<<1;
CLK=1;
for(j=1;j<=128;j++);
CLK=0;
for(j=1;j<=128;j++);
}
CSP=1;
DATA=0;
}
void display(unsigned char rls,unsigned int disdata)
{
unsigned char g;
unsigned char s;
unsigned char kb;
unsigned char q;
unsigned int d2;
d2=disdata;
q=d2/1000;
d2=d2-q*1000;
kb=d2/100;
d2=d2-kb*100;
s=d2/10;
d2=d2-s*10;
g=d2;
if(rls==1)
{
if(g!=dbuffer[1][1])
{
dbuffer[1][1]=g;
write7279(0x80,g);
}
if(s!=dbuffer[1][2])
{
dbuffer[1][2]=s;
write7279(0x81,s);
}
if(kb!=dbuffer[1][3])
{
dbuffer[1][3]=kb;
write7279(0x82,kb);
}
if(q!=dbuffer[1][4])
{
dbuffer[1][4]=q;
write7279(0x83,q);
}
}
if(rls==2)
{
if(g!=dbuffer[2][1])
{
dbuffer[2][1]=g;
write7279(0x84,g);
}
if(s!=dbuffer[2][2])
{
dbuffer[2][2]=s;
write7279(0x85,s);
}
if(kb!=dbuffer[2][3])
{
dbuffer[2][3]=kb;
write7279(0x86,kb);
}
if(q!=dbuffer[2][4])
{
dbuffer[2][4]=q;
write7279(0x87,q);
}
}
}
void ms750(void)
{
unsigned char i=250;
unsigned int j;
for(j=0;j<=2000;j++)
while(--i);
}
/******主函数******/
void main()
{
SCON=0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD=0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON=0x80; //SMOD=1;
TH1=0xF3; //Baud:4800 fosc=12MHz
TL1=0XF3;
TR1=1; // timer 1 run
AD7705_init();
while(1)
{
/*选择通道1*/
AD7705_write_Reg(0x10);
AD7705_write_Reg(0x3c);//通道初始化*/
/*选择通道2*/
//AD7705_write_Reg(0x11);
//AD7705_write_Reg(0x44);//通道初始化
delay(50);//等待完成数据更新
while(DRDY);//检测DRDY输出线引脚是否为低
AD7705_read_result();
/*显示转换结果*/
/*AD7705_write_Reg(REG_SETUP | READ | CH_1);//写入通信寄存器;设置为读时钟寄存器
T_voltage=AD7705_read_Reg(); */
display(1,T_voltage);
if(T_voltage==0) display(1,8888);
SBUF=Data_MSB;
while(TI==0);
TI=0;
delay(50);
SBUF=Data_LSB;
while(TI==0);
TI=0;
AD7705_init();
ms750();
}
} |
|