微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > AD转换及显示

AD转换及显示

时间:10-02 整理:3721RD 点击:
新人求大神指导啊!AD转换不准确怎么回事呀,输入3.3V显示1.4V,数码管用的是四位共阳数码管AD用ADC0809,单片机用的是STC12C5A60S2,谢谢大家!

##include"reg51.h"

#define uchar unsigned char

#define uint unsigned int


#define LED_DIGPORT P0;                   //数码管位选接上拉电阻

#define AD_DATAPORT P1;                              //A/D数据口

#define LED_WORDPORT P2;                         //数码管段码


sbit  AD_EOC=P3^3;                      //A/D转换结束信号输出端

sbit  AD_CLK=P3^4;                          //A/D时钟信号输入端

sbit  AD_START=P3^6;                  //启动A/D转换控制信号输入端

sbit  AD_OE=P3^7;                          //A/D输出允许控制端

sbit  WARM=P3^1;                                  //控制蜂鸣器输出端

sbit  LED=P3^0;                      //基准电压采集结束显示灯

uchar code Seg_Code[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

                                                         //共阳极段码

uchar code SegNode_Code[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

//有小数点段码

uchar a[4],dig=0x01;

uchar flag;

uchar i,max,min,count;

long int sum=0,sum1,sum2;

uchar tab[6];

void Delay(uchar t1,uchar t2)

//延时子程序,t1,t2是无符号的字符型全局变量

{        for(;t1>0;t1--)

for(;t2>0;t2--);

}

void Led_Display()                               //数码管显示子程序

{ uchar i;

for(i=0;i<4;i++)                                 //4个数码管

{ LED_WORDPORT=0xff;                                  //显示清屏

LED_DIGPORT=dig<<i;                                      //位码

LED_WORDPORT=a;                                      //段码

Delay(1,200);                                          //延时

}

}

void time0() interrupt 1

{

    AD_CLK=~AD_CLK;                                  //A/D时钟信号

}


void AD_init()

{

    for(count=0;count<6;count++)              //采集六次转换后的数字量

{

    while(!AD_EOC);

//若AD_EOC为低电平,即转换期间,等待,直到转换结束

AD_START=1;              //给START一个高电平,上升沿复位内部寄存器

AD_OE=1;                                      //数据输出有效,允许输出

    tab[count]=AD_DATAPORT;                    //转换后的数字量放tab里

Delay(1,10);                                //延时,给START一个正脉冲

AD_OE=0;                                    //数据输出无效,不允许输出

AD_START=0;                 //给START一个低电平,启动ADC0809工作

Delay(1,10);          //延时一段时间,使得AD转换次数少些,等待AD转换

}               

    for(i=0;i<6;i++)     //将tab内数字量最大的存MAX里,最小的存MIN内

{

max=tab[0];

min=tab[0];

if(max<tab)

{max=tab;}

if(min>tab)

{min=tab;}

    }

sum1=(tab[0]+tab[1]+tab[2]+tab[3]+tab[4]+tab[5]-max-min)/4;

//TAB内数字量去掉最大和最小的总和放sum1中

sum1=(sum1*50000)/255;

//将总和*10000转换为整数,再转换为跟模拟量对应的数值,以便显示程序调用sum1

count=0;                                                       //清零

LED=0;                                     //基准电压采集结束显示灯亮

}


void AD_chuli()                                         //A/D信号处理

{

AD_START=1;                        //又上升沿复位内部寄存器

AD_OE=1;         //OE为高电平时,允许输出,转换结果出现D7~D0

if(count<6)                          //采集不满6次,不处理,只count++

{

tab[count]=AD_DATAPORT;

count++;

flag=0;

sum=0;

}

if(count==6)                                           //采集到6次时

{

LED=0;                                   //基准电压采集结束显示灯亮

max=tab[0];

min=tab[0];

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

{

if(max<tab)      //将tab内数字量最大的存MAX里,最小的存MIN内

{max=tab;}

if(min>tab)

{min=tab;}

      }

sum=(tab[0]+tab[1]+tab[2]+tab[3]+tab[4]+tab[5]-max-min)/4;

//TAB内数字量去掉最大和最小的总和放sum中

sum=(sum*50000)/255;

//将总和*10000转换为整数,再转换为跟模拟量对应的数值,以便显示程序调用sum

sum2=sum;

a[0]=Seg_Code[sum/10%10];                             //千分位

a[1]=Seg_Code[sum/100%10];                             //百分位

a[2]=Seg_Code[sum/1000%10];                               //十分位

a[3]=SegNode_Code[sum/10000];                               //个位

count=0;

flag=1;

}

Delay(1,10);

AD_OE=0;       //OE为低电平时,不允许输出,D7~D0对外成高阻态

AD_START=0;                          //下降沿又开始启动A转换D

Delay(1,10);       //延时一段时间,使得AD转换次数少些,等待AD转换       

}


void main(void)                                               //主程序

{

Delay(1,30);

    TMOD=0x02; TH0=200; TL0=200;

//定时器工作在方式2,自动重装初值的八位计数器,须定时200us左右

TR0=1; ET0=1; PT0=1;

//TR0启动T0计数,ET0开T0中断,PT0高优先级T0中断  

EA=1;                                                    //开所有中断

WARM=0;                                                //蜂鸣器不工作

AD_START=0;

AD_START=1;                                 //上升沿复位内部寄存器

AD_START=0;                                       //下降沿开始A/D

if(AD_EOC);                              //AD_EOC为高电平,即转换结束

AD_init();                                               //存储数字量

while(1)

{

Led_Display();                                    //数码管显示

if(AD_EOC)

AD_chuli();                                          //查询

    if(sum2-sum1>10000||sum1-sum2>10000)

//10000代表灵敏度暂设为1V上下

WARM=1;

else

WARM=0;

}



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top