|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
超声波传感器和stc89c51单片机的c语言代码 C:
4 W3 w! H9 y( [6 Q* C2 t8 S5 bSMC1602A(16*2)模拟口线接线方式% @' Z+ g7 [" [
连接线图:
* |8 [' E9 P$ ^: Q* B& T ---------------------------------------------------9 Z& X& {' I( b
|LCM-----51 | LCM-----51 | LCM------51 |+ {' O, d: l5 S: {- T7 j9 B: \
--------------------------------------------------|+ |1 c8 P; k. {# O# G' C* k
|DB0-----P2.0 | DB4-----P2.4 | RW-------P0.6 |
+ t( t* `" @2 q$ z) B% d! o- c4 q( `& u |DB1-----P2.1 | DB5-----P2.5 | RS-------P0.7 |6 i: n1 B' a! W+ U$ R/ Z" l
|DB2-----P2.2 | DB6-----P2.6 | E--------P0.5 |
g8 _8 J2 a4 A& h% C+ X |DB3-----P2.3 | DB7-----P2.7 | VLCD接1K电阻到GND| d, @) w7 ~ U# V8 s) f
---------------------------------------------------
( _$ p }( u& F! x. K1 z接线:模块TRIG接 P1.2 ECH0 接P1.1* x1 t9 c1 ?; L% t' Q/ i
+ C4 t, e- E3 J+ Z& Y: E
本程序源码只供学习参考,不得应用于商业用途 |
: \4 L& z6 Q3 _5 `# v9 F$ b#include <AT89x51.H> //器件配置文件
7 S9 j: i5 F5 Q. x8 L5 L#include <intrins.h>
7 j1 t4 z, G& x; v; _/ o7 z#define RX P1_1
6 V8 x7 \' m2 r, }, f q( I#define TX P1_2 ~3 W$ A" q4 W% S+ }2 N" D
$ x7 G$ Q4 B g* n) O
#define LCM_RW P0_6 //定义LCD引脚; \+ h& O3 A/ P! M
#define LCM_RS P0_7 l3 u( K2 l1 A& Q, T
#define LCM_E P0_5
# S- x5 A" y* ~7 `( L$ y( P7 ~% k C#define LCM_Data P26 a! Z% n9 w6 n+ H2 B9 N! u# h7 a J
# P# j0 K: M" d3 k. I( [" W% S' a# I9 `3 V3 U- O9 W$ H5 y
#define Busy 0x80 //用于检测LCM状态字中的Busy标识; Z# S6 _3 ]) p! ^3 X/ K6 Z
9 @" S ^; @2 a. q) e$ n# a+ i
void LCMInit(void);
! g5 o9 Z9 ^$ |void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);# x5 ?. ^" j2 ^3 e( E9 G M. h ?+ x/ ~
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
' U4 A" X$ J, d! r! vvoid Delay5Ms(void);
! i: R- P/ v" { N, q+ Fvoid Delay400Ms(void);, a. E( ?. w, h0 d$ ~
void Decode(unsigned char ScanCode);7 b# a' p$ g, ^9 f' B
void WriteDataLCM(unsigned char WDLCM);% p; c9 j/ g. M& ]4 h
void WriteCommandLCM(unsigned char WCLCM,BuysC);$ R5 i6 D6 x( b, j1 g% ]- q% ]
K8 z1 [% P3 w
unsigned char ReadDataLCM(void);
. C: m7 }9 C4 V zunsigned char ReadStatusLCM(void);
1 r9 c( A# A& y6 I$ h2 L3 Dunsigned char code mcustudio[] ={" WWW*QXMCU*COM "};
' _; m, P& i$ p3 tunsigned char code email[] = {"863888999@QQ.COM"};
3 {& z8 P+ l% f3 }4 n1 ^* Q vunsigned char code Cls[] = {" "};
" G+ X/ ]! C, K: ]* r7 S! J4 Hunsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
0 }% p: i. T8 r" H
5 O' b* b+ b5 U0 u4 M& o0 [$ Bstatic unsigned char DisNum = 0; //显示用指针
. ~3 S8 |- z/ b; L unsigned int time=0;6 Q$ ?6 F6 K! T3 o/ s
unsigned long S=0;
9 H" m. P! g' ?" T4 o1 P- W/ `. M bit flag =0;
* d, k2 c* q9 w- @7 s3 W unsigned char disbuff[4] ={ 0,0,0,0,};' |, Y4 ~# X# E& s( c- y
: y+ P% E: h# F% e' J8 G1 D2 ]
: \. @; E: J- q0 c; H. _//写数据
W1 a/ l- z/ d+ Q9 Hvoid WriteDataLCM(unsigned char WDLCM)- d& B- y# z% H9 W) ?+ ^$ w
{
5 f, V2 _, M: z& L9 k* s ReadStatusLCM(); //检测忙0 X& T" Z, n! t3 X1 K- a+ L
LCM_Data = WDLCM;+ P; g5 ?% O1 T; S2 ^1 Z. I6 ]
LCM_RS = 1;
6 m2 j' I+ Z8 t! e! L, q$ U LCM_RW = 0;
8 P# a) A* P: |! K LCM_E = 0; //若晶振速度太高可以在这后加小的延时- x( E4 c8 ^2 h0 v/ r4 N
LCM_E = 0; //延时2 z6 m3 E& P7 z& b+ j4 g
LCM_E = 1;0 @) z+ o2 O, |
}
+ r; E2 b7 v% m) U% D$ r) v' u5 b$ o d0 y O
//写指令3 ^1 ?) f% p! {& Q4 S3 [) P
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测! C. n1 O* a. p) i. `% o- ]$ A5 n
{( }' u6 T% V8 M* R9 y6 A, U4 }% F
if (BuysC) ReadStatusLCM(); //根据需要检测忙
+ b. v% ^% b" I9 @) j' r LCM_Data = WCLCM;
) D0 X- S7 I( x S7 V- a( s% q LCM_RS = 0;
( n/ B2 E- K# i+ M8 s# F' e* r$ Q LCM_RW = 0;
* D- R/ i8 p) i: E3 k$ W3 E LCM_E = 0;
# l W1 n: V9 G# P' e( M LCM_E = 0;
" ^. ]* }) V$ K& A7 V% s8 D LCM_E = 1; k3 V+ O0 s: D! @8 t* n- ^
}# E8 O0 ~- s. w4 u/ K
+ R; ?, g: p/ h& H3 c//读数据
) b5 _* Z2 h9 M, Dunsigned char ReadDataLCM(void)9 B) B* H+ d" D7 N4 c
{
) p, y C; |7 ` F LCM_RS = 1;$ _, E9 g6 A! x& T; S
LCM_RW = 1;, m' s- E* k/ Q" Y- v7 R
LCM_E = 0;' w1 }; A6 Q) \2 a0 E: ~% X; d
LCM_E = 0;
9 q% N. E1 u! V LCM_E = 1;4 q' \7 {. \2 ]5 J
return(LCM_Data);& J) f# x! l* w8 b/ l' G
}6 C, V1 W! p. ]% i2 x. j( f8 ]
+ P; I% @" A# J h//读状态
0 D% c8 U$ I: y' Z* g J9 uunsigned char ReadStatusLCM(void)
8 c& i* t1 \1 {0 \8 ^3 a{+ w y' y0 x# E& ?8 [2 z" x5 d7 [
LCM_Data = 0xFF;7 j. q% T+ V) l! v" R0 K& _
LCM_RS = 0;% e g) E( ^, i7 [
LCM_RW = 1;3 h- l h9 V0 E+ Y) H$ L# R
LCM_E = 0;
/ t/ g% l& S- u/ M J& X LCM_E = 0;7 q3 w5 `" y% C% G* j5 i6 {
LCM_E = 1;
% F4 U3 J& W* ^" t( ~ while (LCM_Data & Busy); //检测忙信号# }/ S% I2 i k6 ]6 x0 k
return(LCM_Data);( z- L+ R" W; e5 U* k: ^
}
7 R) D# @' T$ b; Q3 K. D
9 n( I) |" E+ y& d, L# nvoid LCMInit(void) //LCM初始化7 h. ^' p+ h' V6 X! w4 ?& c
{; X2 n' `( G+ J. _' T3 u
LCM_Data = 0;
5 h& a9 \. w7 S x2 Q WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号, R" s# A0 x6 A" ~+ x- w5 u/ ]/ v3 u
Delay5Ms();4 A4 K- F% h9 ?9 ?
WriteCommandLCM(0x38,0);
5 `; P- e- B7 z Delay5Ms();1 s M& p# k6 p$ u# u0 Q. H& U3 _
WriteCommandLCM(0x38,0);
+ b0 R/ u @) ?7 q# p Delay5Ms();
* u5 M7 f; x: s5 F7 W. ?7 {7 w' I" A7 _" u0 u0 M
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
0 P, L# t; g4 X6 N& W$ Q5 L8 p WriteCommandLCM(0x08,1); //关闭显示
4 `5 {2 N3 `& N5 c$ t& e' l) _ WriteCommandLCM(0x01,1); //显示清屏) V" w3 W4 V7 G
WriteCommandLCM(0x06,1); // 显示光标移动设置+ z/ } z% C! b
WriteCommandLCM(0x0F,1); // 显示开及光标设置' G. Q" J O+ a$ w
}
: F* h. c8 @5 p5 n# j+ G- L. X
+ f- q; P! {! ~1 r% n//按指定位置显示一个字符6 E" G6 x" E- o8 u& {+ f
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
7 \+ w/ o, c6 N7 ]2 z* q+ H8 z{6 Y) l" k" l( J
Y &= 0x1;) L1 @% |8 ?$ n+ _/ e
X &= 0xF; //限制X不能大于15,Y不能大于14 g/ K( b0 ?* i
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;2 Z* g1 F0 G" k) t
X |= 0x80; //算出指令码
: d1 Z& i" }5 J+ u; m WriteCommandLCM(X, 1); //发命令字
4 G/ b+ `3 s: e) Z. V3 S3 `8 ^ WriteDataLCM(DData); //发数据
) d# c6 H) A7 x" C, m}( L( R* o, E' _" W- j
5 v( H D! t5 E% Q//按指定位置显示一串字符
# h r$ q# t; ^! |+ ~4 v, yvoid DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)0 I% C0 B# i4 W* ?
{. o( p* O" }' N$ o6 W
unsigned char ListLength;3 Y! b( K2 s- q9 Y q4 r4 S
) w0 u/ k* V( I( [/ x' p- }
ListLength = 0;
- F9 J0 \# p& u- T0 ]6 v' [ Y &= 0x1;
, K7 H' @5 ?* }9 U7 w X &= 0xF; //限制X不能大于15,Y不能大于1
2 k3 |# C/ C! i while (DData[ListLength]>0x19) //若到达字串尾则退出
* F7 ^* G- J0 D8 e3 [ { `6 k( Z; k& m2 {* ?
if (X <= 0xF) //X坐标应小于0xF
' r7 x! }" |2 _2 x" L8 Q* a {0 J) y6 z6 q& L2 F8 Z. s
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
, }4 b3 j% C1 W) }" x* Q) u3 e. M3 n+ k: ` ListLength++;! B, M! C9 e9 F; A4 v N' `
X++;
. [) x# f2 h A, d9 q6 E* t K }
$ T0 T, Z( O) m; r4 G }2 |& W- r* `# k# ~/ h; b6 K) J
}
+ W- ^$ M& N; |5 w* A9 S, h- u: [- [2 W D" S
//5ms延时
& k& o+ z% h/ s @& a; \void Delay5Ms(void)
. d- }; N7 u( T" M5 D$ _{1 I1 A6 l" \. }( Q4 h5 M% L
unsigned int TempCyc = 5552;" K; M, D/ o* C! b; `( w' S# B% l
while(TempCyc--);& ]( f! K7 `2 @" y: c6 u: K& k( Y' w3 N
}
( x5 q# c+ |1 X: N4 m/ D0 R$ o8 n% X7 n# ^. C3 I
//400ms延时4 M! O. V; d# T! f
void Delay400Ms(void)* ?* u7 O3 u4 f ]# G; B2 P5 [& e- p
{- M% P k! P, n
unsigned char TempCycA = 5;$ P+ N% J/ H E
unsigned int TempCycB;% z! B: F4 L9 U
while(TempCycA--)" l* f/ K5 J3 ]1 W b8 L- m' w
{
: C# I5 ~& N# ~/ D, `0 q3 a3 V. C TempCycB=7269;
' x8 N- J" z3 O2 `/ f' w* s while(TempCycB--); a+ Y: w/ l# O+ A6 w
};2 [# \3 t2 n: R+ e" ^
}2 r2 @( J; w; A* B& a
/********************************************************/. }; H- m& Y' V+ S
void Conut(void)& A, o0 L# y4 O% |6 Z: q+ N- S1 K
{ P- u W! R' |% u4 w8 E
time=TH0*256+TL0;0 X9 q( i- K" ^* |! V: u8 o6 W
TH0=0;
# `- {' H, O$ p7 P+ b; O TL0=0;8 ~% f1 a' P* a# G+ x% T9 a: \/ g
, W/ [0 {6 R! e* h. y2 {. a# [! v S=(time*1.7)/100; //算出来是CM
]3 ]* D: g6 W% w$ M1 S2 j; c! k- Y7 } if((S>=700)||flag==1) //超出测量范围显示“-”3 h6 H# N1 m" ~) [$ T+ t+ I9 m# U
{ 4 R' ?- B: @& R$ E4 S9 r- V
flag=0;3 \# |) Q, [1 y4 o
+ Z( F6 @$ k, ~7 u4 w DisplayOneChar(0, 1, ASCII[11]);
' `. V! _; A5 s; e7 \ DisplayOneChar(1, 1, ASCII[10]); //显示点
( ^$ R0 m. w* [; m, h DisplayOneChar(2, 1, ASCII[11]);5 o. G5 }$ `: Z6 @) v: G
DisplayOneChar(3, 1, ASCII[11]);
2 @3 i4 o& r7 p; r N% A8 B DisplayOneChar(4, 1, ASCII[12]); //显示M Y3 P- g B$ K. j
}
4 H9 Q7 G2 h. d- S9 S& D5 T else
4 I r( `$ a& w; x, [ {4 s# a! f$ m1 z+ z( x$ a; c: J
disbuff[0]=S%1000/100;
7 X+ `9 H' R! V3 P) ^6 u' b disbuff[1]=S%1000%100/10;
3 t. S0 }/ k4 d* k3 E; R disbuff[2]=S%1000%10 %10;* ]! ? L& z. J. _
DisplayOneChar(0, 1, ASCII[disbuff[0]]);. u5 L5 ?# E& f7 A- u6 c
DisplayOneChar(1, 1, ASCII[10]); //显示点4 E0 r0 b! ^7 P
DisplayOneChar(2, 1, ASCII[disbuff[1]]);* C( P5 @ \, x6 B G1 g$ E: N
DisplayOneChar(3, 1, ASCII[disbuff[2]]);
: F5 G5 }; h6 x% I G' M DisplayOneChar(4, 1, ASCII[12]); //显示M
% K5 k; d. a9 R1 q( u: ^ }7 u: e( P5 W2 t9 E: T3 p, ]' G: u7 z% T
}8 E( }1 A- T& ^$ q) s
/********************************************************/) U0 y6 L0 f, ?, l+ o) M0 a! |- Z
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
I% _8 u+ P) h* o" y! G+ a! M {
' G- a" h- ]' {- T1 o ? flag=1; //中断溢出标志2 Z9 [1 u0 L7 ]) G
}" t* ?7 {7 {- z% {, L0 O# ~
/********************************************************/) q$ M1 B4 N3 L' u
void StartModule() //启动模块
; C6 v, I, {/ N {
$ f5 u. k" \( T C TX=1; //启动一次模块8 R) f& Q+ Q! B
_nop_();
: b+ Y- b! { I x: W( u _nop_();! s9 i" G. N: Z2 H8 D* i
_nop_();
4 w+ m% D0 z: v: e) ? _nop_();
# D( v3 N# W5 Z+ a _nop_();
; @ v% H7 F3 [3 a+ @5 x# ?+ H2 r _nop_();
: c$ N! W0 P( \* w- ^) q! R _nop_();) y# p s2 r g/ \7 F* ~
_nop_();& M9 J6 f2 G% n8 i5 ?) r) e/ m
_nop_();* L+ ~1 X. n0 I$ w5 B2 e% r
_nop_();1 z8 e# @ M" Y- H7 M8 ]0 n* |4 ^, A
_nop_();
" o' e' F/ Z7 r z4 L$ p. t _nop_();) `5 B' Z# f5 z8 w4 x5 P1 \
_nop_();
/ g$ F& t7 _, a; @- g _nop_();& [# v( ^ O/ h, G
_nop_();
( y/ o, ~$ V# a$ w3 u _nop_();$ v. D* I% q5 J
_nop_();* n7 F+ ]6 ?' c4 ^
_nop_();
% x/ b% x- j% t! s8 Y _nop_();
1 g% w: [/ b' W( P2 Q2 N9 m+ K5 ^ _nop_();
: o+ Y' o$ [+ p6 t _nop_();' v# q! [7 ~9 v$ }: A
TX=0;
7 @6 B( B7 P! M9 S5 p }. n! i8 N+ i" Y/ w
/********************************************************/
! v$ w, M8 i J& T- Tvoid delayms(unsigned int ms) ^$ I4 I% r: u+ c
{$ v5 i- C) A) t
unsigned char i=100,j;: e5 R. E8 ]8 R h
for(;ms;ms--)% B# b6 j: K# w- h: F3 ?# M* T
{
+ E- o* E+ H/ e- B+ j# U. P* C while(--i)) `0 a9 n( x7 y3 D
{
9 u! _) f0 E3 P; K5 O j=10;
5 X+ s) `* E& P/ H# o+ i! v2 u- z while(--j);6 S+ P; h: t6 u( [) T f/ v3 x
}* e5 |; l, L7 m0 h* p4 e& b* ~' y
}% l3 T e( m$ _4 w
}2 s5 w' N) s$ Y5 ?
/*********************************************************/, M2 V* ~9 [: K+ K6 d
void main(void)( G$ A/ p( [! o* w" \
{8 }% w6 C) s0 |
unsigned char TempCyc;6 o$ n: ^& k4 J5 N
Delay400Ms(); //启动等待,等LCM讲入工作状态
5 l2 Y* j8 w( P! s- k LCMInit(); //LCM初始化
* [6 N( b$ l$ y. e# u3 }/ w# U4 u Delay5Ms(); //延时片刻(可不要)2 K) J+ D- E6 K
DisplayListChar(0, 0, mcustudio);
" {, h( ?# }6 [; b DisplayListChar(0, 1, email);$ u: w# N! Y$ R3 T
ReadDataLCM();//测试用句无意义
/ [0 t( A, h. a; d6 W for (TempCyc=0; TempCyc<10; TempCyc++)
4 Y- d! }- k9 D% @! y; D8 K Delay400Ms(); //延时
5 j! n& \# q4 O DisplayListChar(0, 1, Cls);
8 g! e1 A$ G/ f& G while(1)+ j; [& T0 V% F& } K4 d& ~5 Y
{3 @, F M& ^: D5 s
TMOD=0x01; //设T0为方式1,GATE=1;$ ^2 p( O& v) o! N- {9 ~4 A- I3 a
TH0=0;/ t( R4 u' o5 V: {
TL0=0;
" D5 i# E' V7 w6 {5 r) j9 C4 d+ b ET0=1; //允许T0中断/ F8 ?4 l \* k
EA=1; //开启总中断
/ t: G5 V5 s8 N4 O
! q& S5 b3 l4 s V& }; P while(1)/ W2 p6 }' H% H( k3 J# y( l: }
{
1 T! w# c" Z L) J" R StartModule();& F) A! t4 ]* o0 Y `
// DisplayOneChar(0, 1, ASCII[0]);
% o D' F: z: T8 E while(!RX); //当RX为零时等待
0 `; h: z. Z0 b3 V* C TR0=1; //开启计数
/ J) k- d6 \1 S# u3 L/ J while(RX); //当RX为1计数并等待* Q- @+ D; S5 ?6 X% E+ a$ I ?
TR0=0; //关闭计数
) X a: J$ U( |3 V$ I* i. E Conut(); //计算/ b8 j% Y" D" I/ t$ u7 y
delayms(80); //80MS F% O, X M% e6 i' f
8 Q3 y' z# Z; s' v8 V1 T7 q }
+ R) J7 ^( ]; v$ a* \& I. f }
* L4 F3 o" E9 K. y& S* I1 q! z}
* u) M7 l8 d3 R: P# v" D
7 T, g1 B: Y% K. O' z- O; m2 z7 U2 @
( d4 z; q1 f V7 a) y |
|