[求助] 是不是ADC0808的程序部分有问题,为什么仿真出来数据不变呢

曾苗筠   2017-5-26 11:41 楼主

电路图是我自己根据功能要求和器件手册设计的,不确定有没有错误,电气检查有一些WARNING 但可导入程序仿真。 总体
局部。
adc0808 lcd1602
大致功能要求:1.倾角传感器经AD将倾角显示至LCD(我把传感器用电位器代替,想着把电压换成角度表示)     
                         2.经运算DA输出一定电压对工作平台倾角进行调整(这个没想好怎么用仿真实现,就只在DAC0832后接了个电压表)
                         3.压力传感器检测超载偏载后声光报警(蜂鸣器和LED)(图中没画第二个电位器以后再加)

最近刚开始调程序,第一步想先调AD0808和LCD1602。

程序主要参考了下面两个链接并根据自己的图进行修改(因为单片机端口不够在P1口接了个锁存器U3)

ADC0808为啥仿真出来的数字不正确呢,算法都正确啊,但是
https://bbs.eeworld.com.cn/forum. ... 7035&fromuid=781354
(出处: 电子工程世界-论坛)

http://blog.csdn.net/u013151320/article/details/46663167

【问题】仿真运行时LCD一直显示的是0.15V,调整电位器对数据显示没有影响,是不是AD程序编得不对或者别的问题?我并没有加什么奇怪的语句啊
     另外,我也不太懂第一个链接readtemp里VOL的算法,以及b c d为啥要加48?


呃问题有点多前路漫漫我加油一个一个解决吧~希望有懂的人儿可以帮我指点一下!谢谢!感激不尽!
  • 仿真

回复评论 (2)

第一次发帖有点混乱。。程序不知道咋没发上来。。我回去整理一下重新发
点赞  2017-5-26 11:47
先贴一下程序吧

#include
#include
#include       //其中有nop函数的定义
#define uchar  unsigned char
#define uint   unsigned int

/* sbit lcdRS=P1^3;       //定义数据命令选择端
   sbit lcdRW=P1^4;       //定义读写选择端
   sbit lcdEN=P1^5;       //定义使能端           */

sbit xuan=P3^1;           //申明U3锁存器的锁存端     //该锁存器输入D接P1,输出Q
sbit ST=P3^6;
sbit EOC=P3^3;
sbit OE=P3^7;
sbit CLOCK=P3^2;

uint a,b,c,d,VOL;
unsigned char code dis1[]={"Vol:"};  //第一行要显示的字符
uchar dis2[]= { "Angel:"};             //第二行

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

//*******************************************
//    判断lcd1602是否处于忙的状态,即读忙   
//*******************************************
uchar lcd1602_ReadBusy()         
{
    uchar temp;
    xuan=1;                        //打开U3锁存端
    P1=0x10;                       //P1=000 10 000   //lcdRS=0; lcdRW=1; //RS=0选择指令寄存器;RW=1读
    xuan=0;                        //关闭U3锁存端

    _nop_();
    P0=0xff;                       //读某IO口数据前,先将该口置为1            
    _nop_();

    xuan=1;                        
    P1=0x30;                       //P1=00 1 10000   //lcdEN=1; //E端使能端,E从高电平到低电平时(1--0),lcd执行命令
    xuan=0;                        

    _nop_();
    temp=P0;                       //读取此时lcd1602的状态字
   _nop_();

    xuan=1;                        
    P1=0x10;                       //P1=00 0 10000  //lcdEN=0;
    xuan=0;                        

    return (temp&0x80);      //如果忙

    /*状态字为temp(8位2进制数)的最高位,最高位为1表示禁止读写,为0表示允许读写,
即temp&0x80得1表示忙,得0表示不忙*/
}

