你好,我想问一下AD转换的问题,这是我写的用数码管显示AD结果的程序,仿真时总时出现问题,

#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned char int datah,datal,i,ad,b;int date1;char a;sbit CLOCK=P2^1;sbit CS=P2^2;sbit EOC=P2^0;sbit ADIN=P2^3;sbit DOUT=P2^4;char duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};char wei[]={0x06,0x05,0x03};char zhong[]={0,0,0};void delay(uchar t) //延时函数{ char n; while(t--) { for(n=10;n>0;n--); }}void init_ding() //定时器初始化{ TMOD=0x01; TH0=(65536-10000)/256; //5ms扫描一次 TL0=(65536-10000)%256; EA=1; ET0=1; TR0=1;}int readTLC1543(uchar port) // ad转换函数{ CLOCK=0; CS=0; EOC=1; port<<=4; for(i=0;i<4;i++) //进行通道的选择 { ADIN=(bit)(port&0x80); CLOCK=1; CLOCK=0; port<<=1; } for(i=0;i<6;i++) //产生6个时钟脉冲,进行数据的采样 { CLOCK=1; CLOCK=0; } CS=1; delay(10); CS=0; for(i=0;i<2;i++) //读出高两位数据 { CLOCK=1; datah<<=1; if(DOUT)datah|=0x01; CLOCK=0; } for(i=0;i<8;i++) //读出后八位数据 { CLOCK=1; datal<<=1; if(DOUT)datal|=0x01; CLOCK=0; } EOC=0; CS=1; ad=datah; ad<<=8; ad|=datal; return(ad);}void main(){ init_ding(); while(1) { date1=readTLC1543(0x01); P2=date1; zhong[2]=date1%10; zhong[1]=date1%100/10; zhong[0]=date1/100; } }void timer0() interrupt 1 //定时器中断函数{ TR0=0; TH0=(65536-10000)/256; TL0=(65536-10000)%256; P0=duan[zhong[2]]; P3=wei[a]; a++; if(a==3) a=0; TR0=1; }

int datah,datal,i,ad,b;//改为unsigned int类型
int date1;//改为unsigned int date1
char a;//改为unsigned char a=0;

void timer0() interrupt 1  //定时器中断函数
{
   TR0=0;
   TH0=(65536-10000)/256;//10ms中断一次
   TL0=(65536-10000)%256;
   P0=duan[zhong[2]];//改为P0=duan[zhong[a]];
   P3=wei[a];
   a++;
   if(a==3)//改为if(a>=3)
    a=0;
   TR0=1;
   
}

做了以上修改后,如果显示还有问题,那就先将AD部分屏蔽掉,单独调试数码管显示这一部分。调试时,可以让date1固定等于已知值,如123,这样正常显示时应该为123.

void main()
{
    init_ding();
    while(1)
    {
//      date1=readTLC1543(0x01);
//      P2=date1;
        date1=123;//test
      zhong[2]=date1%10;
      zhong[1]=date1%100/10;
      zhong[0]=date1/100;
  
     } 
}

待显示部分调试通过后,再加入AD部分的代码。

追问

嗯,按你讲的将AD屏蔽掉后,能显示123,但又重新将AD恢复后,显示的是乱码,就是0123456789这几个都显示。我又加了这一行,还是这样

追答

造成乱码的根本原因是没有做消隐处理。

void timer0() interrupt 1  //定时器中断函数
{
   TR0=0;
   TH0=(65536-10000)/256;//10ms中断一次
   TL0=(65536-10000)%256;
   P3=0xff;//【增加消隐处理】
   P0=duan[zhong[2]];//改为P0=duan[zhong[a]];
   P3=wei[a];
   a++;
   if(a==3)//改为if(a>=3)
    a=0;
   TR0=1;
    
}

追问

嗯,我改过了,现在显示的值能随电压的变化而变化,但是当电压为5v时值为535,而不是1024? 而且在电压从5降到3.8v这一段内,显示值是逐渐递减的,但再往下就又乱了?我把采样程序放到了中断里面。

追答

你对TLC1543的驱动正确吗?AD结果正确吗?

追问

嗯,这两个图用的是同一个采集程序

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-05-15
你的问题很不明确,你想要显示什么,还有用的是什么AD转换芯片,串行还是并行的,还是内置的。现在想帮你也没法帮。追问

用的是TLC1543芯片 串口输出 将转换后的ad值显示在数码管上

追答

变量a没有赋初值,所以刚一上电运行时其值不是0,所以取出数组的值未知。不管别的地方错没错,反正这个地方我觉得不对劲。

追问

可仿真还是和原来的一样呀,我用二极管模拟ad转换后的结果正常,就是将值显示到数码管时不行

追答

P0=duan[zhong[2]];改为P0=duan[zhong[a]];

追问

呵呵呵!不小心弄错了呀!
可改后还是仿真不出来,

追答

以下代码我用硬件调试成功了,为适应我的开发板,我把P2和P3换了以下。给你点思路。只能帮到这了。

void main()

{  

int i;

    init_ding();  

date1=0;

    while(1)

    {

      //date1=readTLC1543(0x01);

 readTLC1543(0x01);

      P3=date1;

      zhong[2]=date1%10;

      zhong[1]=date1%100/10;

      zhong[0]=date1/100;

 for(i=0;i<50;i++)

    delay(1000);

 date1++;

     } 

}

void timer0() interrupt 1  //定时器中断函数

{

   TR0=0;

   TH0=(65536-10000)/256;

   TL0=(65536-10000)%256; 

   P0=~duan[zhong[a]];

   P2=wei[a];

   a++;

   if(a==3)

    a=0;

   TR0=1;

   

}

运行效果:

追问

哈哈哈!太感谢了。
你那个date1++什么意思啊

追答

自增运算符,我是在调试时为了看看是否所有的数字都能在数码管上正常显示而写的。
还有一种可能,就是在进行AD转换时发生了中断,因为你的AD转换函数中有延时,如果在这段时间发生中断,很有可能导致时序错误,因为你的AD芯片是串行的。

本回答被提问者采纳
相似回答