设为首页收藏本站|繁體中文 快速切换版块

 找回密码
 立即加入
搜索
查看: 1316|回复: 0

[讨论] 一个超声波测距的程序源码(和大家分享一下)

[复制链接]

该用户从未签到

尚未签到

发表于 2010-11-2 18:12:11 | 显示全部楼层 |阅读模式

马上加入,结交更多好友,共享更多资料,让你轻松玩转电力研学社区!

您需要 登录 才可以下载或查看,没有账号?立即加入

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。1 b2 G. P6 b- r) s
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。
' x3 T( V, q% a8 J液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。; u" \' d  [: h' t0 X( o7 b
超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。
- m4 @5 p& k4 _# C超声波的接收电路包含一块CD40106处理芯片。
9 ?9 c' s; A$ L! B$ r$ ?技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。
1 ?6 Y& g( c6 t6 H8 U/ q#include<reg51.h>' o) w, e; D) `; h: B
#include <intrins.h>- g) J6 X$ p0 _4 b: v; A
#define Busy    0x80  //用于检测LCM状态字中的Busy标识5 R2 q1 ]- c9 ?$ O3 f! s! K$ N$ Q
#define LCM_Data  P0
2 O) T& z& \$ v0 q+ u, \#define uchar unsigned char
- I( U  G7 }: }" `- ^! I0 w+ e& B#define uint  unsigned int
/ @6 w! S( V" x' l6 C#define ulong unsigned long
1 ]! N8 |4 a& z6 e7 I0 j: _" `) H7 a0 k3 l+ f
3 P7 z  H9 j, h
extern void cs_t(void);0 O; @* |! I9 L2 J0 C, D2 E
extern void delay(uint);5 r4 u% p7 f. b- K& ?0 _0 W
/ H4 P1 i$ N& k- q* S; y

# \, T7 M- @+ j3 U4 ]3 \# b9 y0 o" S7 H5 \
void LCMInit(void);
5 q& L- |2 Q, [" t9 xvoid DisplayOneChar(uchar X, uchar Y, uchar DData);8 ~2 P4 u/ `" m' \% Y2 @# a5 f
void DisplayListChar(uchar X, uchar Y, uchar  *DData);
8 F0 w& ]' y+ z7 O3 W1 p8 Ivoid Delay5Ms(void);% ^! s2 _& J+ `7 n5 y- ?
void Delay100Ms(void);) X# G# O3 ]' \

