找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4632|回复: 5
收起左侧

[求助]ADC0804与天祥TX-1C,数码管总是现实255

[复制链接]
ID:44052 发表于 2012-8-20 22:16 | 显示全部楼层 |阅读模式

我用的是天祥TX-1C的开发板,用单片机控制ADC0804进行数模转换,当拧动实验板上A/D旁边的电位时,在数码管的前三位以十进制方式显示出A/D转换后的数字量,但为什么一直显示255,而不变换,为什么????程序如下,附件是原理图

#include <reg52.h>      //52系列单片机头文件
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;  //申明U1锁存器的锁存端
sbit wela=P2^7;  //申明U2锁存器的锁存端
sbit adwr=P3^6;  //定义AD的WR端口
sbit adrd=P3^7;  //定义AD的RD端口
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delayms(uint xms)    
{
 uint i,j;
 for(i=xms;i>0;i--)        //i=xms即延时约xms毫秒
  for(j=110;j>0;j--);
}

void display(uchar bai,uchar shi,uchar ge)  //显示子函数
{
    dula=1;
 P0=table[bai];    //送段选数据
 dula=0;
 P0=0xff;  //送位选数据前关闭所有显示,防止打开位选锁存时
 wela=1;   //原来段选数据通过位选锁存器造成混乱
 P0=0x7e;  //送位选数据
 wela=0;
 delayms(5);     //延时

 dula=1;
 P0=table[shi];
 dula=0;
 P0=0xff;
 wela=1;
 P0=0x7d;
 wela=0;
 delayms(5);

 dula=1;
 P0=table[ge];
 dula=0;
 P0=0xff;
 wela=1;
 P0=0x7b;
 wela=0;
 delayms(5);
}


void main()  // 主程序
{

  uchar a,A1,A2,A3,adval;
 wela=1;
 P0=0x7f;           //置CSAD为0,选通ADCS 以后不必再管ADCS
 wela=0;
    while(1)
 {
  adwr=1;
  _nop_();
  adwr=0;   //启动AD转换
  _nop_();
  adwr=1;
  for(a=10;a>0;a--)        //TX-1C实验板AD工作频率较低,所以启动转换后要多留点时间用来转换
  {                        //这里把显示部分放这里的原因也是为了延长转换时间                                                                                                                                                                                                                          
   display(A1,A2,A3);
  }
  P1=0xff;                    //读取P1口之前先给其写全1
  adrd=1;                    //选通ADCS
  _nop_(); 
  adrd=0;                     //AD读使能
  _nop_();
  adval=P1;   //AD数据读取赋给P1口
  adrd=1;
  A1=adval/100;  //分出百,十,和个位
  A2=adval%100/10;
  A3=adval%10;
  }
}

tx-1c型单片机开发板原理图.pdf (1015.98 KB, 下载次数: 12)
回复

使用道具 举报

ID:51300 发表于 2013-6-28 21:12 | 显示全部楼层
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit dula=P2^6;
sbit wela=P2^7;
sbit wr=P3^6;
sbit rd=P3^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar aa,bai,ge,shi,d,a;
void display(uchar bai,uchar shi,uchar ge);
void init()
{
        TMOD=0x01;
        TH0=0x80;
        TL0=0xFE;
        EA=1;
        ET0=1;
        TR0=1;
        aa=0;
   


}
void start()
{
   
        wr=1;
        _nop_();
        wr=0;
        _nop_();
        wr=1;       

}
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=10;y>0;y--);
}
void main()
{
  init();
  
  while(1)
        {
                start();
                 rd=1;
                         _nop_();
                 rd=0;
                         _nop_();
                      d=P1;
      
                  rd=1;
                  bai=d/100;
             shi=d%100/10;
             ge=d%10;
                for(a=10;a>0;a--)
            {       
              display(bai,ge,shi);
               
                 }
                }

}

void display(uchar bai,uchar shi,uchar ge)
{
         dula=1;
                P0=table[bai];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0x7e;
                wela=0;
                delay(1);

                dula=1;
                P0=table[shi];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0x7d;
                wela=0;
                delay(1);

                dula=1;
                P0=table[ge];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0x7b;
                wela=0;
                delay(1);
}
void timer0() interrupt 1
{
        TH0=0x80;
        TL0=0xFE;
        aa++;       
}我的这个程序没问题
回复

使用道具 举报

ID:225054 发表于 2017-9-24 08:51 来自手机 | 显示全部楼层
读前读数据rd前要把cs置0也就是wela=1;P0=0x7f

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:661907 发表于 2019-12-11 20:50 | 显示全部楼层
我也遇到了,然后改改改,就正确了,加了注释,代码如下:

