|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机学习:利用ADC0804模数转换器采集电压, }; x* {( |# F5 Q) N3 K& P/ u
, {7 n7 r, o: }" `% I' r; y$ x& Z. b9 ~ i
电位器调节待检测电压值,在数码管上显示出来,
3 X# J3 k2 J+ [' g: m- z代码大多从书上搬过来的,书上例5.3.1要求前3个数码管显示AD转换后的8位数字量(即0~255)4 m8 W0 b, ?! n9 R
我这里让前4个数码管显示具体电压值,比如1.352) E! ~! ]0 s: K# j- p" s( M6 ^! `3 X7 b' S
/ n* G1 f) q; I! r: G1 s( E. o+ L+ U; H1 k4 k/ O* x
#include <reg52.h> ! t, a; N+ \4 ~3 P- ^
#include "MY51.H"
' n2 R7 Q4 m& m2 f
0 h, y1 l9 S9 }+ R% L void initSMG() //数码管初始化信息 8 P V1 }; v. U8 P! ^. r$ F
{ 5 R- ~0 m6 f! a7 `0 a$ q) H% C
//上电时,都为高电平
* v2 p1 w) a: A9 r) P9 }. i" v P0=0xff;
# _' [; m5 y8 n( [% W+ c a$ M$ F wela=open; ' U8 S* |/ `! {
P0=0xff;
# g3 X4 k" O. k1 j5 t! r2 x4 k wela=lock;
! L9 @; X3 U5 ]" x. Q% A- ^$ q0 Z! t% U, \8 k
P0=0; ! n& F7 X8 x. U
dula=open;
2 v: I, l% l) `# s P0=0;
% w4 y& B; y! }/ \0 |9 ?+ x dula=lock; 5 o; s5 `" n. w; \9 ]. F( t* h
}
0 P6 B. X6 j' h9 O: R
: x9 D2 v0 `! H: h. j void ADC0804_csToLow() //cs置低电平 ! T: K7 A! q+ t$ P; [
{
- H; O0 E$ ?7 u wela=open; //打开锁存器
8 E; b4 p- a) f6 _ P0=0x7f; //锁存器最高位送0,也就是CSAD置0 9 m, u& T0 I! K
wela=lock; ' X( I- Z6 l. h; v2 E, ?% U
}
* M$ `* }8 o* t) [" k) K3 T! U5 F/ ~; B: G: H0 F' H, W
void ADC0804_startConvert() //P3.6口是wr,由高到底,再拉高后,ad开始转换 2 C, V8 e2 X r0 J4 p% v
{ 6 ]- H, r/ o) m* z4 i8 O2 r
adwr=high; //虽然原本就是高的,但我们要养成好习惯,该是什么就是什么
2 V- G. R0 [/ D _nop_(); ! F6 _$ W* N! ]( \+ R; Z+ @5 F& ^$ k: }% S
adwr=low; //wr置低后,过小会后AD内部开始执行转换,转换完成后INTR自动置低触发中断 . ^7 G1 w( o9 p' a& E% a
_nop_(); 0 b8 Q; G, o# i0 D
adwr=high;
- C( r7 H0 H& Y! C //由于我们用的不是150pF电容,而是104pF,所以转换比较慢,在调用本函数后最好延时10毫秒以上 5 f( v" L6 w$ K2 Q8 K! ^( k/ y
} . P1 a& J' {6 v9 X) U/ S) c
) m, A# t) j- @( }# Y* i! J8 d uint8 ADC0804_readResult() //读转换结果
! J: H0 k8 D1 f; ^ {
. e* j( i2 Q3 ~, |: }5 I3 R uint8 result=0;
) M$ O- @6 c1 P5 V' |8 M6 \ //延时一会儿,转换就完成了,由于我们将INTR和CS都拉低了,直接操作RD后就可以读了
7 E/ L' a6 T9 n' B P1=0xff; //防止由于转换未完成原因引起的误读
6 Z5 W- j, d' r! d r+ W adrd=high;
' ^2 k" z1 x1 c _nop_(); 0 y7 {1 E$ w. R( z0 Q9 o1 P: q/ o
adrd=low; //rd置低电平后数据总线P1口得到数据,并由led显示现象 3 G$ w9 Y5 q8 i- }/ g/ b
_nop_();
5 o3 R N% E9 L% ~ O+ _ E% | result=P1;
$ J- \; h6 J% D, V1 K adrd=high; 4 u4 B8 q+ j! {/ O" @- X/ T" N
//读完以后,如果ad芯片不用了,就把cs拉高,注销片选
; A# s6 {0 L3 ]# m; e/ S2 o return result; 6 Z; Q" V" @, B0 Y2 r) f: Q& z
} 6 k6 }# M! M! J9 A ~) m4 n0 ?8 U
( I, y( V7 G7 U
void show(uint8 value) //基准电压是2.5V 为了计算方便扩大到2500
9 @9 E" |- S- P3 r( \* } {
( s( f& }1 P7 [4 d# S uint16 temp=value*(2500/255.0); //扩大到4位整数,小数点另外附加显示 % |6 e/ T) c6 p; T) A! j! G# h3 D$ k
uint8 oneWela,twoWela,threeWela,fourWela; //oneWela是最左边的数码管
' Q8 E# @. P ? oneWela=temp/1000; ( G' A6 {$ Y3 n) T2 @
twoWela=temp%1000/100; * x5 {1 j8 `: }+ d0 Y& {) q7 f
threeWela=temp%100/10; * x6 Q/ k* J, d, [' y
fourWela=temp%10; 6 N$ |8 B. F8 u& S. I' l: U
displaySMG(oneWela,twoWela,threeWela,fourWela,dark,dark,dotTable[1]); //最左边的数码管显示小数点
: B' R& W) _4 G3 u3 M2 W# M# Z2 ~& F } 7 ?7 z6 I7 _. p" Z$ ~; u
0 Q7 o3 L/ ?+ K; _& o* Q8 C
void main() / P& L, x- B6 G3 Z2 A5 f8 g
{ % ?6 I2 r% ?8 O* V6 i9 G
+ m. }8 v9 @& }8 m9 ^' M
uchar i=0;
/ g2 y9 z5 U: ^) J6 A uchar adTemp=0; - l& j8 [; n& @9 z/ s% Q
initSMG(); //数码管数据初始化
# q D. k( j+ m& T, Y! P ADC0804_csToLow(); //cs置低
4 l. A0 V8 G/ p0 n/ U* n while(1)
7 x$ M$ f. r9 m) t6 c1 `5 W {
% Y1 H2 b& C$ d2 N7 P ADC0804_startConvert(); //开始将电压数据转换成数字信号 ) c* t0 m3 u1 L3 p) j" D- |+ |
for(i=5;i>0;i--) //主要是延时一段时间,让ad完成转换
) s" ]; Q$ x7 s9 j {
( i$ O/ R2 @" h3 B4 {$ u8 f delayms(1);
" J# B( ~0 |$ t# ^ show(adTemp); //延时的时候,数码管继续动态显示
$ V8 U$ W# u7 [2 @- q" ?+ w } # U% c5 B" r- r3 C) W
adTemp=ADC0804_readResult(); //读取数据 1 |7 n4 O# l. G) @4 }
show(adTemp);
' ~3 S1 D* @, n } # i% M! m0 C" l; A3 K
} 1 S% H. {% y* g4 n1 w
" m) B: x0 |9 l/ _! U5 h4 A& Y6 t8 h$ C
7 X+ f$ O9 D; y5 A. |
/ `( f5 V3 @( t4 u1 U7 u' M2 L$ y' E* x3 @9 {2 L0 {
$ r+ B/ c( ^* J/ D' O. { |
|