|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
超声波传感器和stc89c51单片机的c语言代码 C:
/ b1 }6 j" ? ?0 M, C3 s7 \3 uSMC1602A(16*2)模拟口线接线方式
" j7 U2 J; K5 [0 F连接线图: # i! x7 j1 Z! |( d" \, _7 g6 K* r: n' a
---------------------------------------------------; B' |, `+ h; V
|LCM-----51 | LCM-----51 | LCM------51 |
' ?) j$ n7 S6 p& X* J --------------------------------------------------|
% O! o5 z2 y; E1 k* G! L |DB0-----P2.0 | DB4-----P2.4 | RW-------P0.6 |
/ n- ]) D }2 T# X2 G) o+ s |DB1-----P2.1 | DB5-----P2.5 | RS-------P0.7 |
* W5 I# \+ v* X( X- O# Z7 K& M |DB2-----P2.2 | DB6-----P2.6 | E--------P0.5 |
, ]4 }/ j. e$ v3 ?8 { |DB3-----P2.3 | DB7-----P2.7 | VLCD接1K电阻到GND|- z' Y1 c4 o" X& M" }
---------------------------------------------------$ b8 d: Q! I: r
接线:模块TRIG接 P1.2 ECH0 接P1.1
( y: F9 {! v8 U6 p' h' `9 w0 T4 s
: f/ C1 `. a2 g( G% k本程序源码只供学习参考,不得应用于商业用途 | 0 D5 @- y6 T3 [5 _& ?$ I' b [3 z
#include <AT89x51.H> //器件配置文件
1 M9 `3 }4 P2 n% p# q8 Y' }* x- S8 e#include <intrins.h>
' U7 v1 n5 {: |5 P; W#define RX P1_18 X" B9 n5 s% C" F) H( N# F* ^
#define TX P1_2+ O w3 L; Z7 _5 v. ^/ v
: z# [ F4 R& D, B1 ^! L2 E
#define LCM_RW P0_6 //定义LCD引脚) {: r: I- O7 ^; u) X! ^- P$ k
#define LCM_RS P0_70 d9 _; @* l: `0 O4 }
#define LCM_E P0_58 @4 \ S) [% _
#define LCM_Data P2
1 l, R% f5 k: h8 h) G f: j+ U# w
7 s: h5 X% Q( v: E#define Busy 0x80 //用于检测LCM状态字中的Busy标识; z$ O9 M+ j, c2 T
% ?- y W8 e' g: y9 fvoid LCMInit(void);
9 ]7 F7 ^ a& z4 z3 ?$ Kvoid DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);; _( ^* @6 d/ U3 I r
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);: a$ ^% i% w/ _5 [# n/ M+ Z
void Delay5Ms(void);
; p0 Z/ Q, N3 f) hvoid Delay400Ms(void);5 [, j& N! S/ F8 s1 m' { O* S# S
void Decode(unsigned char ScanCode);
4 @- H0 F) o( vvoid WriteDataLCM(unsigned char WDLCM);! d! f# w3 w3 Q5 X& W
void WriteCommandLCM(unsigned char WCLCM,BuysC);
$ V- @& k1 Q5 E) S7 @- j$ S% Y
# I2 T% f, H! W. Q4 u* ]unsigned char ReadDataLCM(void);
! o/ E1 ^0 T G7 Ounsigned char ReadStatusLCM(void);. M$ c" `& x- c' O& V6 B
unsigned char code mcustudio[] ={" WWW*QXMCU*COM "};
! y$ W+ e% n$ v- k* wunsigned char code email[] = {"863888999@QQ.COM"};
, Z5 q8 X8 `4 C# c f& q; ~unsigned char code Cls[] = {" "};
\; `& y c: r# ^unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
) G/ E1 \% O$ e1 _9 J% p
- K. T! [: O5 ]- ? A& G9 l: v- L# Astatic unsigned char DisNum = 0; //显示用指针
0 ?# h% l( q$ v/ L6 O$ @3 [ unsigned int time=0;$ f2 q; W0 V) N `) `: z) B" Q- R$ ~3 ?
unsigned long S=0;
1 | o* S% k3 d9 C% G bit flag =0;. [8 n" {8 w+ K/ ~7 B) B
unsigned char disbuff[4] ={ 0,0,0,0,};
, e, Q0 G- ] o- Q3 K
: o% b) b! j/ E3 y) w. i; s. e: j- h: F# s! M+ U; I1 E8 z/ r/ ?
//写数据
# u/ `$ I. z: E, yvoid WriteDataLCM(unsigned char WDLCM)
$ y* {: m# |+ K( v9 A3 k! U{% [4 X4 k- f7 s6 E# a$ | ]
ReadStatusLCM(); //检测忙5 H; p4 Y. o/ z9 \$ @* i; S
LCM_Data = WDLCM;8 x- i: \7 C% K. j1 Y2 ]
LCM_RS = 1;
* Y V7 ]* G# N* m: e: J LCM_RW = 0;' C! \ V2 h. k7 x
LCM_E = 0; //若晶振速度太高可以在这后加小的延时5 S) x l, a! s0 p. m8 A8 U
LCM_E = 0; //延时
( q u" A/ K I) { LCM_E = 1;
0 }1 N4 C) L# X; Y# y}/ X. K1 h/ `- b/ m- f* b ~. X, h
7 |* [; V# }8 t0 N K' i! l
//写指令5 u3 a+ b$ e; m& S! H! V# H4 T
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
% g0 f1 g$ l$ K{
8 g) Y8 E4 a) g7 n0 V, M if (BuysC) ReadStatusLCM(); //根据需要检测忙% _, P" K( A1 C% R# F
LCM_Data = WCLCM;, R, |6 X7 Q9 x1 A% P5 W/ h# q
LCM_RS = 0;/ M y( ?! v# W8 i
LCM_RW = 0; ) g; p. d, S5 u
LCM_E = 0;/ l1 t" Z) n: e% Y* x) D
LCM_E = 0;0 u5 V! g$ D! v; G8 Z4 |
LCM_E = 1;
9 K9 R' n' C) x1 s/ A/ {- @}- k6 H; r% T! I& W
& t1 }* h; @* f; a//读数据
# {3 s2 [! d0 c1 Munsigned char ReadDataLCM(void)8 b2 X" i% G- A/ a8 S; \: J+ M
{
1 W- Z" f8 w" Y9 Z0 X2 ^! w1 d LCM_RS = 1;, s, c2 C# { Q, B
LCM_RW = 1;6 ]$ K: y( ]7 Q6 }& K& v
LCM_E = 0;
7 F. m0 V) u2 I+ N, ? LCM_E = 0;2 r% E7 ?, [0 O7 m y6 @% [/ X
LCM_E = 1;8 h R: Q8 W: z( N/ \% y; Z
return(LCM_Data);. {# j6 @& Q7 @8 F" A `! P* e
}, B2 ^; s' \( R4 P3 A( o' x
# y, g2 z0 W9 @$ A
//读状态! G+ L9 O0 V! H8 y0 w- G
unsigned char ReadStatusLCM(void); s4 V" B% _! N
{
9 d' A( e* a; T LCM_Data = 0xFF;
4 _& x4 p( G) f" E; |5 A1 i LCM_RS = 0;- g4 ]$ U5 g* v4 i
LCM_RW = 1;2 Q' B, S% c# U" p- q9 A B. ?
LCM_E = 0;
0 w* k0 U9 Y6 @$ [/ E5 o LCM_E = 0;( C& b3 @1 V% b8 f! a
LCM_E = 1;
: j- a$ V- M9 [, l8 N3 d. U while (LCM_Data & Busy); //检测忙信号9 J( R3 A1 p/ b' C8 l- }# B
return(LCM_Data);
6 u: _$ M' R; g a1 Q z}: M7 [, I3 Q) o6 a! s( r3 ]
+ q# P( F/ w4 F
void LCMInit(void) //LCM初始化; H6 G$ o8 E& s6 K
{
: @: x" E" h" a) w7 f LCM_Data = 0;+ \; J2 c9 F) T Z9 } I/ S. ]
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
) H1 q9 u$ H) v, i Delay5Ms();, p, M3 U2 d$ E
WriteCommandLCM(0x38,0);* d# g+ ]& O6 z* j/ ^+ f4 }+ f
Delay5Ms();
3 y. h1 r* J' b1 B1 t WriteCommandLCM(0x38,0);" r4 x( {$ I. J& K% v" I$ L& @
Delay5Ms();( W7 o$ z2 D1 `% s. C
( c& H8 z2 y) {+ ] z0 @, b# b0 P WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
( y- f, ~5 v' Z: V WriteCommandLCM(0x08,1); //关闭显示
& g$ p: j D# y5 k5 l7 e WriteCommandLCM(0x01,1); //显示清屏8 o4 Z9 u; n5 `. W- z
WriteCommandLCM(0x06,1); // 显示光标移动设置' k8 |; Q% U5 G. j) R& U5 z. J: m/ H
WriteCommandLCM(0x0F,1); // 显示开及光标设置! T' D. F: E: |- |: Z
}
+ o ]- {* h3 {- D4 }' l( b- e0 x6 _. K% [
//按指定位置显示一个字符
1 k+ z+ x/ @7 @2 Bvoid DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
6 e6 e ]" ]6 t; \+ G& J& }{5 p2 z. Y8 `" h* E, ~
Y &= 0x1;1 T% G" _. X* c( o
X &= 0xF; //限制X不能大于15,Y不能大于1' Q% X( ]) L& X [3 C
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
0 M) o* @* F( o( P2 X" V' I x X |= 0x80; //算出指令码
: B+ B- Q3 i0 }0 h; R WriteCommandLCM(X, 1); //发命令字
, x8 R' \) T0 V" @! q+ P WriteDataLCM(DData); //发数据
" |+ {) x2 L+ G# C' m# Q9 B, G6 R( A}
9 |' q6 E3 v, E* u* i# [- s1 ]& V( |
E. @! A: E) R" M/ t* [//按指定位置显示一串字符
! D% x; v4 I$ Z. X: mvoid DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)) C; |5 R. `) A9 H8 S
{
# a% |( r+ F' w! _1 C/ g unsigned char ListLength;! a Q( l; z- b, y7 }* c; H
7 s9 J3 H. f6 ^& K0 ^ ListLength = 0;2 Q |0 Y& v. p3 \( w; x1 T) u
Y &= 0x1; i% {0 x! Q# d S J
X &= 0xF; //限制X不能大于15,Y不能大于1) H4 l) @8 M9 n: D' W2 k1 c
while (DData[ListLength]>0x19) //若到达字串尾则退出' M- a4 I0 I# ?; \; ]' S% f2 B4 I
{/ A6 G2 H7 a( B5 x
if (X <= 0xF) //X坐标应小于0xF; A6 Q5 y" l5 \6 z1 d
{
. \2 O2 o' I0 E { DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符3 ~) {* r. d0 D# Y n, g* e6 R9 F
ListLength++;
( C; y) Q0 f/ f$ {) c) G X++;0 x# n* ~8 {/ ^
}+ [2 [# e5 |' I/ W
}
L7 o! ?/ ]! S" ]( A: N0 [}( a# @' q( f$ a$ i3 \+ u
' {+ K m2 n L$ w! |( x//5ms延时2 p9 [( Y! }: {* x$ D- i# e3 u
void Delay5Ms(void)+ e2 G. r/ f& k* X
{+ N5 e/ Z; D( S5 V l
unsigned int TempCyc = 5552;
9 r8 {* f7 P/ r3 V while(TempCyc--);) H! Z, A6 g, X
}
; N/ J6 I T3 N7 Y
% g# G& M: d8 E' F U# T: @//400ms延时
$ T- E) t e/ a1 Wvoid Delay400Ms(void)- J: H( f/ D( h3 K* C2 S: A0 N
{
/ d. `9 r: ]4 x$ ]" _# R unsigned char TempCycA = 5;
9 ^4 F+ {- q/ P# Z, p unsigned int TempCycB;) z. H7 }) `) A. v; _2 [+ w$ u2 K: F
while(TempCycA--)( ~4 q- f+ O9 w
{
& D; m( {& u& y2 @5 i% w TempCycB=7269;6 j; A" P7 ?1 D
while(TempCycB--);9 d. U6 J! c2 H7 R4 H2 i( F1 L% R# U
};
7 e4 W- q" v( l}6 |* d- {+ p4 H. k3 m
/********************************************************/
2 W! i+ E, T- D' l3 m K- c! n void Conut(void)/ ?9 T4 b% \6 Y. n( b- K/ m
{ b1 j3 b# C" m4 f# W
time=TH0*256+TL0;% [- p' x, r* v5 N* x0 B; M
TH0=0;( U$ d/ q H( p" V/ u$ x9 l
TL0=0;! N1 t4 ^% h1 M* X5 M G/ |
7 ~4 I: G( _+ V8 y2 h( O, x S=(time*1.7)/100; //算出来是CM
6 d( A) l- N% W# ]7 K if((S>=700)||flag==1) //超出测量范围显示“-”' X$ @4 y$ ~. t
{ 7 r# p8 \; _9 V" N2 s! A
flag=0;' f+ ^! D3 t% Y# V0 E% a
! F+ d* O& T% R2 `! f3 [3 |0 O/ g
DisplayOneChar(0, 1, ASCII[11]);
$ w7 L0 T, g& s6 {1 s) s DisplayOneChar(1, 1, ASCII[10]); //显示点
7 O1 Y" C, O# `$ M8 R DisplayOneChar(2, 1, ASCII[11]);0 D2 H' g7 j. @
DisplayOneChar(3, 1, ASCII[11]);: ^4 \1 d! V# t; M8 s0 [8 P
DisplayOneChar(4, 1, ASCII[12]); //显示M9 h' c8 A$ M( i5 u6 L. A" g) l5 b
}. }+ c. s( f8 ^
else6 j4 G6 D6 ?& h7 D8 O t
{- F# _ M+ e n) z( W' E6 i
disbuff[0]=S%1000/100;
8 ~2 B4 k! f( u disbuff[1]=S%1000%100/10;
% d% V( C( T7 A, B6 B, h2 d' N# ] disbuff[2]=S%1000%10 %10;6 ^! h: s: {3 [# c* n
DisplayOneChar(0, 1, ASCII[disbuff[0]]);
3 g" K/ {6 P- L: j# ^2 g: @3 R DisplayOneChar(1, 1, ASCII[10]); //显示点
! K- i% p' L: J! m DisplayOneChar(2, 1, ASCII[disbuff[1]]);
. a# K2 v! m* h2 G DisplayOneChar(3, 1, ASCII[disbuff[2]]);* G" D1 D7 e* |
DisplayOneChar(4, 1, ASCII[12]); //显示M
" M+ A! `# A1 b. s }
$ V$ h% ^% \2 n/ D& a' |2 K! A4 n }: B" N1 |9 O# ?& l: Q# M: u: y3 t
/********************************************************/9 C5 |2 z; g$ z f3 C# ?
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围0 ]7 x( R( @% B- Q1 F2 ^9 v
{. I0 ?( L+ ?. _* g- v
flag=1; //中断溢出标志/ G7 f# c- K; [1 r
}+ e2 B: s4 ], n) y# G- H; r
/********************************************************// t6 O5 x% G: I+ Z
void StartModule() //启动模块- W3 \ b0 U& a0 t, l3 O
{
) T [7 m, w, B TX=1; //启动一次模块5 _" V( k. r* s2 d$ Y
_nop_();9 |, e0 R! ?9 b0 t* g% J, l
_nop_();
9 b1 l! P% d% a) R. w _nop_();8 A# I' i" ~7 ]
_nop_();
: N/ M1 L+ B3 m& w" R) l# e _nop_();
6 s+ i: R+ ^; S _nop_();; h g7 @- n$ k! {( B
_nop_();
$ L7 x) {9 j s( w9 [7 J9 H _nop_();
5 G4 z9 s4 S: J6 M _nop_();. f5 x0 ^0 n! t" [
_nop_();& n! p- p3 o- |! A% s2 A4 G
_nop_();: i* u7 }7 {0 m4 y, n) Q
_nop_();
# H, L% @; X8 X, `8 U" N2 q8 A _nop_();" `. n; f4 o5 {* \6 B9 z
_nop_();5 ?( n; z3 i5 v' a# h# N+ F# t
_nop_();
7 u% Y" G6 k0 o- e+ Q _nop_();
" P0 z& C2 _ Y: z _nop_();
" D* ?6 {# `) V _nop_();
5 Q% E# `1 v; M: R' U9 Y2 ^$ `1 v _nop_();) a; D6 z" e* ~+ K9 j9 Z
_nop_();* i" f& D; H t; J7 g$ k9 \
_nop_();) Q2 i; E; A/ u) F3 M0 x2 X
TX=0;
6 x: _* }# h7 v* i: g: m Q! u* P }
9 N% E. W: b# u2 p/********************************************************/% o2 U, j- G2 [0 @
void delayms(unsigned int ms), k7 {$ B; k. n/ P
{! S7 k& g9 h; D; H+ r6 H
unsigned char i=100,j;
, y5 g- o' c% D2 r7 f" X8 S for(;ms;ms--)2 n' r; V- _9 o" e* d q$ _- e3 {# P
{
; D, e ^5 b3 v$ D, r$ v8 a* d9 [: G while(--i)
. I8 i9 x; M0 c. P8 D8 l {% S6 ?4 p( V. Z3 P$ t
j=10;
# Q S3 o' X( O+ J6 U8 p while(--j);
1 [+ W( }4 g. f5 f }
& ~- u( R, z/ x% X7 m1 y$ |0 V; n% | }
' ^ a' _$ M/ n0 B}/ `3 F1 O0 F7 ?& C- g3 M$ F) L* X
/*********************************************************/; i/ w1 u4 L$ d2 o) v7 o2 V
void main(void)
7 Y$ K- @4 X, h s$ L( M# |{
$ V8 `8 M- c, O9 M) ]! N1 C unsigned char TempCyc;2 J6 D3 U% `. K7 E# z
Delay400Ms(); //启动等待,等LCM讲入工作状态. p+ @, b+ O0 n$ \1 e0 N
LCMInit(); //LCM初始化% \, w+ s4 Z$ u) P% U
Delay5Ms(); //延时片刻(可不要)3 x# R/ Q4 Z& K4 q& e7 r& P
DisplayListChar(0, 0, mcustudio);: p6 H. D. [. L4 }
DisplayListChar(0, 1, email);
9 v8 t r5 T% F8 x! | ReadDataLCM();//测试用句无意义: [: r6 u8 ^( I* r9 E3 J
for (TempCyc=0; TempCyc<10; TempCyc++)
: ]) V5 X: O v Delay400Ms(); //延时
9 {9 R% f7 y/ Q DisplayListChar(0, 1, Cls);
& H! e( O& ?; E; n; N; y while(1)5 R- X* Y8 u& M4 V7 [& O0 u
{: i+ C0 E+ R. a3 y0 r0 G _+ r
TMOD=0x01; //设T0为方式1,GATE=1;
; R% M1 |) n! p. L TH0=0;; w) \% a7 R2 S" x& c
TL0=0; ) R+ h5 |) O& l9 i
ET0=1; //允许T0中断; n- J+ Z4 m7 R+ h/ y8 E4 H
EA=1; //开启总中断 8 \& H7 H& h$ B- s" i( C# @2 W
7 k! ~8 g( ^3 n0 {- e6 M' F$ u
while(1)
; Z8 t, Z% N) Y _ {. @8 z' w- T9 O$ E {) N
StartModule();
% b* s' |; M" k; k3 p // DisplayOneChar(0, 1, ASCII[0]);% q, w/ i8 H% H/ g8 U2 v( m
while(!RX); //当RX为零时等待
; o. y; C4 T" V {4 p6 y- g5 K TR0=1; //开启计数% Q8 n9 R2 y. W. q+ h
while(RX); //当RX为1计数并等待* N0 o! q+ F: _3 W6 e @5 f! P
TR0=0; //关闭计数
j) X6 H) L0 ~: ~ Conut(); //计算
! _ y3 u5 z* S delayms(80); //80MS
0 c X2 Y8 g* Y, w0 w
* U; S7 p. v# X: C4 M6 ]7 z; k }
& ?8 g F: p8 X0 V2 ~0 U" H }0 r% M) L% p! ]3 [& m
}" V! K% E1 C t6 D) S+ i
- D$ Y! ]' w+ U- U: w) E; h
* q3 v1 }) l& P3 c4 G- x! E
! |/ Q! Q3 {4 F0 m. t" Q |
|