/*
原理:
ADC0804: ADC0804是8位全MOS中速A/D 转换器,它是逐次逼近式A/D 转换器,片内有三态数据输出锁存器,
可以和单片机直接接口。单通道输入,转换时间大约为100us。
ADC0804 转换时序是:当CS=0 许可进行A/D 转换。
WR由低到高时,A/D开始转换,一次转换一共需要66-73 个时钟周期。
CS与WR同时有效时启动A/D转换,转换结束产生INTR 信号(低电平有效),可供查询或者中断信号。
在CS和RD 的控制下可以读取数据结果。本实验没有使用INTR信号。
*/

//拧动AD旁边的电位器,会在数码管的前三位显示0-255之间的数值。
//这就是把模拟信号转换成数字信号,即模数转换。

#include <reg52.h>        //52系列单片机头文件
#include <intrins.h>        //包含_nop_()函数所在的头文件
#define uint unsigned int
#define uchar unsigned char

sbit dula=P2^6;        //声明U1锁存器的锁存端
sbit wela=P2^7;        //声明U2锁存器的锁存端

//IO口定义
sbit adwr=P3^6; //定义A/D的WR端口
sbit adrd=P3^7; //定义A/D的RD端口
//数码管编码
uchar code table[]={0x3f,0x06,0x5b,0x4f,
                                        0x66,0x6d,0x7d,0x07,
                                        0x7f,0x6f,0x77,0x7c,
                                        0x39,0x5e,0x79,0x71};

void delayms(uint xms) //延时函数
{
        uint i,j;
        for(i=xms;i>0;i--)
                for(j=110;j>0;j--);
}

void display(uchar bai,uchar shi,uchar ge) //显示子函数
{
        //显示百位
        dula=1;
        P0=table[bai]; //送段选数据
        dula=0;
        P0=0xff;        //送位选数据前关闭所有显示,防止打开位选锁存时原来段选数据通过锁存器造成混乱
        wela=1;
        /*将U2锁存器的输出口的最高位置低电平,目的是将与之相连的ADC0804的CS片选端置低选中。
    一次选中,以后再不用管它。以后凡是操作U2锁存器的地方都不要再改变A/D的CS端*/
        P0=0x7e;  //在数码管显示程序中,送出位选信号时,始终保持U2锁存器的最高位为低电平。位选第一个数码管0111 1110
        wela=0;
        delayms(5);
       
        //显示十位/
        dula=1;
        P0=table[shi]; //送段选数据
        dula=0;
        P0=0xff;
        wela=1;
        P0=0x7d;        //位选第二个数码管 0111 1101       
        wela=0;
        delayms(5);

        //显示个位
        dula=1;
        P0=table[ge]; //送段选数据
        dula=0;
        P0=0xfe;
        wela=1;
        P0=0x7b;        //位选第三个数码管 0111 1011       
        wela=0;
        delayms(5);
}

void main() // 主程序
{
        uchar a,A1,A2,A3,adval; //百十个,A/D value
        wela=1;
        P0=0x7f;        //置CSAD为0,选通ADCS,以后不必再管ADCS
        wela=0;

        while(1)
{
        adwr=1;  //写信号输入
        _nop_();  //_nop_()函数,延时一个机器周期
        adwr=0;        //低电平,启动AD转换
        _nop_();
        adwr=1;
        //立即先送结果给数码管显示,给A/D转换留有一定时间
        for(a=20;a>0;a--)  //TX-1C实验板A/D工作频率较低,所以启动转换后要多留点时间用来转换
        {  //把显示部分放这里的原因也是为了延长转换时间(增加写读之间的时间间隔)
                display(A1,A2,A3);
        }

        P1=0xff;  //读取P1口之前先给其写全1
        adrd=1;  //选通ADCS
        _nop_();  //延时一个机器周期
        adrd=0;  // A/D读使能
        _nop_();

        adval=P1; // A/D数据读取赋给P1口
        adrd=1;
        A1=adval/100; //分出百,十,和个位
        A2=adval%100/10;
        A3=adval%10;
        }
}
/*
1、首次上电会看到显示全是0,但马上又出现数字:首次显示完后,接下来便读取到了A/D转换后的结果,
当程序再次循环回来时,便显示了上次的数值。
2、拧动电位器,数码管上数字始终不动,只有复位一次,或者重新上电一次,数字才会刷新:因为转换时间不够。
两种解决办法:一是将实验板上C11电容换成150pF;
                            二是再适当延长A/D转换时间,即增加数码管显示的次数,可将上例for(a=10;a>0;a--)中的a值增大。
*/

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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