eleven_sue 发表于 2011-4-29 01:29:59

AD0809程序不正确,只有几行,希望高手指点

#include"reg52.h"
#include"intrins.h"

#define uint unsigned int
sbit ST=P3^4;
sbit EOC=P3^2;
sbit OE=P3^3;
sbit ALE=P3^5;


void delay_ms(unsigned int);
void main()
{
P3=0xff;
P1=0xff;
        //初始化
        OE=0;
        ST=0;        //启动转换信号初始为0
        ALE=0;        //地址锁存信号初始为0
        P2=0x00;//地址信号,低三位
        //转换
        while(1)
        {
                ALE=1;//上升沿,锁存地址
                _nop_();
                ST=1;
                ALE=0;
                _nop_();
                ST=0;//下降沿启动转换
                delay_ms(1); //延时等待转换结束
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                while(EOC)//当EOC为低时转换结束
                {
               
                }
                OE=1;       //输出结果
               
                OE=0;
        }
}



void delay_ms(unsigned int t)
{
        unsigned int i;
        unsigned char j;
        for(i=0;i<t;i++)
                for(j=0;j<125;j++);
}
这是小弟编写的程序
http://cache.amobbs.com/bbs_upload782111/files_39/ourdev_635067ULC809.png
(原文件名:QQ截图未命名.png)
这个是小弟画的仿真图,由于0809没法正确仿真就用0808代替了,不知道他们是不是有区别啊?
下面那几个发光二极管是想指示转换结果,
希望哪位大侠可以指点下程序哪里有问题,感激不尽

millwood0 发表于 2011-4-29 02:56:16

"指点下程序哪里有问题"

the code doesn't work because you cannot read and understand the datasheet and code intelligently.

here is what I put together in 5 minutes:

============adc0808.h====================
//hardware configuration
#define ADC_PORT                P2
#define ADC_DDR                        P2
#define ADC_ADD_A                (1<<0)        //address line a
#define ADC_ADD_B                (1<<1)        //address line b
#define ADC_ADD_C                (1<<2)        //address line c
#define ADC_ADD_LE                (1<<3)        //address latch enable: active on the rising edge
#define ADC_START                (1<<5)        //adc start: active on the rising edge
#define ADC_OE                        (1<<4)        //adc output enable:
#define ADC_EOC                        (1<<6)        //adc end of conversion indicator (active high)
//end hardware configuration

#define ADC_CH_IN0                0x00        //adc ch0
#define ADC_CH_IN1                0x01        //adc ch1
#define ADC_CH_IN2                0x02        //adc ch2
#define ADC_CH_IN3                0x03        //adc ch3
#define ADC_CH_IN4                0x04        //adc ch4
#define ADC_CH_IN5                0x05        //adc ch5
#define ADC_CH_IN6                0x06        //adc ch6
#define ADC_CH_IN7                0x07        //adc ch7

#define ADC_OE_ENABLE        0x01        //output enable
#define ADC_OE_DISABLE        0x00        //output disable

//reset the adc
void adc_init(void);

void adc_ch(unsigned char ch);

//star the adc
void adc_start(void);

//enable the output
void adc_oe(unsigned char action);

//read the eoc
#define adc_eoc()                (IO_GET(ADC_PORT, ADC_EOC))                        //return eoc. high = conversion done


============adc0808.c======================
#include <regx51.h>
#include "gpio.h"
#include "adc0808.h"                        //we use adc0808

//reset the adc
void adc_init(void) {
        IO_CLR(ADC_PORT, ADC_ADD_A | ADC_ADD_B | ADC_ADD_C | ADC_ADD_LE | ADC_START | ADC_OE);        //clear output pins
        IO_OUT(ADC_DDR, ADC_ADD_A | ADC_ADD_B | ADC_ADD_C | ADC_ADD_LE | ADC_START | ADC_OE);        //clear output pins

        IO_IN(ADC_DDR, ADC_EOC);
}