' ]2 v# H# k5 r3 h$ t+ Yvoid WriteDataLCM(uchar WDLCM);  o' `" H3 ]! u+ {9 @* e
void WriteCommandLCM(uchar WCLCM,BuysC);! G/ a4 l/ T+ l# D0 o8 Y

+ [# P8 j! J2 e9 L% g' I
+ L( t* z/ j* [# ]  G9 Q1 t% G5 L& Ndata float distant=0.0;
& D5 f% F, n$ o( Iuchar ReadDataLCM(void);4 F2 Q4 F9 Y& i5 E. `
uchar ReadStatusLCM(void);* |" H3 o& Q5 x+ g" X* Z
uchar  cdle_net[] = {"--Daoche_Leida--"};( `# ?& H6 D4 M$ H5 N1 O# T1 x
uchar  email[] = {"Juli:"};0 V! ^' o1 n7 w: T3 y7 F( o- G* |" ?9 O
uchar  cls[]={"         "};, |% I5 R; r: t) y
uchar DIS[7];
- i; [; y& `; x, |4 e6 h+ idata ulong time;$ J/ }. x3 |- L" A; F, T' V* G& G
float distant;
; y& d1 P- x  R: m' `+ E3 gsbit LCM_RS=P1^1;  //定义LCD引脚0 }% z" V4 r4 i( K* p" M+ E
sbit LCM_RW=P1^2;
3 @9 q6 A" B% z( Z1 l) Hsbit LCM_E=P1^3;
$ y  y# \4 h4 {9 d% rsbit P10=P1^0;
5 ~8 r1 [) }- }8 I- N5 m/ a5 l/ S  O2 [; a1 g0 C3 V

0 R% ^1 f6 ^3 c) q/ vdata uchar flag;
1 Y5 l' @, q/ j! T, M
& [4 t0 Q4 \; ivoid zhuanhuan(float juli)1 D* a/ E: M: K. e
{
( `# F3 H* W3 C; n2 k" Hunsigned long juli1;/ B2 p& r1 S4 x  B( o
juli1=juli*100;
* ?4 q- G( z' T  s' v; p+ p- mDIS[6]=juli1%10+0x30;
2 h* X) \# U4 b" B; \juli1=juli1/10;
& i7 l4 D7 I/ g0 u9 YDIS[5]=juli1%10+0x30;/ k# H2 I5 p3 O3 O/ c4 E( t& r
juli1=juli1/10;3 f0 X1 C! o& `7 L% M% P
DIS[4]='.';
8 g6 S5 T1 G2 R* K, \/ FDIS[3]=juli1%10+0x30;
) B6 B3 ^! p8 X' `: n' h. ?+ ujuli1=juli1/10;% r+ J; e( j; b& ~) ^" ~
DIS[2]=juli1%10+0x30;
$ `# h6 P! ~, vjuli1=juli1/10;) y+ K$ @3 K$ d7 Q
DIS[1]=juli1%10+0x30;
& m0 W; X# d; W; Y% Z5 {4 SDIS[0]=juli1/10+0x30;
3 U5 _3 x% v  [4 X9 J
! E3 s& c# c) i6 \/ v}, D9 T3 R% F& s7 A: {: @; i

9 k/ f. p! I; v4 G! \0 g( @6 x4 Rvoid main(void)/ z1 V  v( E. x, X% n' ]" E' b7 X
{
  `% J2 l7 `1 n) |+ w) j  Z0 u    * f$ o% M8 s7 G/ L3 P
    Delay100Ms(); //启动等待,等LCM讲入工作状态3 I2 H0 Z  v: U: \) c7 G3 r
    P10=1;    6 d7 L1 L. e7 d7 e7 u5 t
    TMOD=0x01;             //计数器0工作在方式1
4 Z* p, t, R: W& C* H    TH0=0;! P* N( k; y% S3 ]
    TL0=0;                  //计数值初始化5 a/ X% B1 R  m0 C( ]
    IT1=0;                 //低电平触发中断# e+ S* V& N( h% R! f
    EA=1;                //开总中断
% U: X. X) B2 E  R" k& @: n4 ~    //IP=0x04;             //设置外部中断1为高优先级中断1 t6 r4 {2 E/ c# W- `5 y5 R
    flag=0;+ ?/ L0 k( v4 [; E% K1 a
    LCMInit(); //LCM初始化- ^  Z" l: q+ ^( Z) W2 O  T4 C
   
' s% H$ m/ L7 _    $ x- ?" V) L, X4 G! ?, e9 @
    while(1)
' U! v7 X' G9 v7 x2 ~6 F/ Y+ E" a    {
' r# T8 n& ^) a     cs_t();# W+ A% n! h. J
     Delay5Ms();        # ?( \% ~. O0 p% n
     ET0=1;         //打开计数器0中断# q) l5 c. H1 d  f' S6 r
     EX1=1;         //打开外部中断1
" S3 z* Q% h- T/ E# N& a+ i     TR0=1;0 e+ N8 P$ ~, v/ U5 S; Z# V
     while(!flag)
: Q7 x/ o; b( R+ P! o  c     {: c6 w5 r) g8 `  M- e" X
      DisplayListChar(0, 0, cdle_net);3 d) x+ h, l! q1 I# `0 R+ p; G
      DisplayListChar(0, 1, email);
; v/ T/ J4 O  [% ]/ A1 @     }7 f) J. u5 G! R2 a/ P; i
     if(flag==1)/ f1 }, }" k0 O
     {
1 x  h, G; A; r1 V+ A4 q! Q      time=TH0;; D6 N- P0 `6 D6 y; \0 L
      time=(time<<8)|TL0;3 r" J( z+ P# y& P2 {1 o
      distant=time*1.72/100;
- F% _0 V9 m. V* L; Z      zhuanhuan(distant);
) M* S  Y1 ?! h9 X8 {1 M      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');
: K; P% g6 s( J3 h: l      else   DisplayOneChar(5,1,DIS[0]);& x3 D  O0 {( l# ?0 y7 e# B5 i7 k
      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');/ F2 L" O* G: K+ d: K! B: B
      else   DisplayOneChar(6,1,DIS[1]);/ i1 j4 r) w9 R- C
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');& k. S4 ~0 W( S* ^' f3 B6 j
      else   DisplayOneChar(7,1,DIS[2]);
( f! W2 c& h, A( m# b      DisplayOneChar(8,1,DIS[3]);8 f* K: @) Q% r8 j0 D9 e: l& l
      DisplayOneChar(9,1,DIS[4]);
$ N0 B6 k( y4 D/ G* Y      DisplayOneChar(10,1,DIS[5]);
) a( |2 F* o  F! n      DisplayOneChar(11,1,DIS[6]);( J# U$ J% x9 o7 M: X8 H
      DisplayOneChar(12,1,'c');" h% b" h! o* `$ n, ?
      DisplayOneChar(13,1,'m');
6 H) {2 G- S& [* r# t! N      flag=0;% K+ K, a0 T  S$ V, u2 u
      }
% O8 H& F- C% D. W8 @     else
; e  I6 t1 ^) f% i+ r6 U3 b     {
8 q8 Q& a5 `/ x      DisplayListChar(5,1,"error!      ");
  n# v+ m# f# k- s) ?      flag=0;
0 J3 c& G9 b) v     }8 p6 X6 S# }$ F% [* O- D+ M
     TH0=0;2 z. C; Z* X8 J$ A7 K$ |9 b
     TL0=0;7 Z5 m; k% c: J
    Delay100Ms();
% H* K( s+ }7 |( o0 d    }
, e4 d0 b$ X4 ^% d/ a. Y8 M7 ?}7 w0 @/ e" P  l  b
5 L2 E& M" Q7 o& ?$ Q" z1 h: x
9 D7 F( j  T2 e
: K4 @3 W8 @& R; f9 f0 {
void cs_r(void) interrupt 2
! M" t0 _* [1 h( Z" k{
4 f1 @% }+ l$ N) i- w& F, iTR0=0;" t) R5 Q7 w) P
EX1=0;: I3 a2 y  f) h8 y- W2 E3 h
ET0=0;
! f  @6 [, P! Q. Q6 S# U6 c) Xflag=1;' j4 J+ ?8 ~" d
}
8 K5 [  a" f$ x  G
, O2 h6 M4 D6 u% u) X5 {0 o  B* A5 n5 J/ H, V4 r( O
void overtime(void) interrupt 10 b' \7 o/ F. _5 ~! f8 y  _; E
{
5 C3 p, M4 e  F6 jEX1=0;* N% ^& X* _9 [: r
TR0=0;) Y5 Z: r/ _) U4 O* B1 M; H0 O
ET0=0;
- u" ~( x; c! E8 z. G- h* ]' M/ Uflag=2;
& a* E) m' ~- @2 m; R}
, |8 Z! n" @/ O+ p6 J; A  k; d) j% K8 Q5 s
% G- I& W! q* q$ i9 ~
//写数据
# B: ?' _, F0 ?& h9 Dvoid WriteDataLCM(uchar WDLCM)
0 Z% Y; x; L) U{
  v8 e% t0 F; g; U    ReadStatusLCM(); //检测忙
* W. K* Y# ?) v    LCM_Data=WDLCM;
& H8 Q9 R! Q) Q  B$ J& c# x6 \    LCM_RS=1;( D* {" v# U+ K9 G0 A6 J
    LCM_RW=0;
& N3 R$ P! E% K: F. n    LCM_E=0; //若晶振速度太高可以在这后加小的延时% q- S) ?; p! |" q* p
    LCM_E=0; //延时3 `  M) [: F/ r. Y
    LCM_E=1;
, I) C1 u4 j( Q( E1 J  a1 f}5 D7 p8 m) M6 Q- s5 J, w

" R, n) }; Z4 V- h//写指令/ H+ J  |" U& o0 u
void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测/ }. s) _1 E- s- p  A
{9 J3 p  A3 ^! Q0 R6 k
    if (BuysC) ReadStatusLCM(); //根据需要检测忙9 w& `6 P' ^6 c/ d- U: t) a) l
    LCM_Data = WCLCM;
; g" @3 Q: ?' Q5 B6 C    LCM_RS = 0;! A, H/ x4 k% a& N! X1 w4 u
    LCM_RW = 0;    $ g- n1 o" o1 J
    LCM_E = 0;* V4 {1 r: s$ [2 C1 }2 b
    LCM_E = 0;
) ~  c( U2 j6 ]4 s- v( F& L! j  q    LCM_E = 1;    " Q5 b9 _. _- }( o" N
}# G0 u/ u6 y' J

8 @% M& a+ N7 i0 z/ G- i//读数据) s  F; e2 M1 c9 I6 k# H! z
uchar ReadDataLCM(void)* ]6 x" T1 g& [  G
{
# S- R; V+ \, A/ |- a    LCM_RS = 1;
( Q  m6 k+ m. m) D% Y    LCM_RW = 1;( k7 I9 `1 j& e( G- d
    LCM_E = 0;6 Q: u* |1 ~+ g4 j! i8 P
    LCM_E = 0;, j$ b9 w9 D9 Y
    LCM_E = 1;
0 Y9 r6 x* I- r7 f5 O8 V' ^. f    return(LCM_Data);1 |  b) \# a( O) q
}
  L4 o2 t% a6 M! ]  m( s( D) n! r( p% y3 j, v, B, w5 \7 J: K2 e
//读状态
6 k; V" p7 S3 T6 d8 s+ X' Zuchar ReadStatusLCM(void)/ ~* ]# |( \; h9 z% `, C. ]
{- t1 T, _, u" g% }  z0 g
    LCM_Data=0xFF;
6 q' c3 K, b3 S, o3 ^    LCM_RS=0;
# W5 q9 j( B8 c( y+ _    LCM_RW=1;
( `0 y6 {5 R9 h% s+ C7 S    LCM_E=0;
9 B6 \: g  j* b4 g( D  P' \4 W& |    LCM_E=0;
# ^; \, z& ^' @3 F. W6 {  G+ p+ |    LCM_E=1;
; @* c. a- c2 N  f9 b+ `- }    while(LCM_Data & Busy); //检测忙信号9 S, w; }5 p2 p+ u  e* z1 n6 [
    return(LCM_Data);
7 u- P- l0 d& y  S" `' u! D/ R}
- T6 V7 K# l% H, m4 V2 i$ m7 I2 v$ ]" z' z5 _7 y
void LCMInit(void) //LCM初始化
' |2 }1 q. {% Y0 w! \{
( z% a3 h" u) v; V    LCM_Data=0;; e  i7 Z5 `  M* P4 h4 G
    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
/ g$ ?. i% n% _, ]/ J% s8 \    Delay5Ms(); ) Y% L' [8 i) [* P0 S
    WriteCommandLCM(0x38,0);
; c/ J8 \: |4 i$ x    Delay5Ms();
& B7 L2 I7 Z* @% o    WriteCommandLCM(0x38,0);# V4 f) |" H5 a* ^! X" Y* _& i6 |
    Delay5Ms();
1 F. K: m3 y/ G8 o4 F) M( a# v6 I
* R  E1 v2 _2 k) m; ?7 B, o    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号2 z$ k( ~0 |6 r$ K& U9 _
    WriteCommandLCM(0x08,1); //关闭显示: |, y7 Q0 E. \* ?) J9 v, h
    WriteCommandLCM(0x01,1); //显示清屏7 ?$ s. n6 C) F* N7 S7 f6 j/ m9 \
    WriteCommandLCM(0x06,1); // 显示光标移动设置9 n6 M3 D8 v2 i/ A, w1 M
    WriteCommandLCM(0x0F,1); // 显示开及光标设置
9 Z5 F3 g# f5 ?( v; S' K0 U}
6 }( [  ]$ k0 X: G5 _. R7 ?/ Y
$ t' {! l* p) x: i7 L+ l& n4 {//按指定位置显示一个字符1 {' z& q/ g9 [8 i" v7 H
void DisplayOneChar(uchar X, uchar Y, uchar DData)
: S+ u  v  O" M! I) U. o{* `6 W  `& x; m" K
    Y &= 0x1;+ ?9 E2 C* K- g
    X &= 0xF; //限制X不能大于15,Y不能大于1
5 ?5 U+ a" a8 N0 X    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
9 k- @% D" U3 g    X |= 0x80; //算出指令码
& y% U/ _% ?5 x* m6 ?* y    WriteCommandLCM(X, 1); //发命令字+ o6 ?, c1 ?3 k% C& j3 \
    WriteDataLCM(DData); //发数据
" O* d" t% W% Q& T7 a5 L3 f( s: M" x}
: ~! Y0 ?1 ^: f! v% @4 y- U
2 }* m0 X3 u2 B3 Z9 r//按指定位置显示一串字符
1 o/ M- H8 e' b# P3 ?+ g  ]$ Kvoid DisplayListChar(uchar X, uchar Y, uchar  *DData). u! [* b3 a" S. E
{
5 c7 I$ L' k8 ?7 u; v: u    uchar ListLength;. E# f& _- s% _0 k: l- N
' G" D. f5 V7 e
  ListLength = 0;
, C% b. v1 ~7 u% ?4 e+ r9 t/ e: y; M    Y &= 0x1;
5 ?5 c: k) Y5 W! r- V    X &= 0xF; //限制X不能大于15,Y不能大于1
* v( O" t: _' l  r    while (DData[ListLength]>0x20) //若到达字串尾则退出" t0 G3 i8 U9 r' ?5 f, ~
        {
9 j9 K8 `- D% ], y4 H2 u+ P            if (X <= 0xF) //X坐标应小于0xF  f3 F$ D+ B- k3 t# K5 C5 c
                {
* {: v0 u- Y2 z/ W7 p* s0 |                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
6 @8 g9 U1 V0 o3 v+ c( \8 F* f& e                    ListLength++;. ]! s5 v+ Y! H0 y6 ~
                    X++;* i# T. P# {. [' Q  O/ g
                }
, i1 s" `7 [) n$ n        }8 f* g) U: B% R& j  c$ _) E
}7 C5 V7 E, Q4 I5 h0 w8 z7 @/ o) {, n
' b2 I1 ?- C( r/ L3 f& Q' f1 p
//5ms延时! P7 r1 G1 r8 _/ ]; ~5 S# _
void Delay5Ms(void)
" I" ?3 j9 S* h5 e( h3 P+ b$ h& Z{
/ J0 M% {# c9 }/ K: o3 c    uint TempCyc = 200;2 a* s, T/ K$ a4 D/ l( q" L
    while(TempCyc--);9 Q+ U- Q* S% ?9 C9 p+ U: l6 L
}- S& K) C( [$ G4 f
. m4 I$ e6 o$ W( }8 L
//400ms延时
6 z  e1 m3 e$ _8 |7 `void Delay100Ms(void)
$ r' W5 ?- }9 k{$ T- ~0 {4 n2 D3 N6 ?5 _" C) y+ W% E
    uchar TempCycA = 1;+ h  t$ Q' R/ d" O8 M
    uint TempCycB;; u. o; w- o* X" m5 O) P# n
    while(TempCycA--)! {4 M* a; |  U! p2 k
        {0 T' d) w( v" Y! X* L2 @; S9 n
            TempCycB=7269;
& s2 }. v/ y9 ^5 U7 K! Y            while(TempCycB--);
& ?) L4 T) c% j1 y* W! R6 m+ d        }3 U4 \: g) |( e  K( i$ e: f. c: Z* J
}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

小黑屋|手机版|APP下载(beta)|Archiver|电力研学网 ( 赣ICP备12000811号-1|赣公网安备36040302000210号 )|网站地图

GMT+8, 2026-3-19 09:33

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表