ADC0809数字电压表显示问题

2019-03-24 17:33发布

设计图如下, 设计图 设计图
由于硬件已经实现,无法更改,还望大神多多帮忙。
源代码如下
//---------------------------------------
// AD0809 by maomaochong
// Date: 2011/8/31
// Time: 15:54
// Function: ADDA-ADDC connect to P2.0-P2.2 to choose AD channel
//---------------------------------------

#include "reg51.h"

sbit ST_ALE=P3^0;                //START and ALE both connect to P3.0
sbit EOC=P3^1;                        //EOC connect to P3.1                                       
sbit OE=P3^2;                        //OE conect to P3.2
sbit CLK=P3^3;                        //CLK connect to P3.3
unsigned char CHANNEL;        //AD channel variable
unsigned char LED[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//common cathode LED code
unsigned char CHECK[4]={0xFE,0xFD,0xFB,0xF7};        //choose LED channel

void delay(unsigned char time)
{
        unsigned char i,j;
        for(i=time;i>0;i--)
                for(j=250;j>0;j--)
                ;
}

void display()
{
        unsigned long temp;
        unsigned char DATA,digit[4];
        unsigned int k,l;
        DATA=P1;                                        //save AD data
        temp=DATA;                                        //the temporary variable
    temp=temp*1000/51;                        //AD formula:D=A*5/255
        digit[0]=temp/1000;                        //the thousands place
        digit[1]=temp%1000/100;                   //the hundreds place
        digit[2]=temp%1000%100/10;         //the tens place
        digit[3]=temp%1000%100%10;        //the ones place
        DATA=P2;                                          //save P2
        for(k=0;k<1000;k++)
        {
        /*        lighten each LED and equal the below for loop
                P1=LED[digit[0]]+0x80;
                P2_4=0;
                P2_4=1;
                P1=LED[digit[1]];
                P2_5=0;
                P2_5=1;
                P1=LED[digit[2]];
                P2_6=0;
                P2_6=1;
                P1=LED[digit[3]];
                P2_7=0;
                P2_7=1;
        */
                for(l=0;l<4;l++)
                {
                        P2=P2|0x0F;                        //avoid LED residual
                        P0=LED[digit[l]]+0x80*(l==0);        //LED code
                        P2=DATA&CHECK[l];        //choose LED channel
                }
        }
        P2=DATA;                                        //restore P2       
}

void main()
{

        ST_ALE=0;                        //START and ALE default
        OE=0;                                //OE default
        TMOD=0x02;                        //T0 operate in mode 2
       
        EA=1;                                //all interrupt enable
        ET0=1;                                //T0 interrupt enable
        TR0=1;                                //T0 run
        while(1)
        {
               
                ST_ALE=1;                //lock the AD channel address
                ST_ALE=0;                //AD run
                while(EOC==0);        //wait until AD over
                OE=1;                        //enable to transmit AD data
                display();                //view the AD result and diaplay LED
               
       
               
        }       
}

void T1_TIME() interrupt 1 using 0
{
        CLK=~CLK;                        //CLK 500 kHz
}

问题:滑动变阻器显示的电压和数码管显示的电压数值不等,不知道具体问题是哪里,还望大神多多指教。新生小白一只,刚刚接触单片机,还望多多指教! 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
本站帐号
2019-03-25 10:20
我把我这两天写的ADC0809程序拷给你,你看一下吧,我的原因是ADC0809芯片的时钟频率达不到,以致ADC0809不能工作,显示用的LCD1602液晶显示屏做的,不过差别不大。
   #include<reg51.h>  #include   <lcd1602.h>                  //宏定义,包含头文件lcd1602.h
  #include<intrins.h>
  #include<stdio.h>

  sbit adress_A=P1^2;                //需要接,还有VCC和VREF+,还有adress_B和adress_C;
  sbit ALE=P3^6;                   //
  sbit start=P3^5;                  //
  sbit clk=P1^7;                  //
  sbit EOC=P3^7;                  //
  sbit OE=P1^6;                          //
  sbit D0=P2^0;                         //
  sbit D1=P2^1;                         //
  sbit D2=P2^2;                         //
  sbit D3=P2^3;                         //
  sbit D4=P2^4;                         //
  sbit D5=P2^5;                        //
  sbit D6=P2^6;                        //
  sbit D7=P2^7;                        //

// sbit jidianqi=P3^0;
  sbit K2=P3^2;

    int flag=4,i=0;


  void Delay(unsigned int c);
  void h(float temp);

  void Delay(unsigned int c)
  {
          while(c--);
  }
void timer0init()        
{  
    TMOD=0x01;           
    TH0=(65536-1)/256;      
    TL0=(65536-1)%256;   
    EA=1;     
    ET0=1;      
    TR0=1;
        clk=0;        
}

void main()
{          
    unsigned int temp_data=0;
    float a;
    int U=0;
        timer0init();
    LCD_init();
    IT0=1;
        EX0=1;
        EA=1;
        while(1)
    {       
                        ALE=0;start=0;
                        _nop_();_nop_();_nop_();
                        adress_A=0;
                        Delay(10);
                        ALE=1;
                        start=0; _nop_();_nop_();_nop_();       
                        start=1;
                        _nop_();_nop_();_nop_();
                        start=0;                                  
                //        while(!EOC);
                        P2=0xff;
                        OE=1;
                        Delay(13);
                        temp_data=P2;
                        ALE=0;                       
                        OE=0;
                  a=(float)(temp_data*5/4095.0);         
                  h(a);                                                       //显示部分传值函数
                   Delay(10);  //延时等待芯片反应
        }

  }
  void h(float temp)
{
    unsigned char str[9];
        unsigned char a[]="Recent Voltage";       
        unsigned char b[]="Recent Electry ";
//        sprintf(str,"%.3f",temp);
//        LCD_dsp_string(0,0,str);           //lcd1602第一行显示
//        LCD_dsp_string(1,0,"SUCCESSFUL");  //lcd1602第二行显示
          if(flag==4)
        {
        sprintf(str,"%.3f",temp);
            LCD_dsp_string(0,0,"guoliu baohu");
                LCD_dsp_string(4,1," ");                                 //空格消除由于档位切换,字符长度不同导致的显示问题
                LCD_dsp_string(11,1,"V");
        }   

        if(flag==0)
        {       
        sprintf(str,"%.3f",temp);
                LCD_dsp_string(0,0,"0V--5V Voltage");           //lcd1602第一行显示
           LCD_dsp_string(11,1,"V");  //lcd1602第二行显示
           LCD_dsp_string(4,1," ");
            LCD_dsp_string(10,1," ");
            LCD_dsp_string(12,1,"   ");
          }
   if(flag==1)
        {
            sprintf(str,"%.3f",temp);
                LCD_dsp_string(4,1,"-");
            LCD_dsp_string(11,1,"V");
            LCD_dsp_string(0,0,"-5V-0V Voltage");
                LCD_dsp_string(10,1," ");
                LCD_dsp_string(12,1,"   ");
        }
   if(flag==2)
        {
            temp=temp*1000/200;
            sprintf(str,"%.3f",temp);
            LCD_dsp_string(11,1,"mA");
            LCD_dsp_string(0,0,b);
                LCD_dsp_string(4,1," ");
                LCD_dsp_string(13,1,"   ");
        }   
   if(flag==3)
        {

            temp=temp*3;
                LCD_dsp_string(0,0,"9V-12V Voltage");
            sprintf(str,"%.3f",temp);
           LCD_dsp_string(11,1,"V");
        LCD_dsp_string(4,1," ");
        LCD_dsp_string(10,1," ");
        LCD_dsp_string(12,1,"  ");
        }                          
        LCD_dsp_string(5,1,str);
}
  void timer0() interrupt 1
{
            TH0=(65536-1)/256;        
            TL0=(65536-1)%256;  
                clk=~clk;
}

void  counter(void) interrupt 0                    //外部中断
{
   EX0=0;                                                   //关闭中断,防止在执行中断过程中又进入中断
        i++;
   if(i==1)
      flag=0;                                         //zhengchang dianya
        if(i==2)
            flag=1;                                         //fu dianya
        if(i==3)
           flag=2;                                 //dianliu
         if(i==4)
         {   
            flag=3;                                //9-12V dianya
                i=0;
                }

   Delay(60);                                          //时间延迟,消除按键抖动
   EX0=1;                                                  //kai zhongduan
}

LCD1602.c文件
//adc0809+最小系统+LCD1602液晶显示屏
#include        <lcd1602.h>        //宏定义,包含头文件lcd1602.h
#include<reg51.h>
#define  LCDIO  P0                           //定义数据端口
sbit LCD1602_RS = P1^5;                   //数据命令选择接口
sbit LCD1602_RW = P1^3;                   //读写选择接口
sbit LCD1602_EN = P1^4;                   //使能信号接口

/**
* @brief LCD1602初始化函数
*
* @param 无
* @return 无
* @note
*/
  void Delay(unsigned int c);
void LCD_init(void)
{
        LCD_write_command(0x01);         //清屏
        LCD_write_command(0x38);         //设置16*2显示,5*7点阵,8位数据接口模式
        LCD_write_command(0x38);         //设置16*2显示,5*7点阵,8位数据接口模式
        LCD_write_command(0x0C);         //打开LCD显示 ,不显示光标,光标不闪烁
        LCD_write_command(0x06);         //设置LCD第一个显示的地址
        LCD_write_command(0x01);     //清屏
}

/**
* @brief 写指令函数
*
* @param command:写入的指令
* @return
* @note
*/
void LCD_write_command(unsigned char command)
{
        LCDIO = command;                        //指令
        LCD1602_RS = 0;                                //输入指令
        LCD1602_RW = 0;                                //向LCD写入指令
        LCD1602_EN = 1;
        LCD1602_EN = 0;                                //使能信号1->0时(下降沿)执行指令
        Delay(10);                                //延时
}

/**
* @brief 写数据函数
*
* @param dat:写入的数据
* @return 无
* @note
*/
void LCD_write_dat(unsigned char dat)
{
        LCDIO = dat;                                //写入的数据
        LCD1602_RS = 1;                                //输入数据
        LCD1602_RW = 0;                                //向LCD写入数据
        LCD1602_EN = 1;                               
        LCD1602_EN = 0;                                //使能信号1->0时(下降沿)执行指令
Delay(1);                                //延时
                       
}

/**
* @brief 显示位置函数
*
* @param  x:行显示地址(取值范围0-1),y:列显示地址(取值范围0-15)
* @return
* @note   
*/
void LCD_set_xy(unsigned char x,unsigned char y)
{
        unsigned char address;           //定义地址码
        if(y==0)                                   //要显示第一行
        {
                address = 0x00 + x;           //地址码+0x80
        }
        else                                           //要显示第二行
        {
                address = 0x40 + x;           //地址码+0xC0
        }
        LCD_write_command(address|0x80);//写入地址码
}
/**
* @brief 显示一个字符函数
*
* @param  x:行显示地址(取值范围0-1),y:列显示地址(取值范围0-15),dat:显示的字符
* @return
* @note   
*/
//void LCD_dsp_char(unsigned char x,unsigned char y,unsigned char dat)
//{
//        LCD_set_xy(x,y);                   //设置显示位置
//        LCD_write_dat(dat);                   //在设置的位置写入一个字符
//}

/**
* @brief 显示字符串函数
*
* @param  X:行显示地址(取值范围0-1),Y:列显示地址(取值范围0-15),*s:要显示的字符串
* @return
* @note   
*/
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s)
{
        LCD_set_xy(X,Y);                  //设置显示位置
        while(*s)                                  //检测字符串结束标志
        {
                LCD_write_dat(*s);          //写入当前字符
                s++;                                  //指向下一个字符
        }
}

LCD1602.h文件
#ifndef __LCD1602_H__
#define __LCD1602_H__


void LCD_init(void);//初始化函数声明
void LCD_write_command(unsigned char command);   //写入指令函数声明
void LCD_write_dat(unsigned char dat);           //写入数据函数声明
void LCD_set_xy(unsigned char x,unsigned char y);//设置显示位置函数声明
//void LCD_dsp_char(unsigned char x,unsigned char y,unsigned char dat);//显示一个字符函数声明
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s);//显示字符串函数声明

#endif

一周热门 更多>