|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机学习:利用ADC0804模数转换器采集电压 O8 F0 l M0 m+ Q8 e
5 [) l9 K0 C3 G! c m7 ^0 x( ~4 l+ d
电位器调节待检测电压值,在数码管上显示出来,$ D, _ _ U* X- m. y0 v
代码大多从书上搬过来的,书上例5.3.1要求前3个数码管显示AD转换后的8位数字量(即0~255)# J8 T5 B* v+ u+ j% U/ L* W& G' C9 p
我这里让前4个数码管显示具体电压值,比如1.3521 V: I$ F8 `6 n4 m2 S: T
% @! ^$ s, `8 h z' _( d4 @% R4 D" U7 ^/ }% G
#include <reg52.h> 0 G$ U& z( j$ W3 }6 Z7 ^1 ^9 ^
#include "MY51.H"
/ U6 {/ `6 X- c
: v( h* a( k3 F5 l4 H: p void initSMG() //数码管初始化信息 : B/ Y: r2 |# ^. j- |
{ ' t. d3 q0 n: d6 f9 u# Y! M
//上电时,都为高电平
7 K% n0 c$ E5 k H# S7 L P0=0xff;
$ {) R0 F5 K9 b/ N- e wela=open; ( [8 D5 g8 Q: ?0 j i$ R( `
P0=0xff;
% n$ ^% b% {. M0 I( S; P wela=lock; 4 s( v9 j, v$ M8 Q- I. K: `
* A; w/ S% n: d2 U
P0=0; 4 h; A' P, r$ O0 ]* Y, w7 @5 i9 E
dula=open; / e' R" G; E& ]! `& s( h/ L" F2 R
P0=0;
8 _; ^" R+ x" c& `% ?# n7 Y dula=lock; ; j5 ^3 C6 W% O0 ~
}
8 }" M7 U& u$ @* e7 H Q4 L5 k
3 \8 j' e7 e" P% ^ void ADC0804_csToLow() //cs置低电平
& t7 W2 r1 o6 }; Q0 p7 T { 0 g, L' B5 ~# u+ ~: C" F
wela=open; //打开锁存器
: {7 n1 ?$ _' g- E8 ` P0=0x7f; //锁存器最高位送0,也就是CSAD置0 ' m/ s. L; J v3 o' z
wela=lock;
6 \0 x \( h2 J* h+ x# H* g }
, T" E/ n! t$ E1 Y. G, k/ V# f. v' X0 N5 I x
void ADC0804_startConvert() //P3.6口是wr,由高到底,再拉高后,ad开始转换 , }2 ^/ a& m& W/ w
{ ! _4 v4 B0 w( a. z
adwr=high; //虽然原本就是高的,但我们要养成好习惯,该是什么就是什么
3 g6 P( C, J5 ? _nop_();
7 l: Z/ Z/ Z7 B1 a4 x$ n' ? adwr=low; //wr置低后,过小会后AD内部开始执行转换,转换完成后INTR自动置低触发中断 2 U W# F1 K. y6 A
_nop_();
; J& y# K1 h7 F5 l" I/ A adwr=high;
7 h2 n* [( S4 y //由于我们用的不是150pF电容,而是104pF,所以转换比较慢,在调用本函数后最好延时10毫秒以上
$ O1 W1 l9 b2 P }
& f( t8 [' _7 |+ _5 q* \3 W: c
9 X: ~; D6 _3 C2 T* l( b uint8 ADC0804_readResult() //读转换结果 $ J1 H- L) z* q' r/ @
{ " X; b1 C, ?& N5 g K1 w
uint8 result=0; # N, U% f- C" |) t2 r
//延时一会儿,转换就完成了,由于我们将INTR和CS都拉低了,直接操作RD后就可以读了 - R3 `% Z/ V R( g Z
P1=0xff; //防止由于转换未完成原因引起的误读
7 |$ v* V4 m7 K' `. Z( P adrd=high;
; t8 B' _( N. m- K7 e" ^* Q0 n _nop_();
+ U3 q1 w' S8 [ adrd=low; //rd置低电平后数据总线P1口得到数据,并由led显示现象 5 V: c) j7 I$ Z/ _$ w! h
_nop_();
3 ^: w! ]; q* z y7 `# O8 X result=P1;
* E0 x: ]2 _# K5 E5 Z5 P& t adrd=high; 6 i8 X$ b( L/ V/ P+ G* M
//读完以后,如果ad芯片不用了,就把cs拉高,注销片选
M& F8 l- p* a N( B return result;
% }2 P0 R6 E; N) A* S }
) W$ E+ r, q" F! e. W5 Z6 ^4 R( B* X6 N$ z. p1 S
void show(uint8 value) //基准电压是2.5V 为了计算方便扩大到2500 6 t& S5 P X/ O; v1 r. _
{ + A, q4 H. ?8 z5 L5 w
uint16 temp=value*(2500/255.0); //扩大到4位整数,小数点另外附加显示 & ]4 _( a7 c& \* B0 N# B$ W0 I7 p
uint8 oneWela,twoWela,threeWela,fourWela; //oneWela是最左边的数码管 4 N) w0 R1 N9 R& R+ T
oneWela=temp/1000;
' v7 v: Z2 f6 I" {3 B+ @1 u' f twoWela=temp%1000/100; 1 k. `8 f! S8 G: G2 I* [
threeWela=temp%100/10;
5 |: D) E! `) X fourWela=temp%10; ; {, e( z" |5 }/ T/ s! ?" d
displaySMG(oneWela,twoWela,threeWela,fourWela,dark,dark,dotTable[1]); //最左边的数码管显示小数点
! h2 h( T: z+ ` }
: [) C0 J3 g Z6 h; c# f* D( q$ f+ w2 J7 J4 A1 a0 m
void main() / T# G% [& k5 D" B* {4 t
{
9 @1 ?4 J7 l2 ?4 S0 a
& L: z1 S& c7 \6 ?: A uchar i=0;
" m6 v5 ~- X. Q9 n' I uchar adTemp=0;
8 s9 W, P* g' v# P x initSMG(); //数码管数据初始化
% S' r* ` N& ^: n2 y" M7 \3 m" m ADC0804_csToLow(); //cs置低
, C) k5 h% A5 M$ \% }# d* u. T while(1)
' R9 H; w7 H6 K( i& E! X( r { 4 W3 |6 a2 d( P$ b3 J8 N
ADC0804_startConvert(); //开始将电压数据转换成数字信号 ' E$ S; B; H2 L% R/ Y- w& s
for(i=5;i>0;i--) //主要是延时一段时间,让ad完成转换
* P$ k! J: Z5 b8 e4 R; {) s& B. s# I { : S% g# e0 I, `5 V
delayms(1); ! i: Z: V) E/ Q9 x, `$ `
show(adTemp); //延时的时候,数码管继续动态显示
9 n7 k) {( u5 z Z* n }
3 d* }2 P( W9 T adTemp=ADC0804_readResult(); //读取数据 4 o& o, t4 H+ F2 o0 V2 k) z' b7 ]
show(adTemp);
: T2 M5 j$ H+ B- q3 U }
( G9 a% k) D; T } : Q) q5 }2 B6 K7 H. U2 j) N
3 \) z# h* w9 o3 U/ H+ U; N
/ |8 h& w9 k8 ?* F, u
# R, m7 U# F1 K' i$ X+ K$ T
9 ~, n6 _% I g4 v0 b, m& b) X3 [% ^
7 b& T+ }( H: f4 ] J6 J |
|