|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
超声波传感器和stc89c51单片机的c语言代码 C:
, i6 Q. D6 h" \( L6 N7 {SMC1602A(16*2)模拟口线接线方式
/ R* h- C- R8 h" E0 b3 ~连接线图: " O6 U. X5 U- m- D( ]' |+ \
---------------------------------------------------
7 |( E" r2 w: Y2 Q2 E |LCM-----51 | LCM-----51 | LCM------51 |
4 ]2 y! ?/ \8 }$ z$ j --------------------------------------------------|
! q" C4 t3 q) b |DB0-----P2.0 | DB4-----P2.4 | RW-------P0.6 |
8 ^9 E# {4 Z, g, N: p& M b |DB1-----P2.1 | DB5-----P2.5 | RS-------P0.7 |4 Z$ M, B. P( N4 S! t- ~
|DB2-----P2.2 | DB6-----P2.6 | E--------P0.5 |1 Q2 S; M3 \. p, B x
|DB3-----P2.3 | DB7-----P2.7 | VLCD接1K电阻到GND|
4 |" P. y1 n8 C$ e. h ---------------------------------------------------+ R) ~( m/ o) ]& _6 P
接线:模块TRIG接 P1.2 ECH0 接P1.10 A) A" r: k# v3 ^7 t; R
8 n" L' T. O. ^/ M9 ^5 Z; d" H
本程序源码只供学习参考,不得应用于商业用途 |
8 P4 J2 L( z0 A5 u' p#include <AT89x51.H> //器件配置文件9 K" R; ~6 [1 j4 ~# r
#include <intrins.h>$ ^1 U- Q- ^( `$ a/ ?* E
#define RX P1_1" r( }. v6 Y o& G2 m% b6 n
#define TX P1_26 q% W3 J4 R: B) a
6 U- H! {% L' X* r. S
#define LCM_RW P0_6 //定义LCD引脚, V& S6 s$ `; n4 ~% X
#define LCM_RS P0_7% Q0 G5 U& ]( r6 B: A
#define LCM_E P0_5
% q: {1 O4 Z i, _6 F4 q% r1 P#define LCM_Data P2
8 z1 B# R% Q& K& \ O- W. b- |* Z5 B" ^
, H2 C( H% V3 d. |+ c#define Busy 0x80 //用于检测LCM状态字中的Busy标识
: h, |% F3 e6 F2 Y; L' |- y2 ]' N
! N% [5 G& ?) E* T9 z+ V" w# avoid LCMInit(void);9 o: p" \: h5 Y- k
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); q3 t, M# ^) g2 F6 S E
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
/ i) s( c! N$ e0 M& avoid Delay5Ms(void);
+ Q$ n; p5 j$ @# J7 J/ Cvoid Delay400Ms(void);; C, U7 Y, K0 @7 V
void Decode(unsigned char ScanCode);
% H) [$ @2 E, P/ k' Y2 fvoid WriteDataLCM(unsigned char WDLCM);9 j- N r! u+ J( w% t
void WriteCommandLCM(unsigned char WCLCM,BuysC);
/ G1 @/ ]3 z n7 w4 E6 Z! u! k* |. J. R" Z; S
unsigned char ReadDataLCM(void);" _/ R: }$ H. b" l+ e5 ^
unsigned char ReadStatusLCM(void);
$ a2 v$ Q q3 c7 k: M6 sunsigned char code mcustudio[] ={" WWW*QXMCU*COM "};, \; J" E" H' K
unsigned char code email[] = {"863888999@QQ.COM"};
/ H/ }) B+ C8 funsigned char code Cls[] = {" "};
$ K; ^% v0 P/ y6 v. D8 Y6 Nunsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M'};
' i% a) T. q7 i2 f8 T) F( @0 X; b& h
static unsigned char DisNum = 0; //显示用指针 & m* J7 } U: }
unsigned int time=0;, _# V0 k7 c6 p0 e3 y' c7 ]
unsigned long S=0;
$ c2 Q5 _8 u V# M bit flag =0;4 W! q, g2 p8 z' U
unsigned char disbuff[4] ={ 0,0,0,0,};- l4 G# {0 C7 r7 P. Q8 l
% P/ L+ q# K: Z" _
5 {' x2 t; m* h# C6 R+ b//写数据+ Q' I. s- o9 l4 }4 g( m2 v. L; v
void WriteDataLCM(unsigned char WDLCM)
& R$ b& @" W* y D c$ @9 J{
6 P4 U v6 k8 k ReadStatusLCM(); //检测忙
: F' H$ ^& j1 z/ H LCM_Data = WDLCM;( h- ^/ o2 g5 j0 h4 A1 x
LCM_RS = 1;9 R& `9 s- |( d- h! H9 w6 L
LCM_RW = 0;6 \7 T! `1 p' ~, ]
LCM_E = 0; //若晶振速度太高可以在这后加小的延时7 g& o) P) b0 P! \$ S z
LCM_E = 0; //延时/ }# |9 j* Q$ n- d0 N
LCM_E = 1;
+ W: k+ p6 ?+ q1 M& Z1 `: k}6 w+ q0 F' F" `. l
0 F7 [. c6 f$ t7 p r1 m
//写指令. Y h/ l; a2 ], M" i9 N# a, f
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
1 Z/ q* v- i4 ]5 ^8 ~5 E{
* n7 c9 q3 n# ?7 B& g5 ]3 v7 D; k if (BuysC) ReadStatusLCM(); //根据需要检测忙; k1 a- F. S/ C4 U
LCM_Data = WCLCM;
. j5 u" Z0 |4 Q9 ` LCM_RS = 0;
" u/ L O/ K# ?- c" ~0 P LCM_RW = 0; $ b4 n! a9 F0 J7 ~
LCM_E = 0;
7 F& b# G9 d6 @) A2 G- R, ^ LCM_E = 0;2 g+ }" X! m( T, X( \+ p) q$ R* R5 g
LCM_E = 1;
3 ^' x8 ?0 o0 [! o1 Z- q}* f9 P2 T* k2 K5 I: @6 r
& R. p9 t' a l& n( N" n/ y//读数据' w$ E; i8 S4 K% C
unsigned char ReadDataLCM(void): o- u! U) m# K% L5 ?
{
3 t: |7 ]$ F# I" s# B LCM_RS = 1;
3 ~% M- R+ s0 X: w- H0 \1 l6 j LCM_RW = 1;8 {) B O8 i( A$ z
LCM_E = 0;
: r) g& V! W# W% _ LCM_E = 0;, Z" d- {( A: p' y2 J. g+ h {
LCM_E = 1;
# ^9 L; X: @% J r return(LCM_Data);3 a* V3 M, ~# W
}
+ K7 M( e9 Q* c* Y/ h+ X# I
: I- `. `* h" E: y6 B$ N2 M) O//读状态7 N+ n0 c2 X* c0 P3 N
unsigned char ReadStatusLCM(void)
/ z9 P5 T4 {& l6 k0 X* ~{
! y; w, Q7 S& p7 ]$ N, C9 r4 O: [ LCM_Data = 0xFF;
$ x/ ]9 q% J4 z; s LCM_RS = 0;& u% ^' d* k+ }" j; n( N& z& d
LCM_RW = 1;
# X; j' _& Z0 A8 i LCM_E = 0;
+ m0 ]( U; M: K6 `# { LCM_E = 0;
% L3 a k" f9 ?4 s, { LCM_E = 1;
' q+ W$ o7 D, T2 {6 A1 L while (LCM_Data & Busy); //检测忙信号
Z6 I5 w; r/ T6 S8 p' C return(LCM_Data);. D9 K$ T/ e4 o/ x+ s$ A- V
}- K1 C( ]& z% ^' q6 P/ Z, ~" [
" T: Y9 u& k) m6 F$ o% N% A
void LCMInit(void) //LCM初始化
1 r: p& o! P3 `{
. o, ?( a& q- J. U LCM_Data = 0;
1 J' a4 [9 ~2 B WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号; j! ~" e. T' F% j
Delay5Ms();
9 a( k4 b) E8 Z7 @6 O, H WriteCommandLCM(0x38,0);
. E! F$ N' N F$ c4 w/ P, Z Delay5Ms();9 K: |" ~% o% y, r# F
WriteCommandLCM(0x38,0);
+ c; b9 o/ Y+ Z0 t# ]' V9 B& y Delay5Ms();7 }$ a7 w8 H# U& `5 F
1 U$ L- [9 F# \% C0 f WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号# X5 @3 A$ D7 D" z; U S: ]- K% E
WriteCommandLCM(0x08,1); //关闭显示! u C4 S4 Z4 `. @2 i: r' p1 |
WriteCommandLCM(0x01,1); //显示清屏
4 L3 f' C8 S) v! C WriteCommandLCM(0x06,1); // 显示光标移动设置
3 t4 S4 c$ @7 P WriteCommandLCM(0x0F,1); // 显示开及光标设置
" i$ a& g& W2 ] t6 V}6 p9 Z2 Y0 C; x, {3 b- h
' W6 r" W/ ^9 H1 H0 p6 W# o+ i4 M//按指定位置显示一个字符
& c* ^& D6 g8 @/ m3 l8 O: u8 X5 Cvoid DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
( }. ~/ l" T- E4 b0 f9 I{/ \4 M+ t/ e% w6 A k
Y &= 0x1;
, A; }- V; \( k# t/ H1 i X &= 0xF; //限制X不能大于15,Y不能大于1+ @. I* t. C# D8 K: V- v) m
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
$ T/ Q! w1 P |& ~ X |= 0x80; //算出指令码
& v3 f G$ D' p, w Z; K8 Z7 [ WriteCommandLCM(X, 1); //发命令字
$ ?2 w. z1 a/ q- o1 \3 W7 r WriteDataLCM(DData); //发数据
4 E, e2 Z, _3 u; F# R}5 W/ q- t4 b8 m }
3 C/ |/ r9 C% G+ ]3 s- B1 R. e/ g+ g! m
//按指定位置显示一串字符
6 C4 P# G0 U% }, U: F- w8 Wvoid DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)' I. ] P; S9 p$ K9 N
{$ E) |: B) h/ K7 ]" q
unsigned char ListLength;
% g+ Q- q7 B: j! r; k7 \7 \% R
ListLength = 0;2 D. {* j" b5 Y; H# j
Y &= 0x1;
* P0 A( w. r5 g4 f3 v& R- ? X &= 0xF; //限制X不能大于15,Y不能大于1
8 U/ O# _2 K& y while (DData[ListLength]>0x19) //若到达字串尾则退出
! I8 W) i% Z$ o! N$ g {/ F3 [. d3 O% t$ V* {5 V# j- q6 H
if (X <= 0xF) //X坐标应小于0xF& m4 K/ @! G% T K, Z
{
$ }. G4 d8 u1 E6 ] DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符: E# m/ L7 s% ~6 b+ r* a8 W
ListLength++;
/ M" T i( Q- h% X+ U' x& t. D X++;
/ \( m% I9 A9 I( ~2 _5 L! U# W' M }6 ]& h! c0 \+ @# q
}) |" r l$ u( t7 r1 u7 \3 S
}
% e" @, c3 x) n$ \0 i7 }0 a" M0 W+ |3 T2 J3 u5 N' y) h `
//5ms延时
2 b# y. h: A- h% gvoid Delay5Ms(void), h8 e6 T$ S3 k& ^
{! X* S: @( C# E* G, {( C
unsigned int TempCyc = 5552;
: l" r1 v0 w9 z' y2 U; L9 q" M while(TempCyc--);
- `' L1 o' X, J" @}. P: H$ C9 b1 d
O# p% v2 y2 V4 D//400ms延时1 y/ m. {( Q/ \: F n
void Delay400Ms(void): k, w' c: |& p0 ~5 T9 e
{! B% c9 }, }$ t3 I- f8 n; }
unsigned char TempCycA = 5;
" n0 Z" |6 S- Q$ E- w2 [/ X- |" Q& Z unsigned int TempCycB;
3 R8 K- `2 w" L1 a while(TempCycA--)
1 L& e1 L! B' O4 U) B7 N. u {, }# b0 N0 R: }
TempCycB=7269;& g! V/ C0 E' Z+ w' ]7 `) L3 A5 h
while(TempCycB--);& H+ [- G) V( f4 h8 _; ^; |
};
: O/ E" G( S w8 z2 i0 |}
4 ?( O( `1 J, \5 O/********************************************************/
: h3 M; b! I/ F* } void Conut(void)( Q- Q/ R# c* u# ~
{% P$ O4 k+ a, L. B" i% D6 `" m
time=TH0*256+TL0;4 J# G: C9 T7 b# p k3 a
TH0=0;
+ l& S) f( ?. G- F1 v1 A TL0=0;2 V0 i5 I$ K5 {
' y7 `3 B* r- u3 q0 m( n/ F& W: P
S=(time*1.7)/100; //算出来是CM
4 F& w0 [! |6 A$ a0 g/ c j if((S>=700)||flag==1) //超出测量范围显示“-”
1 J) @; c. ?! E/ [& E3 G' \ { 7 O' v0 ^* R# j- t; m" E6 g+ o
flag=0;
0 {( G( k& O! n; U/ t5 ~+ g+ q' |+ [' w' g3 @1 T
DisplayOneChar(0, 1, ASCII[11]);/ ], V( l q* k/ W5 W
DisplayOneChar(1, 1, ASCII[10]); //显示点
4 n1 @ p4 l/ @7 h, w4 H DisplayOneChar(2, 1, ASCII[11]);
$ z! {" V! F1 i2 F DisplayOneChar(3, 1, ASCII[11]);
" B- I1 L$ v6 D: \- @2 R6 A DisplayOneChar(4, 1, ASCII[12]); //显示M
5 ^( ^1 O! E" A5 t" K1 t) T }
c. d4 \* c! _. Q+ J+ x$ _2 j" x else+ r5 v8 [$ V: U( q7 `" r
{6 Y0 c. s- d1 G/ ]; d- |* @8 Z
disbuff[0]=S%1000/100;7 A+ x. |1 ]/ ^( p) M0 q& |
disbuff[1]=S%1000%100/10;
I4 G; r" A& _3 ^# u9 m/ U" S' D8 ~ disbuff[2]=S%1000%10 %10;
9 s" S3 I% v0 ^$ l ? DisplayOneChar(0, 1, ASCII[disbuff[0]]);7 b2 V9 ]: k+ W& W5 E
DisplayOneChar(1, 1, ASCII[10]); //显示点& N4 T" s1 O9 d# o
DisplayOneChar(2, 1, ASCII[disbuff[1]]);
9 s! A4 T. r& l' O4 w DisplayOneChar(3, 1, ASCII[disbuff[2]]);3 }7 u3 X" a% G% k1 R* s- o( L- [
DisplayOneChar(4, 1, ASCII[12]); //显示M" d6 _* p: j$ | f! S' h
}3 W9 R; [( N% w$ B: s n4 R
}; |& C5 s) n: S
/********************************************************/0 i2 J- ^/ P# u V+ t" j D
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围3 ?9 w, C' c2 N2 D% b
{
; l3 d5 C; d/ W3 T! x flag=1; //中断溢出标志4 H( K+ v: h3 E" e/ P
}
# J/ I) @7 l4 e# r7 @/********************************************************/
8 e5 ~/ V# b' w7 _9 L void StartModule() //启动模块# p+ ]2 m" _( |/ t3 r5 c8 Z
{
! K$ u0 w# V, Q9 Z, l# G3 y W! i TX=1; //启动一次模块; n$ N: J0 `! f i" P3 W) g
_nop_();
# j& A! s# R8 S z8 W+ r _nop_();
6 e$ i0 X/ ^( c5 }9 T _nop_();
7 g- ~& j/ K) `/ e _nop_();% ?1 M, q+ x8 B Z" Y
_nop_();0 i/ k/ e3 c8 m: j; t5 a6 r
_nop_();5 q9 Z) a! l2 }! e
_nop_();/ R1 D" O0 v b& H" C4 y
_nop_();$ b) g3 `1 n8 F" a ^
_nop_();
$ ? z1 r% \# G, ~+ r. Y# h _nop_();
4 x5 N) ?, W+ p0 e& e. o# _0 W _nop_();$ b" l3 t# w9 [) d; T, Z
_nop_();& z$ v- C- V1 t; w4 K3 c
_nop_(); O* S! k; x1 d: Z. I
_nop_();+ r! _% ^/ m. i
_nop_();- z4 r! {& m2 S. o( H N- w# J2 ?* I6 X
_nop_();5 K, ]' [% y# {$ N+ C( H
_nop_();0 u0 Q/ g6 N; i2 w4 i5 @* |
_nop_();
( p* F: l. H7 J( ~7 ^" ~" V8 Y _nop_();( {+ [0 T% s1 D6 c
_nop_();
( p$ B; M/ Y w0 x" p7 E& ] _nop_();
' z$ i9 c, t4 |5 s u TX=0;& U% w% S; J2 D1 t
}
" \. n3 \9 I% t/********************************************************/* H. ]) J+ s8 |) s- D) m1 F: f% p5 [
void delayms(unsigned int ms)
0 }% n. T- U- ^+ [% _+ a9 l( L{1 ^9 x: {& d6 T4 r/ _$ \& ^5 {
unsigned char i=100,j;8 K3 h G O( y4 K5 k: G- @$ D1 i! f3 j
for(;ms;ms--)% B# Q: r) a/ n6 R. X
{) {0 c' E2 u! x S3 l% x% V
while(--i)4 F ~1 Z& u; K) P. z
{
2 f$ A8 E6 X' ~6 ^" G8 f. K j=10;
( E( ?& P3 B! ? while(--j);- F8 l# H8 o7 f
}
! t5 r* X: k8 R }
+ l! \1 s- A3 H V# Z. D' b1 x; @9 w4 L" x}) z m, h) q! h- ^! A8 G
/*********************************************************/9 [, c* H8 i) o) f
void main(void)
6 f! Q0 D3 I4 W. f( q5 A& E3 m$ u6 m{
/ y3 r! c/ Z. _5 ?; o! v0 `2 w6 l# { unsigned char TempCyc;8 \6 T7 m% y2 A% }3 e+ N0 F
Delay400Ms(); //启动等待,等LCM讲入工作状态
- v) y6 | c+ F8 n LCMInit(); //LCM初始化
( b4 X8 c/ u4 k) }2 ~5 I Delay5Ms(); //延时片刻(可不要)9 D1 J5 z/ N1 w5 u7 p
DisplayListChar(0, 0, mcustudio);
, i7 k' T8 M* C/ f DisplayListChar(0, 1, email);
+ r( h9 X- }: L. z8 N( K- M: U q ReadDataLCM();//测试用句无意义
7 T, J* Z( a+ y, b for (TempCyc=0; TempCyc<10; TempCyc++)
; c l. v9 g; j Delay400Ms(); //延时 X+ |" ?2 H. U
DisplayListChar(0, 1, Cls); 6 A) O/ @0 l* a9 ]8 N
while(1)
8 s z; Z9 c% i5 z) b! n {
: W$ `) p% u& C+ D, c! p TMOD=0x01; //设T0为方式1,GATE=1;
# I& M" P w# Q. [* a: S1 U# J TH0=0;
5 }$ `% _, J M' {4 w TL0=0; 8 F- y! [: u2 h( v3 s
ET0=1; //允许T0中断: k* e; ^. T- z. b* c
EA=1; //开启总中断 3 l: k+ Z" y3 }- h+ x! x
, b' r) O- J$ V' M" B7 B( \/ ~
while(1)" z. N# S7 t- d/ M. N- {
{2 v' z7 L5 V& f2 V2 L9 ^2 }2 u
StartModule();0 A4 z. g5 U# }$ l8 G) b+ l" T F
// DisplayOneChar(0, 1, ASCII[0]);
8 C5 M+ |7 w2 i! ?- ?4 W# w while(!RX); //当RX为零时等待
2 O( T) i! Z7 d. r- \ TR0=1; //开启计数# m; B3 j: }+ R7 k0 ]
while(RX); //当RX为1计数并等待
; e( M. l' m# c! t. V# q( w TR0=0; //关闭计数2 D$ J1 u" g# ]- E! d& m
Conut(); //计算
% c; [2 F7 P8 p delayms(80); //80MS
, p/ F( C/ b, s& K' T3 H4 G9 K. `* v
}! z2 S! p y- l) \4 B. P9 q) I
}
; Y4 \3 @9 n; E+ C2 S}( {* V' W0 o" d" ^
. ~, n7 G6 |0 b. L: b9 M
9 n- O' G/ a% ~/ e( S$ e
* h0 m3 B9 F1 |2 q |
|