|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机学习:利用ADC0804模数转换器采集电压& g1 ?4 c8 b9 d/ b7 c
' c/ n4 \" N/ T& p5 C0 A8 ~
2 i4 J5 x6 T$ {9 L4 a; C/ k+ l电位器调节待检测电压值,在数码管上显示出来,
& I- \$ g5 A. b+ H u代码大多从书上搬过来的,书上例5.3.1要求前3个数码管显示AD转换后的8位数字量(即0~255)4 `; h( i5 i+ d8 ]' I5 t
我这里让前4个数码管显示具体电压值,比如1.352: z6 t3 G3 V, O) A Q2 d
/ F# u8 Q2 \1 P9 f' @ K
7 |9 h: x# ~0 Q9 ? }7 b' m/ a) ]
#include <reg52.h> + a+ [- Z* ], ~) o3 g
#include "MY51.H" 5 |* d6 h: `5 B; s
" y: W O, @. q7 }2 X
void initSMG() //数码管初始化信息 # l- p0 F/ C4 Z( C, g$ ]
{ 9 ~/ ]; Z1 D( F; Q& q5 z$ L- ?+ K: \) l
//上电时,都为高电平
" k! ~7 L1 n7 [- A* s8 L8 U$ S P0=0xff;
6 ]! t0 D( z" U5 k6 u wela=open; " S; `- J; g3 }' a) K
P0=0xff; 1 L- N# q7 p" r1 i) ~4 A; c2 F, E1 J: @
wela=lock; * x4 O' n8 g& [, v. u, G9 @2 d$ c& H
+ D% ^: J; \# \* S0 ?) u
P0=0;
! w: }1 M9 j) @* J7 Q dula=open; 7 m1 c2 Z# s5 Q- v0 T( ?# L' U
P0=0;
# J9 h( U! q' Y& p dula=lock;
: G; j$ N. _* Y4 p" P } 9 b7 S9 G( O1 e( S3 Y
; C2 `8 W' l: C. G/ E6 y6 T8 Z8 p+ m
void ADC0804_csToLow() //cs置低电平
2 n! [6 y9 T* N$ }, n1 h5 K& h {
4 e% N: `" e- W, y* U wela=open; //打开锁存器 % s$ Z& T+ f) n0 n
P0=0x7f; //锁存器最高位送0,也就是CSAD置0
3 S* d7 q% ?9 ]* Q. c0 Q! ^4 Q wela=lock;
0 @7 t3 @% I2 E, Z } 0 {& i* [7 T) Y
9 x( o$ v0 K$ H! a9 w! ` void ADC0804_startConvert() //P3.6口是wr,由高到底,再拉高后,ad开始转换 ! f4 R8 r) E9 _/ _8 j/ X, f
{
. b' j, b; i: @ adwr=high; //虽然原本就是高的,但我们要养成好习惯,该是什么就是什么
0 t& v D9 I6 `0 Q5 L, P* S _nop_();
' ~9 ?4 r6 }, n% \# L0 E adwr=low; //wr置低后,过小会后AD内部开始执行转换,转换完成后INTR自动置低触发中断
3 c2 l" l3 W" b( { _nop_(); % s6 C. N; e! G0 b8 O8 p2 V
adwr=high;
3 M& ^. p0 j2 V* U' {0 W //由于我们用的不是150pF电容,而是104pF,所以转换比较慢,在调用本函数后最好延时10毫秒以上 - b! x/ F( U. @' w) x8 C: [
} 7 s* o" w9 u ] Q7 T, y8 d0 l
# D7 U' t1 D8 R# o3 \ uint8 ADC0804_readResult() //读转换结果 * L+ |# c2 L J4 P+ v8 Q& Z7 w
{ " s" i4 y1 U& V; M& G
uint8 result=0; : m+ e' G6 O9 {; @9 f# l* m
//延时一会儿,转换就完成了,由于我们将INTR和CS都拉低了,直接操作RD后就可以读了 : ^' y2 }0 D, G9 h3 B7 \
P1=0xff; //防止由于转换未完成原因引起的误读 - x3 J/ R" o' \: L% D1 U
adrd=high;
7 h$ P1 R+ d X8 K/ \* _8 S _nop_();
7 Z* ~3 o' `' d5 u8 @& ]- ` adrd=low; //rd置低电平后数据总线P1口得到数据,并由led显示现象 % H, V5 @7 h! \4 k
_nop_(); ' @- k. X) a# e! {# s
result=P1; 6 Z4 U4 k4 Q0 `3 {4 G
adrd=high; 7 K! r; J3 P4 D; I3 @8 X: B
//读完以后,如果ad芯片不用了,就把cs拉高,注销片选
/ |6 [' l+ h P( x* g return result; ( u" o9 x' N$ T
}
+ n x$ `' U( o) L# J2 }1 c: C) U4 r7 L5 N0 f
void show(uint8 value) //基准电压是2.5V 为了计算方便扩大到2500
# f( d8 x: x& M7 H& Z, c8 Z8 H! Y0 \ { ; C% m$ I k4 F+ U
uint16 temp=value*(2500/255.0); //扩大到4位整数,小数点另外附加显示 ' w: E5 T& D) o! Y4 r; ]6 @$ v
uint8 oneWela,twoWela,threeWela,fourWela; //oneWela是最左边的数码管
8 D* ~# I( I% v0 \8 }8 R oneWela=temp/1000;
6 G6 B$ e) k; [! R) ?' f4 C twoWela=temp%1000/100;
0 G. P7 P+ M- t threeWela=temp%100/10; % D8 Y. L S1 B2 k! f6 z/ p
fourWela=temp%10;
0 I1 d1 Z3 T; @* a- { displaySMG(oneWela,twoWela,threeWela,fourWela,dark,dark,dotTable[1]); //最左边的数码管显示小数点 & C. k( V6 z' _4 o" ]# X& g
}
# Z n: V* R: i4 h4 |+ t7 A- v0 d
/ ^. x' I7 x( r+ K5 l/ `- V4 t+ ?3 [ void main() 3 V6 x' [# @8 T+ Y( `" j9 Q
{ , d$ ]2 I+ ^2 [$ W6 R
! k8 m+ {$ A6 Z uchar i=0;
1 d+ ~, w/ u k5 A+ ? uchar adTemp=0; " ~; K6 _5 T& b g
initSMG(); //数码管数据初始化 : e, u' X1 V6 q% x
ADC0804_csToLow(); //cs置低 3 D& `, a' a) A) ]* h3 X
while(1)
! J6 z6 X/ _5 ]9 ] { 0 t2 F4 D$ r7 |/ Z$ O+ \
ADC0804_startConvert(); //开始将电压数据转换成数字信号
& J& b, \& @4 Q! ^2 ] for(i=5;i>0;i--) //主要是延时一段时间,让ad完成转换
" Z4 {# e2 B B' r5 k, `. e {
) X6 o3 l. m9 D( M( u: k delayms(1); 4 e; o, m0 y. I, ?' ?' U
show(adTemp); //延时的时候,数码管继续动态显示
7 z) q/ G- Z7 |; s! V& I } 3 b: a2 a' H# y! B+ c8 g1 H
adTemp=ADC0804_readResult(); //读取数据
- D1 e4 n1 M" s* Z show(adTemp);
1 n: f5 `9 X5 w } . |! Q7 r; x! c; x" M v/ B
}
1 N# C, G6 S8 Z# A5 U
2 `0 @& s h9 }2 n* _" D
" T8 ^# u. _2 `% R$ z7 k6 A" i5 H
$ H$ t1 e$ Y$ Z* Y4 w( G. A
% O2 v- `2 r5 |) f* d# c, i2 L* e
8 d6 l; ?2 a/ g3 f. u9 g6 O: { |
|