void adc_ch(unsigned char ch) {
        //set the add a/b/c pins
        switch (ch) {
                case ADC_CH_IN0: IO_CLR(ADC_PORT, ADC_ADD_C); IO_CLR(ADC_PORT, ADC_ADD_B); IO_CLR(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN1: IO_CLR(ADC_PORT, ADC_ADD_C); IO_CLR(ADC_PORT, ADC_ADD_B); IO_SET(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN2: IO_CLR(ADC_PORT, ADC_ADD_C); IO_SET(ADC_PORT, ADC_ADD_B); IO_CLR(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN3: IO_CLR(ADC_PORT, ADC_ADD_C); IO_SET(ADC_PORT, ADC_ADD_B); IO_SET(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN4: IO_SET(ADC_PORT, ADC_ADD_C); IO_CLR(ADC_PORT, ADC_ADD_B); IO_CLR(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN5: IO_CLR(ADC_PORT, ADC_ADD_C); IO_CLR(ADC_PORT, ADC_ADD_B); IO_SET(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN6: IO_CLR(ADC_PORT, ADC_ADD_C); IO_SET(ADC_PORT, ADC_ADD_B); IO_CLR(ADC_PORT, ADC_ADD_A); break;
                case ADC_CH_IN7: IO_CLR(ADC_PORT, ADC_ADD_C); IO_CLR(ADC_PORT, ADC_ADD_B); IO_SET(ADC_PORT, ADC_ADD_A); break;
        }

        //latch the addr pins: active on the rising edge
        IO_CLR(ADC_PORT, ADC_ADD_LE);
        IO_SET(ADC_PORT, ADC_ADD_LE);
        IO_CLR(ADC_PORT, ADC_ADD_LE);

}

//star the adc
void adc_start(void) {
        //create a rising edge on adc_start
        IO_CLR(ADC_PORT, ADC_START);
        IO_SET(ADC_PORT, ADC_START);
        IO_CLR(ADC_PORT, ADC_START);
}

//enable the output
void adc_oe(unsigned char action) {
        if (action == ADC_OE_ENABLE) IO_SET(ADC_PORT, ADC_OE);        //enable the output
        else IO_CLR(ADC_PORT, ADC_OE);                                                        //otherwise disable the output
}

//read the eoc
//#define adc_eoc()                (IO_GET(ADC_PORT, ADC_EOC))                        //return eoc. high = conversion done


and here is the application code

===============main.c================
#include <regx51.h>
#include "gpio.h"
//#include "delay.h"
#include "adc0808.h"                                                //we use adc0808
       
void mcu_init(void) {
}

int main(void) {
        mcu_init();                                                                //reset the mcu
        adc_init();                                                                //reset the adc
        adc_ch(ADC_CH_IN0);                                                //set input channel to IN0
        adc_start();                                                        //start the adc
        while (adc_eoc()) continue;                                //wait for the adc to end
        adc_oe(ADC_OE_ENABLE);                                        //enable the output

        while (1) {
        }
}

the first lesson in any code is that you have to code them to a logic layer to enhance portability. in this case, you can configure the wiring in adc0808.h to your particular design and then recompile the code to work.

"由于0809没法正确仿真就用0808代替了,不知道他们是不是有区别啊? "

read the @#%!@#$@ datasheet as that is the ONLY way to code any device.

millwood0 发表于 2011-4-29 06:44:59

a correction:

"while (adc_eoc()) continue; //wait for the adc to end "

should have been:

"while (!adc_eoc()) continue; //wait for the adc to end "

here is a piece of code that continues to adc IN0's input (in this case, a 1v+1v*sin(1hz)).

========main.c===============
#include <regx51.h>
#include "gpio.h"
//#include "delay.h"
#include "adc0808.h"                                                //we use adc0808
       
void mcu_init(void) {
}

int main(void) {
        mcu_init();                                                                //reset the mcu
        adc_init();                                                                //reset the adc
        adc_ch(ADC_CH_IN0);                                                //set input channel
        adc_start();                                                        //start the adc
        adc_oe(ADC_OE_DISABLE);                                        //disable the output
        while (!adc_eoc()) continue;                        //wait for the adc to end
        adc_oe(ADC_OE_ENABLE);                                        //enable the output
       
        adc_ch(ADC_CH_IN0);                                                //select in0
        adc_oe(ADC_OE_ENABLE);                                        //output enabled
        while (1) {
                IO_FLP(ADC_PORT, (1<<7));
                adc_start();                                                //start the adc
                while (!adc_eoc()) continue;                //wait for the adc to end
        }
}


http://cache.amobbs.com/bbs_upload782111/files_39/ourdev_635088IAZAWV.PNG
(原文件名:43. adc0808 on sin wave.PNG)

notice that the chip's output is reverse: lsb on output8 and msb on output1.
页: [1]
查看完整版本: AD0809程序不正确,只有几行,希望高手指点