//*******************************************
//                  写命令
//*******************************************
void lcd1602_WriteCom(uchar com)  
{
    while(lcd1602_ReadBusy());     //判忙
    xuan=1;                        
    P1=0x00;                       //P1=000 00 000  //lcdRS=0;lcdRW=0;  //指令;写
    xuan=0;

    _nop_();
    P0=com;                        //准备发送命令
    _nop_();

    xuan=1;                        
    P1=0x20;                       //P1=00 1 00000  //lcdEN=1;
    xuan=0;

    _nop_();
    _nop_();

    xuan=1;                        
    P1=0x00;                       //P1=00 0 00000  //lcdEN=0;
    xuan=0;

    _nop_();
    _nop_();   
}

//*******************************************
//                  写数据
//*******************************************
void lcd1602_WriteData(uchar dat)
{
    while(lcd1602_ReadBusy());     //判忙
    xuan=1;                        
    P1=0x08;                       //P1=000 01 000  //lcdRS=1; lcdRW=0;  //数据;写
    xuan=0;

    _nop_();
    P0=dat;
    _nop_();

    xuan=1;                        
    P1=0x28;                       //P1=00 1 01000  //lcdEN=1;
    xuan=0;

    _nop_();
    _nop_();

    xuan=1;                        
    P1=0x08;                       //P1=00 0 01000  //lcdEN=0;
    xuan=0;

    _nop_();
    _nop_();   
}

//*******************************************
//               lcd初始化函数
//*******************************************
void lcd1602_init()               
{
    delayms(15);
    lcd1602_WriteCom(0x38);        //显示模式设置
    delayms(5);
    lcd1602_WriteCom(0x38);
    delayms(5);
    lcd1602_WriteCom(0x38);
    lcd1602_WriteCom(0x0c);        //显示开及光标设置
    lcd1602_WriteCom(0x06);              //显示光标移动设置
    lcd1602_WriteCom(0x01);        //显示清屏
}

//*******************************************
//                 lcd显示
//*******************************************   
void display(void)
{
    uint i,j;
    lcd1602_init();

    lcd1602_WriteCom(0x80);        //0x80是第一行的第一个字符的地址
    for(i=0;i<10;i++)  
       lcd1602_WriteData(dis1[i]);  

    lcd1602_WriteCom(0x80+0x40);   //0xc0是第二行的第一个字符的地址  //表示的方法有很多,可以用0xc0,0x80+0x40,0x80|0x40等等
    for(j=0;j<10;j++)
       lcd1602_WriteData(dis2[j]);
}

//*******************************************
//            ad0808转换数据并显示
//*******************************************
void readtemp()
{
    OE=0;                                 //ad输出允许OE,高有效
    ST=0;ST=1;ST=0;                //ad转换启动ST,高有效  //启动转换

    while(!EOC);                       //EOC转换结束,高有效,即相当while(EOC==0)或while(1)  //等待转换结果
    OE=1;                                //允许输出
    a=P1;
    OE=0;                                //关闭输出
    delayms(10);
    VOL=a*1.0/256*500;           //不太懂?
    b=VOL/100;
    c=VOL/10%10;
    d=VOL%10;            
     
    lcd1602_WriteCom(0x85);        //(0x80+0x05) 05是第一行第六列
    lcd1602_WriteData(b+48);   
    lcd1602_WriteData(0x2e);       //小数点
    lcd1602_WriteData(c+48);
    lcd1602_WriteData(d+48);
    lcd1602_WriteData('V');
}


void main()
{
    lcd1602_init();
    TMOD=0x01;                     //设定时器1工作方式0,13位定时/计数器;定时器0工作方式1,16位定时/计数器
    TH0=(65536-2)/256;
    TL0=(65536-2)%256;
    TR0=1;                             //启动定时器0
    ET0=1;                             //开定0中断
    EA=1;                              //开总中断
    CLOCK=0;
    display();
        while(1)
    {  
     readtemp();
    }   
}

void t0(void) interrupt 1 using 0   //这个中断左右是使CLOCK产生500kHZ的脉冲
{
    TH0=(65536-2)/256;
    TL0=(65536-2)%256;
    CLOCK=!CLOCK;                     //ADC0809时钟信号        
}                                 
点赞  2017-5-26 11:47
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复