找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3500|回复: 17
打印 上一主题 下一主题
收起左侧

求助STC89C52用ADC0809采集问题,仿真可以但实物不行

[复制链接]
跳转到指定楼层
楼主
50黑币
请问,我用以下的仿真图连接实物,为什么采不出真实的电压值?仿真图,可以采到差不多的电压值。我的实物图是没有还提供采集通道的电压呢,怎么就有电压3.710出来了?有做个类似的么?是不是仿真图不能用实物连接的啊,需要个锁存器么?请求帮助,谢谢了。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:394367 发表于 2018-9-26 20:52 | 只看该作者

RE: 求助STC89C52用ADC0809采集问题,仿真可以但实物不行

请问,我用以下的仿真图连接实物,为什么采不出真实的电压值?仿真图,可以采到差不多的电压值。我的实物图是没有还提供采集通道的电压呢,怎么就有电压3.710出来了?有做个类似的么?是不是仿真图不能用实物连接的啊,需要个锁存器么?请求帮助,谢谢了。

11.jpg (269.56 KB, 下载次数: 60)

11.jpg

10.jpg (166.52 KB, 下载次数: 64)

10.jpg

评分

参与人数 1黑币 +15 收起 理由
perfect123 + 15 很给力!

查看全部评分

回复

使用道具 举报

板凳
ID:303383 发表于 2018-9-26 21:21 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

地板
ID:394367 发表于 2018-9-27 08:29 | 只看该作者
小猫猫爱吃鱼 发表于 2018-9-26 21:21
你好!一般情况下,都是 0809 时钟提供的不对,发图出来看看吧

我用是0.2ms中断一次产生时钟的,给你看看程序对不对
#include <reg52.h>                    //52系列单片机头文件
#include <intrins.h>
#include "math.h"
#define uchar unsigned char
#define uint unsigned int
sbit st=P2^2;                //定义AD的WR端口
sbit oe=P2^3;                //定义AD的RD端口
sbit eoc=P2^0;
sbit ale=P2^1;

sbit lcden=P2^6;        //液晶使能端
sbit lcdrs=P2^4;        //液晶数据命令选择端

sbit ADDA=P2^5;                //定义A、B、C三条地址线
sbit ADDB=P3^6;
sbit ADDC=P3^7;
sbit CLK=P2^7;          //定义时钟端口
uint a,num;
float OPA,OPB,AD;
uchar code table41[]="WELCOME!";


