|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机学习:利用ADC0804模数转换器采集电压
* z2 H3 v9 i% i; _" _7 X- E/ h% c* G
6 T0 @9 M9 J3 g1 \; I1 C
电位器调节待检测电压值,在数码管上显示出来,
6 m; _. N; y2 b* D7 h- Q代码大多从书上搬过来的,书上例5.3.1要求前3个数码管显示AD转换后的8位数字量(即0~255)
% v3 \$ e0 O3 f- ]我这里让前4个数码管显示具体电压值,比如1.352
0 H+ s5 [4 c2 r8 p0 ]! ^" \0 [" X% m6 x' V9 w; r0 I2 C* L: o
5 J5 x2 r$ g* u. S ^8 T" m #include <reg52.h> 9 T3 Z$ p: `2 i# S4 w4 T% O
#include "MY51.H"
# S5 J' a; ~& L" L7 \" [+ N! e3 S% Z4 {, b
void initSMG() //数码管初始化信息
& Y# l P4 }5 i& k9 J* C9 _ { - g9 v- q1 K& }( f
//上电时,都为高电平
2 b3 m- Z( A( o/ K) @9 Z6 \ P0=0xff; |) m0 r& v5 l4 K
wela=open; : S! d3 k2 b! }6 E Q
P0=0xff;
+ s( `. L9 e& \" y' u7 M X wela=lock;
# u6 F7 S3 |: a/ u; j/ h* B5 C. ^* F Q. N" n4 e/ U6 k
P0=0;
2 G, _! s- K! }; o0 m% H% q6 {4 S dula=open;
, R3 j9 _8 A U# L3 |+ K7 K( N+ i% M P0=0; * R' t& b# U2 X7 Z- B- D& C3 ^
dula=lock;
R0 I/ a U, g% l! n! w } ' t7 |3 |/ ]* \& w/ z$ u. S/ j
/ l' ?+ g; k( p! W# U0 a void ADC0804_csToLow() //cs置低电平 7 b) { B0 D! |7 y9 e8 d7 T
{
1 s* N: S4 f* }2 I& |4 U; u* t wela=open; //打开锁存器 ; v- D) D* C _; l$ |% C
P0=0x7f; //锁存器最高位送0,也就是CSAD置0 9 u" r8 z- E+ m/ j
wela=lock;
# s& I0 u+ u! z8 Z }
4 _" v9 A V# i3 h2 v3 U/ y" A6 E. T/ t( G
void ADC0804_startConvert() //P3.6口是wr,由高到底,再拉高后,ad开始转换
# M! j$ B2 k: Z% [% E { % a3 I- s* n$ G( x: i
adwr=high; //虽然原本就是高的,但我们要养成好习惯,该是什么就是什么 - B9 h0 Z2 o5 ]" T- f& a! V' w0 a
_nop_(); ; z6 f/ K J; g; [* n& |1 T3 u
adwr=low; //wr置低后,过小会后AD内部开始执行转换,转换完成后INTR自动置低触发中断
& F2 O( {' u0 G8 f _nop_(); , }5 r1 ?" i5 P
adwr=high;
! s7 g: w& y3 S //由于我们用的不是150pF电容,而是104pF,所以转换比较慢,在调用本函数后最好延时10毫秒以上
9 @' A' C( i" q1 V } 1 O! D' h' u+ F+ v1 v
/ F& a! T5 J9 a; N2 d
uint8 ADC0804_readResult() //读转换结果 7 [+ L$ z) L% h
{ " t) U1 ^4 O' ^; }: q
uint8 result=0; # @7 g) j, M4 F* V+ @0 Y# C& J
//延时一会儿,转换就完成了,由于我们将INTR和CS都拉低了,直接操作RD后就可以读了
' I) Z" _, r" ?. a. R P1=0xff; //防止由于转换未完成原因引起的误读 8 [; Y. x' E$ ~+ L g
adrd=high; ' R0 R/ K/ l0 J u: J$ n8 I$ A, [$ f8 {
_nop_(); * Z) \) d8 X! z0 l( l/ }+ \
adrd=low; //rd置低电平后数据总线P1口得到数据,并由led显示现象
0 g$ v* y8 G4 M# S" Y" x& L: T _nop_();
/ y. ^2 c3 E8 t v" Q- D result=P1;
3 F' s3 G( [! V, n' G* m adrd=high;
# C6 X8 T/ ]* K; a1 A) |/ L" {4 Q //读完以后,如果ad芯片不用了,就把cs拉高,注销片选
' I* F% y0 P. |) J" X9 V# @! ^ C return result; 1 `2 s# D) h; G) c c
}
' e3 i5 V# e- ^ U& {! h3 d6 i, Y/ z, n+ W9 z
void show(uint8 value) //基准电压是2.5V 为了计算方便扩大到2500
; e* R. P6 N4 W0 ]( T' w" E {
3 m ^, c& |+ s uint16 temp=value*(2500/255.0); //扩大到4位整数,小数点另外附加显示
. N6 r6 e" s- ]& { uint8 oneWela,twoWela,threeWela,fourWela; //oneWela是最左边的数码管 0 b9 G, x5 p# H- W, R7 E% v1 Q
oneWela=temp/1000;
! \; f, ^) y0 c/ x' ? twoWela=temp%1000/100;
. m g& n( g( E( \0 @ threeWela=temp%100/10; : V6 R; ^+ ~/ ^
fourWela=temp%10;
; I1 x; B& W) T x displaySMG(oneWela,twoWela,threeWela,fourWela,dark,dark,dotTable[1]); //最左边的数码管显示小数点 8 @' ^8 G: i P0 e: O) z4 C: E
}
+ ~- z: S. y/ j& ]# d
! G+ u. ]3 n4 E0 M: y! c2 z void main() y* u. @% W8 R
{ - ^ ~' d& o4 U: ?8 m4 g7 u
* Y8 `/ ~, v" l: ^" Y# O0 E% X0 N uchar i=0;
- b6 F; u( ^) L( h uchar adTemp=0; / D) f% y3 _' ] s. ?" K! @& {- M
initSMG(); //数码管数据初始化 / E3 ]2 Q; q4 v) h5 Y; e
ADC0804_csToLow(); //cs置低 {+ ?7 M' K+ |" x9 i2 p
while(1) 7 ?; G$ e" v0 T6 y7 W0 x8 R& i) q. j `
{
3 S" k) O5 X; Y8 o( `' u ADC0804_startConvert(); //开始将电压数据转换成数字信号 2 r& u7 n6 C* y; R' i* Q" t) ?
for(i=5;i>0;i--) //主要是延时一段时间,让ad完成转换 9 }+ c* I% S' n, m2 Y K* P
{ 7 s% c I4 }* Y: y6 G" N: G
delayms(1);
: D* k R r# G+ j+ R) G2 [0 h show(adTemp); //延时的时候,数码管继续动态显示
/ {) z, k" F/ n4 m2 e9 G. I8 | }
# \8 `) j9 N% J- }* q adTemp=ADC0804_readResult(); //读取数据 3 f! f7 w) ?! |0 E
show(adTemp);
( b; g/ u8 k3 `- X } ( b- N3 c& E9 Z0 u/ U( ?6 }; U1 D7 g
} / G" J: T7 J5 A& ]/ W: C& ]
# ] z; c2 U- Y5 ]! J5 D( T/ `" M; t8 c" E) H
' W: a* d) h9 W4 j2 W! {: d
. d5 e$ c' J5 D w
5 p7 J3 f3 W9 w9 K! E& t& J$ M
+ |4 @/ p7 ]; x d: n h2 Q |
|