回帖奖励 6 分积分 回复本帖可获得 2 分积分奖励! 每人限 5 次

[讨论] stc90c51和ad7705显示总是错的

[复制链接]

实习生

发表于 2018-1-23 13:40:25   459 查看 9 回复 显示全部楼层 倒序浏览
分享
我打算用51单片机和ad7705做一个电压采集,但是无论我读取ad7705的什么寄存器都显示255附件是原理图,下面是程序,有没有懂得人万分感谢了 还有如果将程序里main函数的int a;改成uchar a;就显示-256
#include"reg51.h"
#include"intrins.h"
#include "stdio.h"
#include"math.h"
sbit AD7705_SCLK = P2^0;  
sbit AD7705_DRDY = P2^3;
sbit AD7705_DOUT = P2^2;
sbit AD7705_DIN  = P2^1;     // 通讯寄存器地址定义
#define uchar unsigned char
#define uint unsigned int
#define   WR_SETUP_REG           0x10       //选中设置寄存器,写  
#define   RD_SETUP_REG           0x18       //选中设置寄存器,读  
#define   WR_CLOCK_REG           0x20       //选中时钟寄存器,写
#define   RD_DATA_REG            0x38       //选中数据寄存器,读  
#define   WR_OFFSET_REG          0x60       //选中offset寄存器,写
#define   RD_OFFSET_REG          0x68       //选中offset寄存器,读  
#define   WR_FULL_REG            0x70       //选中full scale寄存器,写
#define   RD_FULL_REG            0x78       //选中full scale寄存器,读
#define   SYS_ZERO_CALI          0x80       //系统零校准模式  
#define   SYS_FULL_CALI          0xC0       //系统满量程校准模式
#define   ZERO_CALIBRATION       0x00       //系统零校准
#define   FULL_CALIBRATION       0x01       //系统满量程校准   
#define   CLOCK_REG_SET          0x04       //CLOCK寄存器设置,无分频,50HZ输出更新速率   
#define   DELAY()              {_nop_();_nop_();_nop_();}

void v_DelayMs_f(unsigned int nDelay);
void v_Lcd_SendCmd_f(unsigned char byCmd);   //发送命令
void v_Lcd_SendData_f(unsigned char byData); //发送数据
void v_Lcd_Init_f(void); //初始化
void v_Lcd_SetAddress_f(unsigned char x,y); //地址转换
void v_Lcd_PutString_f(unsigned char x,unsigned char y,unsigned char *pData);
void  DelayMs(unsigned int nDelay);   
sbit LCD_RS = P2^7;
sbit LCD_RW = P2^6;
sbit LCD_EN = P2^5;  
sbit LCD_PSB = P3^2;
#define LCD_DATAPORT P0  
#define SET_DATA  LCD_RS = 1
#define SET_INC   LCD_RS = 0
#define SET_READ  LCD_RW = 1
#define SET_WRITE LCD_RW = 0
#define SET_EN    LCD_EN = 1
#define CLR_EN    LCD_EN = 0
void  AD7705_Init(void);
void  AD7705_Reset(void);
void  AD7705_Start(void);   
uchar AD7705_ReadByte(void);   
void AD7705_WriteByte(uchar d);
int AD7705_ReadVol(void);   
void main(void)
{
        int a;       
        char z[16]="01231";
        AD7705_Init();
        AD7705_Start();
        a=AD7705_ReadVol();
        sprintf(z,"%d",a);
        v_Lcd_Init_f();
        v_Lcd_PutString_f(0,1,z);
               

       
               
       
           
       
       
}
void v_DelayMs_f(unsigned int nDelay) //延时
        {
                unsigned int i ;
                for(;nDelay>0;nDelay--)
                {
                        for(i=125;i>0;i--) ;
                }
        }        
void v_Lcd_SendCmd_f(unsigned char byCmd)   //发送命令
        {
                v_DelayMs_f(50);   
                   SET_INC;//rs 0
                  SET_WRITE;//rw 0
                CLR_EN; //e 0
                LCD_DATAPORT=byCmd;
                  _nop_();
                  _nop_();
                SET_EN;  // e1
                _nop_();
                _nop_();
                  CLR_EN;//e 0
                SET_READ; //rw 1
                SET_INC; //rs 0
        }
void v_Lcd_SendData_f(unsigned char byData) //发送数据
        {
                v_DelayMs_f(50);
                SET_DATA; //rs1
                SET_WRITE; //rw0
                CLR_EN; //e0
                LCD_DATAPORT=byData ;
                _nop_();
                _nop_();
                SET_EN; //e1
                _nop_();
                _nop_();
                CLR_EN; //e0
                SET_READ; //rw1
                SET_INC; //rs0
        }

void v_Lcd_Init_f(void) //初始化
        {
                v_Lcd_SendCmd_f(0x30); //基本指令集
                v_DelayMs_f(50);
                v_Lcd_SendCmd_f(0x01); //清屏
                v_DelayMs_f(50);
                v_Lcd_SendCmd_f(0x06); //光标右移
                v_DelayMs_f(50);
                v_Lcd_SendCmd_f(0x0c); //开显示
        }