/*********
延迟函数
**********/
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
/************
2002写命令
**************/
void write_com(uchar com)
{
        lcdrs=0;
        P0=com;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
/************
2002写数据
*************/
void write_data(uchar date)
{
        lcdrs=1;
        P0=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
/****************
液晶初始化
*********************/
void init()
{
        lcden=0;
        write_com(0x38);//设置2002显示,5X7点阵,8位数据接口
        write_com(0x0c);//设置开显示,不显示光标
        write_com(0x06);//写一个字符后地址指针加1
        write_com(0x01);//显示清零,数据指针清零
}
/********************
显示程序
****************************/
void display(uint x,uint qian,uint bai,uint shi,uint ge)
{
        write_com(0x80+x);
        write_data(0x30+qian);
        write_data('.');
        write_data(0x30+bai);
        write_data(0x30+shi);
        write_data(0x30+ge);
}
/********************
   定时中断初始化,为了产生AD芯片需要的时钟信号
*********************/
void init_time0()
{
     TMOD = 0x02;
         TH0=(65536-200)/256;
         TL0=(65536-200)%256;
         IE   = 0x82;
         TR0  = 1;
}

/********************
A通道OPA光电压采集
***********************/
void OPA_1()
{
   
             ADDA=1;           //选择通道1
             ADDB=0;
             ADDC=0;
             oe=0;                //关闭输出允许位
             st=0;
             st=1;
             st=0;                //以上三句,开ADC0809
             delay(1);        //延迟1ms
             while(!eoc);//等待转化结束
             P1=0xff;
             oe=1;                //开启输出允许位
             a=P1;                //将转化出的数字存放至a
             a=a*19.53125;          //  a=a*5/256*1000
             OPA=a*0.001;  
}
/********************
主函数:
*******************/
void main()
{       
     uint a1,a2,a3,a4;

     init_time0();
         init();
         write_com(0x80+0x07);
     for(num=0;num<8;num++)
     {
                  write_data(table41[num]);
                  delay(150);
         }
         delay(1000);
     while(1)
     {                              
               
                 OPA_1();//A路光电压采集                                
                 a1=a/1000;
             a2=a/100%10;
             a3=a/10%10;
             a4=a%10;
             display(0x48,a1,a2,a3,a4);                      
         }                  
}
void Timer0_INT() interrupt 1        //用定时中断产生ADC芯片时钟信号
{

        TH0=(65536-200)/256;
        TL0=(65536-200)%256;
        CLK = !CLK;
}  
回复

使用道具 举报

5#
ID:394367 发表于 2018-9-27 09:09 | 只看该作者
有没人给我看看,是不是AD芯片时钟信号给的不对?下面是程序
#include <reg52.h>                    //52系列单片机头文件
#include <intrins.h>
#include "math.h"
#define uchar unsigned char
#define uint unsigned int
sbit st=P2^2;                //定义AD的WR端口
sbit oe=P2^3;                //定义AD的RD端口
sbit eoc=P2^0;
sbit ale=P2^1;

sbit lcden=P2^6;        //液晶使能端
sbit lcdrs=P2^4;        //液晶数据命令选择端

sbit ADDA=P2^5;                //定义A、B、C三条地址线
sbit ADDB=P3^6;
sbit ADDC=P3^7;
sbit CLK=P2^7;          //定义时钟端口
uint a,num;
float OPA,OPB,AD;
uchar code table41[]="WELCOME!";


/*********
延迟函数
**********/
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
/************
2002写命令
**************/
void write_com(uchar com)
{
        lcdrs=0;
        P0=com;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
/************
2002写数据
*************/
void write_data(uchar date)
{
        lcdrs=1;
        P0=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
/****************
液晶初始化
*********************/
void init()
{
        lcden=0;
        write_com(0x38);//设置2002显示,5X7点阵,8位数据接口
        write_com(0x0c);//设置开显示,不显示光标
        write_com(0x06);//写一个字符后地址指针加1
        write_com(0x01);//显示清零,数据指针清零
}
/********************
显示程序
****************************/
void display(uint x,uint qian,uint bai,uint shi,uint ge)
{
        write_com(0x80+x);
        write_data(0x30+qian);
        write_data('.');
        write_data(0x30+bai);
        write_data(0x30+shi);
        write_data(0x30+ge);
}
/********************
   定时中断初始化,为了产生AD芯片需要的时钟信号
*********************/
void init_time0()
{
     TMOD = 0x02;
         TH0=(65536-100)/256;
         TL0=(65536-100)%256;
         IE   = 0x82;
         TR0  = 1;
}

/********************
A通道OPA光电压采集
***********************/
void OPA_1()
{
   
             ADDA=1;           //选择通道1
             ADDB=0;
             ADDC=0;
             oe=0;                //关闭输出允许位
             st=0;
             st=1;
             st=0;                //以上三句,开ADC0809
             delay(1);        //延迟1ms
             while(!eoc);//等待转化结束
             P1=0xff;
             oe=1;                //开启输出允许位
             a=P1;                //将转化出的数字存放至a
             a=a*19.53125;          //  a=a*5/256*1000
             OPA=a*0.001;  
}
/********************
主函数:
*******************/
void main()
{       
     uint a1,a2,a3,a4;

     init_time0();
         init();
         write_com(0x80+0x07);
     for(num=0;num<8;num++)
     {
                  write_data(table41[num]);
                  delay(150);
         }
         delay(1000);
     while(1)
     {                              
               
                 OPA_1();//A路光电压采集                                
                 a1=a/1000;
             a2=a/100%10;
             a3=a/10%10;
             a4=a%10;
             display(0x48,a1,a2,a3,a4);                      
         }                  
}
void Timer0_INT() interrupt 1        //用定时中断产生ADC芯片时钟信号
{

        TH0=(65536-100)/256;
        TL0=(65536-100)%256;
        CLK = ~CLK;
}  
回复

使用道具 举报

6#
ID:403018 发表于 2018-9-27 10:19 | 只看该作者
看下ADC0809这个芯片手册提供的时序,然后看看你程序是不是一致,如果大致没问题,可以尝试微调下延时的时间,如有需求可以加Q:1327360970
回复

使用道具 举报

7#
ID:303383 发表于 2018-9-27 10:59 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

8#
ID:388197 发表于 2018-9-27 11:01 | 只看该作者
8位重载模式,定时计数器高8位和低8位应该值相等才对.
并且不需要在中断函数里面对TH0 TL0进行设置.
void Init_T0()              //12M晶振12分频
{
  TMOD |=0x02;
  TH0 = 0x9c;
  TL0 = 0x9c;
  ET0 = 1;
  TR0 = 1;
  EA = 1;
}

中断服务函数
void Timer0_ISR () interrupt 1
{
    CLK = ~CLK;
}
如果没有示波器,你可以接个LED到CLK口,然后用中断写个1秒闪一次的程序看看LED会不会闪就知道了,如果闪,把频率改高就行.
用AD直接用12系列以上的51现在新出的芯片片上都集成了12位的ADC,只需要1个IO口作为模拟输入口就行,ADC0809这种过时的芯片,除了在过时的书上面,实际运用中根本不会用到.
回复

使用道具 举报

9#
ID:394367 发表于 2018-9-27 11:40 | 只看该作者
yk910127 发表于 2018-9-27 10:19
看下ADC0809这个芯片手册提供的时序,然后看看你程序是不是一致,如果大致没问题,可以尝试微调下延时的时 ...

好的,我试试,谢谢了
回复

使用道具 举报

10#
ID:394367 发表于 2018-9-27 15:27 | 只看该作者
看来,直接用89C52直接产生不了AD芯片需要的时钟信号(500-640KHZ),实物上没有产生clk这个时钟信号。
回复

使用道具 举报

11#
ID:394367 发表于 2018-9-27 16:54 | 只看该作者
cjm82 发表于 2018-9-27 11:01
8位重载模式,定时计数器高8位和低8位应该值相等才对.
并且不需要在中断函数里面对TH0 TL0进行设置.
void  ...

我想请问下,用STC12系列的单片机是不是采集电压直接连IO口就可以了,不用其他外围电路了吧。你有类似的电路么
回复

使用道具 举报

12#
ID:249808 发表于 2018-9-28 09:34 | 只看该作者
有时候不要光想着软件问题,有可能是硬件问题呢?之前我弄了一个搞了半天,结果是硬件的问题,你查一下基准电压,还有电阻的阻值啊!这些有偏差也会导致电压不准的!
回复

使用道具 举报

13#
ID:388197 发表于 2018-9-28 09:56 | 只看该作者
FJ2018 发表于 2018-9-27 16:54
我想请问下,用STC12系列的单片机是不是采集电压直接连IO口就可以了,不用其他外围电路了吧。你有类似的 ...

一般应用直接接带有ADC功能的IO口,设置相关寄存器就行,怎么设置手册里有详细的介绍,12系列ADC是10位的,最新的8系列IO口是12位的.QFP64封装的有单独的ADC电源和参考电压引脚,适合接基准源精度较高的场合.相关电路手册里也有,下图是从手册里截的,最常用的接法

QQ图片20180928094823.png (42.8 KB, 下载次数: 38)

QQ图片20180928094823.png
回复

使用道具 举报

14#
ID:394367 发表于 2018-9-28 17:30 | 只看该作者
cjm82 发表于 2018-9-28 09:56
一般应用直接接带有ADC功能的IO口,设置相关寄存器就行,怎么设置手册里有详细的介绍,12系列ADC是10位的,最 ...

我今天用12系列的做出来了,也采到了电压。谢谢你们了。
回复

使用道具 举报

15#
ID:230313 发表于 2018-11-7 22:12 | 只看该作者
楼主,我的也遇到相同问题能加下你,问下么
回复

使用道具 举报

16#
ID:388197 发表于 2018-11-7 23:01 | 只看该作者
不要在AD0808之类的过时芯片上浪费时间了,0808占用IO口超多,还需提供时钟,并且只有8位.现在的单片机基本都集成了ADC功能,分辨率也完爆0808,要求不高的话,模拟电压量直接接到IO剩下的工作就是敲键盘而已.寄存器设置参考手册上的例程即可,非常简单.可以说0808已经没有任何使用价值,这完全是教材跟不上时代的原因.(没记错的话0808的价钱还比片上集成12位ADC的51价格还贵)个人觉得学51最好的教材就是参考手册
回复

使用道具 举报

17#
ID:394367 发表于 2019-3-29 14:39 | 只看该作者
xuanshao 发表于 2018-11-7 22:12
楼主,我的也遇到相同问题能加下你,问下么

建议还是用带ADC的单片机采集AD吧
回复

使用道具 举报

18#
ID:481641 发表于 2019-4-3 16:32 | 只看该作者
仿真不准正常
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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