今天做了一个AD的实验,在此记下一点经验。
采用芯片:ADC0832,89S52
电路图如图:
今天第一次看ADC0832的数据手册,一头雾水啊,找了篇中文资料写的不错
其实在英文手册里的时序图写的也很明白了,可惜E文太差看的不懂。
这里无论是要用CH1,还是CH0都得把ADC0832的DI,DO搞好。DI决定了芯片工作的开始与CH0,CH1的选择,DO是输出数据的端口。DO,DI这两个端口其实不会同时工作,用一个IO口控制就够了,杜洋老师采用了如下电路,节省了一个IO口。如图:
在上面电路重要的是如何启动ADC0832和如何从ADC9832中读取数据,并在数码管上显示出来。
代码如下,是用keil uVesion编译过的,达到了想要的效果:
Code
在ReadADC()中,对于ADC0832的启动一段代码具有通用性,可以按照得到的channel值启动CH0或者Ch1.这样我可以把键盘扩展进来用键盘来输入得到一个channel,来控制开启哪个CH。
顺便今天熟悉了一下c语言中的位操作:
在上面ReadADC()中tmp=channel&0x01;就用到与运算把最后一位提出来。
在reg51.h中P0,P1,P2,P3都被定义成sfr型,sfr是用于定义特殊功能寄存器的地址,sbit是用于定义一些特殊位的。因此程序里的CLK,DI,DO都是P1的某些个别端口,其实质是一个位而已,因此DI=tmp;这一句其实是把一个char赋给一个位,只要tmp不为0,那么DI就一直为1.因此必须把channel里的每一位取出来然后和DI进行赋值,才能得到我们想要的对channel的低三位每一位依次赋给DI的效果。
这个程序用到了intrins.h这个头文件,此头文件定义了Keil C中的内函数,在ReadADC()中,用了一个_nop_()这个空操作。
/*--------------------------------------------------------------------------
INTRINS.H
Intrinsic functions for C51.
Copyright (c) 1988-2004 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/
#ifndef __INTRINS_H__
#define __INTRINS_H__
extern void _nop_ (void);
extern bit _testbit_ (bit);
extern unsigned char _cror_ (unsigned char, unsigned char);
extern unsigned int _iror_ (unsigned int, unsigned char);
extern unsigned long _lror_ (unsigned long, unsigned char);
extern unsigned char _crol_ (unsigned char, unsigned char);
extern unsigned int _irol_ (unsigned int, unsigned char);
extern unsigned long _lrol_ (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
extern void _push_ (unsigned char _sfr);
extern void _pop_ (unsigned char _sfr);
#endif