void v_Lcd_SetAddress_f(unsigned char x,y) //地址转换
        {
                unsigned char byAddress ;
                switch( y )
                {
                        case 0 : byAddress=(0x80+x);
                        break;
                        case 1 : byAddress=(0x90+x);
                        break;
                        case 2 : byAddress=(0x88+x);
                        break;
                        case 3 : byAddress=(0x98+x);
                        break;
                        default:
                        break ;
                }
                v_Lcd_SendCmd_f(byAddress);
        }
void v_Lcd_PutString_f(unsigned char x,unsigned char y,unsigned char *pData)
        {
                v_Lcd_SetAddress_f(x,y);
                while(*pData!='\0')
                {
                        v_Lcd_SendData_f(*pData++);
                }
        }
void DelayMs(unsigned int nDelay) //延时
        {
                unsigned int i ;
                for(;nDelay>0;nDelay--)
                {
                        for(i=125;i>0;i--) ;
                }
        }
void AD7705_Reset(void)
{   
        uchar data i;
           for( i=0; i<<36; i++ )
          {
                AD7705_SCLK = 0;   
                   AD7705_DIN = 1;    // DIN端口连续写36个周期的高电平,保证复位  
                   DELAY();   
                  AD7705_SCLK = 0;
                   DELAY();  
          }   
        DelayMs(1);             // 复位之后等待1MS      
}  
//****************************************************************************
//功能:往AD7705写1个字节数据
//参数:要写入AD7705的数据
//返回:无
//备注:无  
//****************************************************************************
void AD7705_WriteByte(uchar d)
{
   int i;
   int temp;         
   temp=0x80;
   for(i=0;i<8;i++)
        {
   if((temp&d)==0)
      AD7705_DIN=0;
   else AD7705_DIN=1;
      AD7705_SCLK=0;
      AD7705_SCLK=1;
   temp=temp>>1;
    }
}
//****************************************************************************
//功能:从AD7705读一个字节的数据
//参数:无
//返回:读到的一字节数据
//备注:无  
//****************************************************************************
uchar AD7705_ReadByte(void)
{   
        uchar idata i, d=0;     // 读数据,高位在前   
        for( i=0; i<16; i++ )  
        {   
                d<<= 1;   
                  AD7705_SCLK = 0;  
            DELAY();   
                   if(AD7705_DOUT) d++;  
                   AD7705_SCLK = 1;   
                  DELAY();  
        }   
        return d;
}     
//------------------------------------------------------------------------------------------  
//功能:先写offset寄存器,再写full scale寄存器,然后启动7705进行单次转换
//参数:
//返回:无
//备注:  
//------------------------------------------------------------------------------------------
void AD7705_Start(void)
{     
        AD7705_Reset();    // 复位,防止接口迷失  
        // 复位之后一定要重新设置各寄存器,复位之后默认状态为等待对通信寄存器的一次操作   
        // 遵循先写命令,后写数据的原则,命令默认写到通信寄存器     
        //写OFFSET寄存器   
        AD7705_WriteByte(WR_OFFSET_REG);  
        AD7705_WriteByte(0xFF);     
        //写满量程校准寄存器   
        AD7705_WriteByte(WR_FULL_REG);
        AD7705_WriteByte(0xFF);   
          AD7705_WriteByte(WR_CLOCK_REG);  // next write to clock reg,AIN1,  0010 0000  
          AD7705_WriteByte(0x00);          // CLKDIS=0,CLKDIV=0,CLK=0,FS1=0,FS2=0  0001 0000   
          AD7705_WriteByte(WR_SETUP_REG);  // next write to setup reg,AIN1   0001 0000  
          AD7705_WriteByte(0x04);          // 正常状态启动装换,GAIN=1,B/U=0,BUF=0,FSYNC=0,增益=1,双极性 }   
}
void AD7705_Init(void)
{  
          AD7705_Reset();  // 复位,防止接口迷失   
          AD7705_WriteByte(WR_CLOCK_REG);  // next write to clock reg,AIN1,  0010 0000   
        AD7705_WriteByte(0x10);          // CLKDIS=0,CLKDIV=0,CLK=0,FS1=0,FS2=0  0001 0000      
                              // 外部主时钟频率为2.4576MHz   
          AD7705_WriteByte(WR_SETUP_REG);  // next write to setup reg,AIN1   0001 0000  
          AD7705_WriteByte(0x44);          // SELF-CAL,GAIN=1,B/U=0,BUF=0,FSYNC=0,自校准模式,增益=1,双极性
}     
int AD7705_ReadVol(void)
{   
        uchar idata a=0;  
           AD7705_WriteByte(RD_DATA_REG);    //READ FROM DATA REG,AIN1
        a=AD7705_ReadByte();   
          return a;  
}

Sheet1.pdf

30.37 KB, 下载次数: 0, 下载积分: 积分 -1 分

标签:显示 stc90c51 ad7705

高级工程师

发表于 2018-1-23 13:55:35  

