制作的模数转换,在硬件和仿真都有一些问题,请求帮助

2019-07-15 18:17发布

本帖最后由 新时代工程师 于 2014-10-18 23:30 编辑

在这里先感谢各位的回答。

目的:key1控制ADC0809的通道选择,每次加一,key2负责把转换后的数值相加。

故障描述:(1)在proteus仿真时,第一次按下key1会多出一个莫名的数值,之后正常但通道号错误。
                  (2)在硬件实验时,第一次按下key1一直显示在"LO"字符。("LO"字符是用于当AD0809还没                         有转换完成时显示。)
                  (3)我初步怀疑是多出来那个值得原因。

代码:
#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

uchar code lednum[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x76,0x79,0x38,0x40}; //0~9,'h','e','l','-'
uchar ADC_data = 0;
uint temp = 0;
uchar wei5, wei4, wei3, wei2, wei1;
uchar channel = 0;        //用于标记模数转换的通道值(在这里是IN0和IN1轮换)
uchar a[2] = {0, 0};      //用于存储已转换的数字数据值
uchar ge, shi, bai, qian, wei, t;  //用于显示

sbit le = P2^0;          //锁存器锁存控制端,用于数码管位选
sbit clk = P2^1;         //ADC0809的时钟信号输入端
sbit adda = P3^4;        //ADC0809的地址输入端
sbit addb = P3^5;
sbit addc = P3^6;
sbit start_ad = P2^5;    //ADC0809启动信号,高脉冲启动
sbit OE = P2^7;          //ADC0809读数据控制端
sbit key1 = P3^0;        //用于切换转换的通道,每次加一
sbit key2 = P3^1;        //用于把转换后的值相加
sbit I = P2^2;           //74hc138控制数码管的位码
sbit J = P2^3;
sbit K = P2^4;
sbit EOC = P3^7;

void ADC_TRANC(uchar channel);

void delay_ms(uint ms)
{
    uint i;
    ms = ms * 120;
    for(i=0;i<ms;i++)
    {
        ;
    }
}

void delay(uint x)     //微秒级延时子程序
{
  uint i,j;
  for(i=x;i>0;i--)
      for(j=110;j>0;j--);
}

void inital_myself(void)     //初始化单片机
{
    le = 1;              //确保其他芯片不会误动作
    P0 = 1;
    start_ad = 0;
    OE = 0;
    key1 = 1;
    key2 = 1;
    EOC = 0;
}

void T1_Inital(void)
{
   TMOD=0x01;
   TH1=(65536-200)/256;//求T1高八位数
   TL1=(65536-200)%256;//求T1高八位数
   EA=1;    // 开中断
   ET1=1;    // 允许T1中断
   TR1=1;    // 启动T1
}

void display_hello()      //显示‘Hello’作为开始
{
    uchar i;
    for(i=0;i<3;i++)
    {
        le = 1;         //'H'
        K = 1;
        J = 0;
        I = 0;
        P0 = lednum[10];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 1;
        I = 1;
        P0 = lednum[11];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 1;
        I = 0;
        P0 = lednum[12];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 0;
        I = 1;
        P0 = lednum[12];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 0;
        I = 0;
        P0 = lednum[0];
        le = 0;
        delay_ms(5);
        }
}

void display_lo(void)   //当AD芯片还没有转换完成是,数码管显示‘LO’
{
        le = 1;
        K = 0;
        J = 0;
        I = 1;
        P0 = lednum[12];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 0;
        I = 0;
        P0 = lednum[0];
        le = 0;
        delay_ms(5);
}

void display()
{
    uchar j;
    for(j=0;j<25;j++)
    {
        le = 1;          //显示ADC转换后的数据需要6位 格式为“通道号 — 数值”
        K = 1;
        J = 0;
        I = 1;
        P0 = lednum[wei];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 1;
        J = 0;
        I = 0;
        P0 = lednum[13];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 1;
        I = 1;
        P0 = lednum[qian];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 1;
        I = 0;
        P0 = lednum[bai];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 0;
        I = 1;
        P0 = lednum[shi];
        le = 0;
        delay_ms(5);

        le = 1;
        K = 0;
        J = 0;
        I = 0;
        P0 = lednum[ge];
        le = 0;
        delay_ms(5);

    }

}

void key_scan()         //键盘扫描程序
{
    if(key1 == 0)
    {
        delay(5);
        if(key1 == 0)         //消抖
        {
            while(key1 == 0)  //等待按键松开
            {
                ;
            }
            if(channel == 2)   //这本实验中要求只转换IN0和IN1的模拟值,并循环转换次序
            {
                channel = 0;
            }
            ADC_TRANC(channel);
            channel++;
            t = 1;
        }
    }

    else if(key2 == 0)
    {
        delay(5);
        if(key2 == 0)
        {
            while(key2 == 0)
            {
                ;
            }
            temp = a[0] + a[1];
            ge=temp%10; //个位
            shi=temp/10%10;//十位
            bai=temp/100%10;//百位
            qian=temp/1000;//千位
            wei=channel;
         }
        t = 1;
    }
    else
        t = 0;
}

void ADC_TRANC(uchar channel)
{
    OE=0;
    start_ad=0;
    start_ad=1;
    start_ad=0;     //START从1->0下降沿开始转换数据
    adda=0x01&channel;
    addb=0x01&(channel>>1);
    addc=0x01&(channel>>2);      //选择通道输入模拟量
    do{display_lo();}while(!EOC); //当ADC0808转换数据时,EOC=0;转换结束时,EOC=1;在还没有转换完毕时,输出“LO”
    OE=1;     //允许A/D数据输出,单片机读取数据
    ADC_data=P1; //将输出数据P0端采集,将采集数据放到ADC_data中
    OE=0; //关闭A/D数据输出
    temp=ADC_data*1.00/255*500;   //转化为十进制数字量
    a[channel] = temp;
    ge=temp%10; //个位
    shi=temp/10%10;//十位
    bai=temp/100%10;//百位
    qian=temp/1000;//千位
    wei=channel;
}

int main(void)
{
    inital_myself();
delay_ms(5);
T1_Inital();    //定时器初始化
    while(1)
    {
        key_scan();
        if(t == 1)
            display();
        else
            display_hello();    //没有按键按下则显示“HELLO”
    }

    return 0;
}

void T1_interrupt(void)interrupt 3 using 0           //ADC芯片的时钟来源
{
   TH1=(65536-200)/256;    //转换时间为200us(时钟频率为640Hz)
   TL1=(65536-200)%256;
   clk=~clk;  //产生同步时钟信号
}

电路图 电路图
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。