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代替了,不知道他们是不是有区别啊?
下面那几个发光二极管是想指示转换结果,
希望哪位大侠可以指点下程序哪里有问题,感激不尽 "指点下程序哪里有问题"
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. 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]