回帖奖励 +2 分积分

你的主程序没有循环,也就是只显示了执行一次的结果,另外可以试试显示任意数值,看看显示部分是否正确,主程序可以改成如下,看看效果如何
void main(void)
{
        int a;        
        char z[16]="01231";
        AD7705_Init();
        AD7705_Start();
        v_Lcd_Init_f();        while(1)
        {
               a=AD7705_ReadVol();
               sprintf(z,"%d",a);
               v_Lcd_PutString_f(0,1,z);
         }

}
回复

点赞 举报

实习生

发表于 2018-1-23 14:10:02    楼主|
人中狼 发表于 2018-1-23 13:55
你的主程序没有循环,也就是只显示了执行一次的结果,另外可以试试显示任意数值,看看显示部分是否正确,主程序可以改成如下,看看效果如何
void main(void)
{

按照您的程序改了一下 还是显示255这个数字不动,正常我没给输入,他数值不是应该很小么,哎................
回复

点赞 举报

实习生

发表于 2018-1-23 14:10:03    楼主|
人中狼 发表于 2018-1-23 13:55
你的主程序没有循环,也就是只显示了执行一次的结果,另外可以试试显示任意数值,看看显示部分是否正确,主程序可以改成如下,看看效果如何
void main(void)
{

按照您的程序改了一下 还是显示255这个数字不动,正常我没给输入,他数值不是应该很小么,哎................
回复

点赞 举报

高级工程师

发表于 2018-1-23 14:28:26  

回帖奖励 +2 分积分

ADC不给输入的话有可能是任意值,也可能是固定值,可以分开测试,先测试显示部分,是否ADC范围内的任意数值都能正确显示,等显示正确了,那剩下的就是AD部分的问题了
回复

点赞 举报

实习生

发表于 2018-1-23 14:35:43    楼主|
人中狼 发表于 2018-1-23 14:28
ADC不给输入的话有可能是任意值,也可能是固定值,可以分开测试,先测试显示部分,是否ADC范围内的任意数值都能正确显示,等显示正确了,那剩下的就是AD部分的问题了

谢谢 我刚刚试了一下,显示部分是可以显示更大的数值的,那应该是ad问题?可是我读取所有的寄存器都显示这一个数值  我应该给输入?
回复

点赞 举报

高级工程师

发表于 2018-1-23 14:42:19  
没用过这款AD,对于ADC的测试,就是给ADC的输入端一个电压,这个电压最好是通过一个可调电阻,这样可以得到不同数值的电压,然后读取ADC转换后的结果,进行数据格式转换,将ADC转换的结果转换成电压值,与ADC的输入电压对比,在一定的误差范围内,就可以认为ADC调通了,再进行不同电压的转换,多次验证就可以了。
具体ADC的输入如何连接,需要看具体芯片的资料
回复

点赞 举报

实习生

发表于 2018-1-23 15:36:56    楼主|
人中狼 发表于 2018-1-23 14:42
没用过这款AD,对于ADC的测试,就是给ADC的输入端一个电压,这个电压最好是通过一个可调电阻,这样可以得到不同数值的电压,然后读取ADC转换后的结果,进行数据格式转换,将ADC转换的结果转换成电压值,与ADC的输入电压对比,在一定的误差范围内,就可以认为ADC调通了,再进行不同电压的转换,多次验证就可以了。
具体ADC的 ...

谢谢  谢谢  我试一下
回复

点赞 举报

实习生

发表于 2018-1-23 16:47:55  
稍微看了下楼主的问题,我用过AD7710,与这个有些类似,也碰到过类似的问题,你可以量一下DRDY信号的,当时我这面的具体解决方式是,写完寄存器之后,延迟时间等待DRDY信号变低后,选择采集电压通道,然后进行延迟,等待DRDY信号变低,但有时DRDY信号变低后采集的电压信号不对,处理方式:增加延迟时间,这个延迟时间与当时手册给出的延迟时间是有很大差距的,建议楼主采用增加延迟时间的方式处理一下,仅供参考~
回复

点赞 举报

实习生

发表于 2018-1-23 19:11:59    楼主|
gshuang12 发表于 2018-1-23 16:47
稍微看了下楼主的问题,我用过AD7710,与这个有些类似,也碰到过类似的问题,你可以量一下DRDY信号的,当时我这面的具体解决方式是,写完寄存器之后,延迟时间等待DRDY信号变低后,选择采集电压通道,然后进行延迟,等待DRDY信号变低,但有时DRDY信号变低后采集的电压信号不对,处理方式:增加延迟时间,这个延迟时间与当时 ...

谢谢谢谢
我实在是找不出来病了
回复

点赞 举报

高级模式
您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐 上一条 /9 下一条

快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

工程师杂谈

项目|工程师创意

招聘|求职}工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

MSP430技术论坛

FPGA|CPLD|ASIC论坛

STM32/STM8技术论坛

NXP MCU 技术论坛

PIC单片机论坛

DSP论坛

瑞萨单片机论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

工程资源中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

电子展览展会专区

芯片求购|供应发布区