|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
超声波传感器和stc89c51单片机的c语言代码 C:
; l% m9 h* w# H3 B" c: `SMC1602A(16*2)模拟口线接线方式9 M& m* t9 z/ \/ C8 W, ^9 E
连接线图:
e( f$ a! s0 \* Y! |% U3 P0 ] ---------------------------------------------------9 Z2 _; k- u) _( D( v0 ^- k
|LCM-----51 | LCM-----51 | LCM------51 |& F0 y; G5 R9 X) j2 e
--------------------------------------------------|, a. |5 X4 ?" y& t: \) w
|DB0-----P2.0 | DB4-----P2.4 | RW-------P0.6 |
4 z# `2 l) E/ ]+ {# ?* l& c1 Z) b |DB1-----P2.1 | DB5-----P2.5 | RS-------P0.7 |
0 y; ]7 O) }& m4 D& T* G* e8 A |DB2-----P2.2 | DB6-----P2.6 | E--------P0.5 |( N" R( u+ ?7 A) {
|DB3-----P2.3 | DB7-----P2.7 | VLCD接1K电阻到GND|' N4 l2 k0 }+ {( u0 ^6 z3 n
---------------------------------------------------. @) j% ]5 \# m7 B0 Q0 d# H
接线:模块TRIG接 P1.2 ECH0 接P1.1+ n3 y7 {& O3 T
/ C/ _; Z ]4 c6 h本程序源码只供学习参考,不得应用于商业用途 | # S! B. u1 F/ x3 m! X1 }! ?
#include <AT89x51.H> //器件配置文件
: p9 r" ~8 o* D+ v+ Z H% _+ S& k#include <intrins.h>* D/ z, @: z6 ]0 o/ Z+ R+ f9 @
#define RX P1_1$ f; y; [0 m) R" k. y& v* @( d
#define TX P1_2; s7 N% Q( b4 n5 B
7 z3 K+ f& T7 j( i1 x& }#define LCM_RW P0_6 //定义LCD引脚/ L4 M' X) R4 w8 }
#define LCM_RS P0_78 x' B y& g9 n1 t8 T# C
#define LCM_E P0_5
# ?6 Y0 p' l3 Y/ V& d. e- p i#define LCM_Data P2) C3 Y4 O, g3 h! r D
* ]7 V6 ^9 K9 G o" c: h2 L% E5 m! {# q0 z& u# K! ]+ S, j+ S z
#define Busy 0x80 //用于检测LCM状态字中的Busy标识' V# a. ?% D n8 V
2 R: n3 j l. i* B m( g3 ]) u
void LCMInit(void);
+ A8 U$ ~# z. Ovoid DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
6 ~- k8 t. O2 |9 Fvoid DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);7 W% Q: ?! {, \& ~" N! _3 i
void Delay5Ms(void);
1 [% b, E _2 |( N3 Zvoid Delay400Ms(void);
5 c& b9 Z, p# S# K% o3 z/ [9 ]7 _void Decode(unsigned char ScanCode);% a: E0 |& i8 R: b3 i, f8 ]" M
void WriteDataLCM(unsigned char WDLCM);" P& }& c3 X x" o" Q2 T: @/ u7 F$ L7 W
void WriteCommandLCM(unsigned char WCLCM,BuysC);
1 d: j+ Y: S+ w! F4 a4 r
' r" G- y- O0 L$ q5 X# n0 c- A6 Hunsigned char ReadDataLCM(void);7 D6 N$ C0 M2 S" [( ?
unsigned char ReadStatusLCM(void);
Z4 q7 ]# ^0 e' A3 v& bunsigned char code mcustudio[] ={" WWW*QXMCU*COM "};
/ M3 q6 L% K$ Ounsigned char code email[] = {"863888999@QQ.COM"};
$ J0 o) ~4 _ y- w9 |unsigned char code Cls[] = {" "}; l. C. ^8 Q8 D2 J5 d! @
unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
0 l! e. ^, ~8 b0 H8 X9 I# s; U1 o0 `! H: L) w+ p
static unsigned char DisNum = 0; //显示用指针
& D; y! F7 Y3 ~# {% a unsigned int time=0;
( m( U& A0 x2 p( Y" D unsigned long S=0;: p v, r! d) S. `9 x. A% S
bit flag =0;9 T# r7 W$ I. P2 T5 ~( {1 G" R+ s
unsigned char disbuff[4] ={ 0,0,0,0,};+ v! e: a3 o% d# e9 [
6 A% Y \( t4 l
2 R2 K. E& R& y' n6 i4 z
//写数据- Z$ x X5 `4 K7 B& ?
void WriteDataLCM(unsigned char WDLCM)* M& Q$ M) U, |/ q8 a. Z0 S
{
G3 m1 M: d) U' {/ c- H8 U ReadStatusLCM(); //检测忙8 k" P9 b# B2 @- e
LCM_Data = WDLCM;/ l! s1 i% o( i n
LCM_RS = 1;/ i5 ?! n. n4 Q& M, A2 l
LCM_RW = 0;" h$ E6 L6 [" c8 h+ v! \% f& n
LCM_E = 0; //若晶振速度太高可以在这后加小的延时. L8 B" s/ g1 [9 b4 B& C
LCM_E = 0; //延时
9 b& q7 @ N \3 q9 a LCM_E = 1;
* j3 `+ M1 {0 z, n/ ^+ B) P# {}1 F5 |! B& }: B) }3 \' F
% u! J/ D8 [( d: C0 i, T0 {1 d& u
//写指令% w# V7 v; A5 I4 S f1 D: H
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
- W& r1 ^. q' Z: r* {{
0 y/ N, k e% ^' ~ if (BuysC) ReadStatusLCM(); //根据需要检测忙 M; b% B( z' ]/ |; D, _* ^
LCM_Data = WCLCM;& F: f0 r1 X6 V4 t
LCM_RS = 0;
( p! }/ `& Q+ o% G+ S/ t LCM_RW = 0; " Z* C {+ a* d) l! D; u m
LCM_E = 0;
+ k. b& c4 d3 z- f3 M LCM_E = 0;
0 `1 y' C" Q& }+ N% a- R9 \ LCM_E = 1; 1 M% S' Z( A8 k3 c) o, L' q; X/ t
}! Q- ^* e$ H+ g. c6 X
- I7 \6 W4 ^/ g( \ \1 |# E1 f
//读数据
7 @5 j% ?. m$ l$ i: Runsigned char ReadDataLCM(void)7 c' N; X! a& s/ h, _9 \+ M' b6 G
{
. Y) u( d1 R6 ?$ m3 S6 W LCM_RS = 1;4 w6 g: n e! S
LCM_RW = 1;
3 Y+ j- p. C( N c# @" o LCM_E = 0;; ~% Q$ x/ U2 g& Z5 P4 B6 G0 g
LCM_E = 0;: D2 h/ r/ l; e" C3 Y
LCM_E = 1; Y* f( P, \0 ^: S% P
return(LCM_Data);
+ r! }2 m% `, M l$ S3 X* v}) o: n% O$ F3 Y
" ]! g2 c1 z( S7 G! J% p
//读状态
6 P- A- E* S6 r9 q2 k9 t8 Cunsigned char ReadStatusLCM(void)# a+ a+ P. |: _1 x, Q
{, S) F- n; d1 { S0 A
LCM_Data = 0xFF;3 P$ R- o f6 O) b5 i. I. |: v
LCM_RS = 0;3 R( \6 S! m8 F! h& R" k2 b% a6 @1 I" g
LCM_RW = 1;
6 ~) V4 c4 E/ A: ` LCM_E = 0;
3 k9 f1 a x6 ?% ] LCM_E = 0;
) R$ @" A- b" L* |% z LCM_E = 1;# r! u2 i) |' }
while (LCM_Data & Busy); //检测忙信号' s3 p( {( d: G4 g9 v4 G, m* @6 z
return(LCM_Data);
* m4 d! ^% M2 b) Y$ o1 o}
$ }: N$ ?7 H' Q* l. z2 P* N& x& U0 K% l
void LCMInit(void) //LCM初始化7 O$ ]9 I/ K1 `
{2 `& t3 ~2 d5 N: g- {( L+ w% k; X' U
LCM_Data = 0;
- J& ~$ e% B5 [( S9 O; s4 S WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
$ z! e' M" g- f' S Delay5Ms();6 Z i5 Q: p" Y
WriteCommandLCM(0x38,0);
% w; Y4 j. e' o- H# S Delay5Ms();% p5 F4 W e1 \* v
WriteCommandLCM(0x38,0);* [0 E1 G# H% Z4 C+ ~ [
Delay5Ms();+ F3 S5 K7 S9 [' e
& ~+ G' @' M7 r( r2 j# y
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
i* \+ T9 {1 s( |5 G0 o WriteCommandLCM(0x08,1); //关闭显示
& v4 n9 |( v5 U WriteCommandLCM(0x01,1); //显示清屏
; f% u( \7 W1 o# `" L WriteCommandLCM(0x06,1); // 显示光标移动设置7 x+ J: X# A4 H( j+ c2 a( L
WriteCommandLCM(0x0F,1); // 显示开及光标设置
" m( { m0 I- H7 B- `0 E4 `}
8 U. z7 R; w( E; p. {( x7 f, M0 S; z9 j) H6 s1 \0 q& Y' U6 _* J
//按指定位置显示一个字符
8 u, @9 c' j" T4 I1 `8 ]void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
" m8 {. G# r; f/ v% g{
" U @6 w2 G. H: r$ w/ F Y &= 0x1;9 A, \8 S* M y# i2 L
X &= 0xF; //限制X不能大于15,Y不能大于1
: n. U% I: o ]* B( N( W if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
+ }3 Q, n3 b; i/ I3 W X |= 0x80; //算出指令码6 s- C0 k- E1 c
WriteCommandLCM(X, 1); //发命令字2 B2 E' W: G8 Z1 w
WriteDataLCM(DData); //发数据
2 k7 X) }& y D( d- Z5 g0 O/ b}
! \) L R& v1 ]7 S' p; J( B
7 r) P, G7 e2 P8 }( I//按指定位置显示一串字符
- O2 Q2 v5 U8 j+ S2 U8 |; |2 h) tvoid DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
6 ~3 _8 O! @* ?* s. v5 v{
0 K! l7 l" d8 L2 A unsigned char ListLength;9 d9 }+ q; w( v% B: P
$ N0 K5 {! b/ y2 F( W. i1 U ListLength = 0;" _( P4 n! i5 E/ c0 U
Y &= 0x1;1 r# `- S3 y0 N" a! J8 ~3 _
X &= 0xF; //限制X不能大于15,Y不能大于1. p& G/ i, @# R! _
while (DData[ListLength]>0x19) //若到达字串尾则退出
' \+ s! b+ `4 m3 K {0 G( I7 ~- @: ~
if (X <= 0xF) //X坐标应小于0xF
4 d' n2 i; g/ s Y) D, ^ {
) ~- S- P) K' |: Q( B' V3 j DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
8 @8 U1 m3 p( `- n. W ListLength++;
7 @: `1 n% k$ x X++;
: Z4 d4 Q" O% V) F5 ?9 y& O- j }% y9 B Q9 B- N. U5 B
}- ~' l7 ^2 S) a6 n
}1 c, q# e! \! T$ }+ n; U, K6 ^+ z. n
, n( O8 x& O: r( R9 a! ^
//5ms延时, F5 c9 x3 Y& v- L
void Delay5Ms(void)
1 ]- M! d; r5 y* L% i{
- @. |* p5 f5 o- Q unsigned int TempCyc = 5552;) L6 A5 _- _$ Q6 A
while(TempCyc--);, A# P) [5 Q7 b' U7 M! c
}
9 Y$ S, |8 | ~* K/ G N9 W( g1 W& w9 r- q8 s+ r6 S/ z; i6 W# o! e2 H( I5 y
//400ms延时
5 s; q" ~: D( T& { Tvoid Delay400Ms(void)
! v: G% `! \0 H0 r{
) r, d8 K' J# Q; [( T- a unsigned char TempCycA = 5;
5 A7 G: b7 c; F" n# D; ] unsigned int TempCycB;
' T6 f/ Q7 j; W _: v G5 ? while(TempCycA--)
, V. T! [. h* K8 r. J& s0 D {1 p& G& B+ g2 h! ?0 ~. I- p) c
TempCycB=7269;/ t1 n( T9 n. c. E+ o7 r2 N
while(TempCycB--);
+ a% d; l/ y z) M. P };
+ T0 `8 M- Q/ f; b7 u) `}
( B# A# B' ]5 q$ K% S" y8 L/********************************************************/. e- C, B& a. X/ A; s
void Conut(void)
( R3 ~. Z9 _' x7 y9 m( [ {
6 J4 G0 l; T2 V% D3 y time=TH0*256+TL0;
" ^* m) }$ w" \ TH0=0;
: p. H" L! Z. L$ d TL0=0;: S& P& r- W: k0 J2 q4 j
3 ^5 }: y& [' q. W y5 |9 ~) l4 g S=(time*1.7)/100; //算出来是CM
1 v" o, c7 B( C' _0 X) v3 [6 ^ if((S>=700)||flag==1) //超出测量范围显示“-”5 U) d8 @ B0 N6 n! |3 r% B
{ 6 Q" C( f; a6 m) `" m
flag=0;
5 E3 |/ x4 n; r8 x0 z8 r5 P) j8 R$ S: Y) h# o
DisplayOneChar(0, 1, ASCII[11]);! X8 s" c* v0 [1 O2 T( Q; h
DisplayOneChar(1, 1, ASCII[10]); //显示点& d4 G, _6 X/ W
DisplayOneChar(2, 1, ASCII[11]);0 b, A7 B p; v$ G- N5 G
DisplayOneChar(3, 1, ASCII[11]);
2 w$ j j* Z4 c. |* B" ~ @) L% o7 \: Z DisplayOneChar(4, 1, ASCII[12]); //显示M
/ D- e' n4 m `. T/ b }8 l! f3 @* t, q5 S. U7 k4 h, T- N" ~
else
" B& y% A* ^3 Z# f% { L9 j6 H {3 j+ W- c0 n6 F" Z9 e$ x
disbuff[0]=S%1000/100;
+ q" n9 H; d# Y disbuff[1]=S%1000%100/10;
7 G$ s" J" @, b, j! | disbuff[2]=S%1000%10 %10;
- \1 `# F$ s# s DisplayOneChar(0, 1, ASCII[disbuff[0]]);
; S( E+ |* V w( f* i* f/ c/ F1 K DisplayOneChar(1, 1, ASCII[10]); //显示点# }+ C1 O d5 S& g) g9 n# g
DisplayOneChar(2, 1, ASCII[disbuff[1]]);
* b0 I7 Q. t: K' } DisplayOneChar(3, 1, ASCII[disbuff[2]]);: ]0 @' ]1 H5 Y( m0 f$ c0 r
DisplayOneChar(4, 1, ASCII[12]); //显示M$ W S2 f) C3 ]/ o+ F( G
}
. [$ r6 v/ L K% X z& X }
1 [+ s+ j5 r8 X4 b2 P/ G/********************************************************/" O* X6 e: J) [+ P8 Q' d0 v
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
* X. l2 n" E4 q2 }9 w4 a. ] {
B' k5 K% ~# b0 T# U/ r: A, d flag=1; //中断溢出标志
7 T! a$ @; {1 H7 N& ^6 Y }0 O7 d0 W a: I% X1 M
/********************************************************/1 }0 A" f# o7 d/ o/ C8 h% }% _% x& |
void StartModule() //启动模块/ x/ s8 Y) A0 R* |1 J7 a; W
{
2 J* y* P( _3 {6 T TX=1; //启动一次模块5 r) [& {# N: _- a# p; U" U. d
_nop_();
' }5 F9 h" b( D' O I _nop_();
1 {& ?/ ^! X1 q4 h! m0 o* F _nop_();
' k$ _% l1 X& c+ J7 a) c _nop_();
6 f5 l, x# I- ~6 r/ _1 v) U1 G6 Z$ G9 T, K _nop_();
" P$ C4 |- j6 n. Z: s7 O6 d* o2 z | _nop_();
y1 S7 g6 a* R' \7 y _nop_();! T9 W9 V" H: r+ ]8 ?+ J
_nop_();
' e. J9 V$ s/ } g8 @. k9 W+ } _nop_();2 q- r. j1 \& v0 }5 V. B! a9 u
_nop_();
8 s' x% w, h( M* R _nop_();6 \ L# s. R7 l! [" _" `: X$ q1 M
_nop_();
" U# b# I+ D8 X! M b3 o5 P _nop_();$ \7 D6 \& J |5 a
_nop_();2 w: N6 }0 U% r
_nop_();& N6 c4 }. t, |- p9 N
_nop_();
; v8 U! m' ^6 D( v+ e _nop_();2 a& U# ~! \0 F* n) X
_nop_();
' j& T" J' M* q. B0 Z' x; L% I8 Q$ n _nop_();% Z* T6 R& c, ~& E; b$ M( M3 G
_nop_();8 p" k" }, }, y# G2 q; e! v
_nop_();2 I8 `: C# X2 L9 a- Y/ l
TX=0;/ Y# ^! V- o/ J0 b
}
7 s2 o; j" B7 G/********************************************************/4 o! X! o7 `" g( y" Q
void delayms(unsigned int ms)7 e e, L6 k+ A; ]
{+ s: }, R9 M/ X. V* }/ j6 X
unsigned char i=100,j;
4 u: q" Z5 n1 p# k5 { for(;ms;ms--); h$ u/ k8 }$ @# u5 O3 h
{. l" X7 e' H2 r; \' }
while(--i)
8 }* D# U, K, |: p {% r0 T# ~. m0 F: f5 [4 G2 f
j=10;
1 C% D$ v3 e7 C* D w2 U while(--j);
& y8 A5 o! ~) e4 b L- O9 p }
( G0 I8 i' s) P. z, Y }7 K" L9 ?7 s: o4 q* P; j9 u
}; o& n. Y4 b6 Q, N+ \- ]
/*********************************************************/
* f# v8 h& M: c4 e, `* uvoid main(void), u: z9 Z b+ T0 W4 V# q5 _5 [
{
2 Y9 `3 C6 B4 U! x+ R1 V unsigned char TempCyc;
n: S" ` m' e4 A0 \ ^4 s Delay400Ms(); //启动等待,等LCM讲入工作状态
' V9 }/ s" a/ i4 ?& w, t LCMInit(); //LCM初始化; A5 n7 f! V$ q( R
Delay5Ms(); //延时片刻(可不要)
. o4 H% P8 j6 w* N5 j) ` DisplayListChar(0, 0, mcustudio);
( _& c1 L7 O( A7 k R DisplayListChar(0, 1, email);
\ n# u/ }" b% I) O ReadDataLCM();//测试用句无意义5 d9 m: W% x( [$ t+ j# }( t; B. a, w
for (TempCyc=0; TempCyc<10; TempCyc++)1 K0 `* y* i' l5 R% {
Delay400Ms(); //延时
3 a! T! s. i- J4 i! B: v2 O DisplayListChar(0, 1, Cls);
) j, y5 F- U6 N' P while(1)
2 k! X0 Z) U0 W- Z" p' i$ ] {+ w7 f, h! }( B" e; O& H, X
TMOD=0x01; //设T0为方式1,GATE=1;
* C- o" N, a: x) r TH0=0;" U! I. W' | h9 K* b$ {, e
TL0=0; 5 j" o1 n, H5 _0 u* Y
ET0=1; //允许T0中断3 M% r8 s2 s* ~& M- R3 i" O b
EA=1; //开启总中断 3 z* B' |9 k. V
( Y) t: n& B& ?7 D9 x& a/ B while(1)
6 b( j9 H# }, R9 _% X, b$ d {' i2 P1 f/ ?, Q7 Z# B* ?# p; t) I: `- X
StartModule();
8 }5 z7 H' h' E3 ~ // DisplayOneChar(0, 1, ASCII[0]);# I1 o3 {, S9 f9 p# B
while(!RX); //当RX为零时等待6 c! t: L1 A4 u0 t: h3 X" {! @
TR0=1; //开启计数
6 ?- a3 h* o1 s1 V$ z3 s& R while(RX); //当RX为1计数并等待- y a' I: e d7 X9 ]; m" K* n0 X1 g
TR0=0; //关闭计数
! z4 q9 Y) ^/ o: o: b% Q, a# ^ Conut(); //计算3 ^2 P D. u/ T6 s; p; L
delayms(80); //80MS" J! h& M o" Z0 P$ l% s
1 t8 y' x) W8 O } y5 \+ n( i: |
}* C7 f$ }! Z. F" W$ o4 k
}
& `# z* R# _2 U% I- W: F
9 M1 F' y) O: O' r$ K) H
0 X" Y3 v6 q; K) g/ D3 R# C% q h/ ]8 r
|
|