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

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

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

[复制链接]

该用户从未签到

尚未签到

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

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

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

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。
$ \, O6 H" ]; R硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。2 ]. Z* z! U; `- o1 p" X
液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。. d$ @+ k2 l, |: F+ }# a2 e2 `; [
超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。/ }7 [5 j# c7 p4 i7 l
超声波的接收电路包含一块CD40106处理芯片。8 y1 ^$ L& R. ?0 u+ E2 p" D
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。$ U: s% {/ c, g5 F2 `* G. g
#include<reg51.h>* }) N5 V, Q" j+ p+ v
#include <intrins.h>0 _; M3 Z  l7 }" U) B9 t
#define Busy    0x80  //用于检测LCM状态字中的Busy标识
% T& _1 C- u' ^8 s, O, P4 d) ?1 c) ^#define LCM_Data  P0
' a+ R! v6 T5 o2 h#define uchar unsigned char2 `& x3 k) r9 V$ k4 }
#define uint  unsigned int6 N1 [3 B4 x! K0 S: A
#define ulong unsigned long
* V5 V$ o9 e* t! z/ m2 W
6 s7 i8 p- Z) A3 u% r; r
# @9 f) A9 Z' |& j* j9 Iextern void cs_t(void);
6 p0 R8 b, o% i) e$ y4 textern void delay(uint);
9 r+ v! g8 |; Z% |7 [4 h8 V% r/ a1 ^9 u$ G

/ f' ]7 w1 X0 d8 d* o* T5 J
0 b9 f' L4 o: Y$ Evoid LCMInit(void);
2 t. c  F8 V- k. a3 qvoid DisplayOneChar(uchar X, uchar Y, uchar DData);
" r2 a0 \2 N6 m5 g- c1 j# X! }  w+ [void DisplayListChar(uchar X, uchar Y, uchar  *DData);
% l$ u- v2 }( h* Q- evoid Delay5Ms(void);6 r6 v8 O# d% ^# z6 M) }3 l. J
void Delay100Ms(void);
  z# c# T6 T' S1 _& h' a  N/ Y( Q, Y* P/ D' V2 M3 W0 A
void WriteDataLCM(uchar WDLCM);# Y- }% p! V+ V  g- d: s
void WriteCommandLCM(uchar WCLCM,BuysC);
6 `- X1 C; v3 n* n: G
9 g* X3 E8 n% ^2 N
. C. u8 d8 o# p) d1 J2 z9 Adata float distant=0.0;! W" w8 K+ L6 {  ^7 v: s# e
uchar ReadDataLCM(void);
6 p* p) T0 H" Q$ f) suchar ReadStatusLCM(void);
, t: c- G. V3 D6 tuchar  cdle_net[] = {"--Daoche_Leida--"};
: P: u; w/ n- M2 T4 g8 b. d: G$ @uchar  email[] = {"Juli:"};' S" }, F: d$ m& v
uchar  cls[]={"         "};
) j1 p: z8 M# R1 i9 o$ X) k$ C4 Ouchar DIS[7];
. {' S$ d* a1 z/ L6 \7 E, ?; ]data ulong time;) h0 S, ?- [, e$ O7 z
float distant;
$ i; l# F) U8 u7 B! z' Ksbit LCM_RS=P1^1;  //定义LCD引脚
# O* N; x. P( F& Bsbit LCM_RW=P1^2; 9 l8 q' @+ `3 I0 V% [
sbit LCM_E=P1^3;
* W5 H6 |  p/ F9 B. \9 B' O+ E! msbit P10=P1^0;
& ?' x2 f! l) ^& }6 k# D: N! R0 u2 M3 e9 a( [+ Z0 g% u: v9 x: g

5 ]* d& N4 f( a  Z$ Bdata uchar flag;; t4 p0 H' H- i9 F

  }. H2 F* W4 u, [void zhuanhuan(float juli)
+ M" g( ^( a4 F/ ?{9 H* j! D! i* Z2 o" p# W
unsigned long juli1;/ u6 E& `4 b) N5 S# l6 N
juli1=juli*100;' G+ O  v" B& M4 e3 k% O
DIS[6]=juli1%10+0x30;
8 f3 r$ {; {) t  f7 V, [' v8 Ejuli1=juli1/10;  f  E. m) K! s! w
DIS[5]=juli1%10+0x30;) ?; n, k: P$ s+ M
juli1=juli1/10;
$ N: [, f: Z8 `; D8 K1 B9 R8 zDIS[4]='.';
/ n  c& }! [+ a! V; LDIS[3]=juli1%10+0x30;
/ H3 t; A1 o) N% e' a! a/ \juli1=juli1/10;
/ T6 i% e7 l/ F$ S: k) lDIS[2]=juli1%10+0x30;1 o$ Z# A6 w* f& z4 j8 @) a
juli1=juli1/10;
' G0 e$ H* f9 j  t4 |5 n0 JDIS[1]=juli1%10+0x30;
3 w& j+ |7 B+ Z  b* SDIS[0]=juli1/10+0x30;9 l/ h. U7 m; f  r) `; e" t
' R9 r0 e1 b/ G$ R& I7 I
}
8 Q+ u2 E2 j8 n# F7 R* ?' z0 K7 D& K0 V
void main(void)4 o# T$ s  @2 s
{' f7 M$ |3 ?7 J" E
    2 `6 k6 I: ~$ N6 ^" h  r
    Delay100Ms(); //启动等待,等LCM讲入工作状态  i5 I! n/ ?1 E$ c5 m* l: n- G
    P10=1;   
3 O& B3 N3 A$ _    TMOD=0x01;             //计数器0工作在方式15 e: P( d$ q! i# A" x, O/ y
    TH0=0;% V' w9 H/ n( ]+ h/ _5 t( p4 p( _* X
    TL0=0;                  //计数值初始化
7 {: W; j  k. t* H    IT1=0;                 //低电平触发中断
- M' s3 t' Y& V6 Q9 w) ?" C    EA=1;                //开总中断3 d- d& q& L: }( c- k; c1 V; l6 T
    //IP=0x04;             //设置外部中断1为高优先级中断; {$ V, D" l( B! ?, a
    flag=0;5 y0 R( M1 I6 \! a) K6 r; m; ^4 `
    LCMInit(); //LCM初始化2 q5 ?, b* I' u1 b! H' G
    : E' J2 b  [+ q3 J( e- t+ C( Z# D
   
4 z  z3 m9 `8 \" V4 I    while(1)
4 M0 {+ n* `2 E    {6 n: T" `5 S5 ]. P) b9 @
     cs_t();
& B% b7 j1 q; U) C/ S9 C- q0 ~     Delay5Ms();        
- Z+ [3 d* c4 E: O* G# ?     ET0=1;         //打开计数器0中断
' d$ L& s& F2 k0 s     EX1=1;         //打开外部中断16 m' r( ^: F- r
     TR0=1;
6 c# D7 D8 D2 W! |! m     while(!flag)
; X9 _/ W6 k% _% j! A     {
( Y9 f4 f. L* [4 d7 @2 }8 h      DisplayListChar(0, 0, cdle_net);+ m& a& f9 Q* J6 B# J
      DisplayListChar(0, 1, email);0 F/ J* T& A3 t' u. m2 K: H
     }% G8 t. T* h/ x& x) y! m7 J& Y
     if(flag==1)
3 Q8 G# S0 d- ^7 E+ L# I% L     {* z7 s6 T+ M& |
      time=TH0;" ]2 ~3 K# i; d
      time=(time<<8)|TL0;% p, Z3 [5 R4 n4 M
      distant=time*1.72/100;* P6 K8 u3 ^' q5 t" b
      zhuanhuan(distant);
$ P) r  n7 x! I5 T$ ]/ @, [& b- ~& R      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');
/ \  m( f/ `2 ~& w/ y      else   DisplayOneChar(5,1,DIS[0]);
6 ~! @. A" N' p: ]8 ^5 I      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');  D  f5 F/ A5 r& y7 o6 J& H
      else   DisplayOneChar(6,1,DIS[1]);; Y0 [& H. Y0 s" j
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');: w2 f  O1 `9 _1 R/ Q# m1 `
      else   DisplayOneChar(7,1,DIS[2]);
- p0 `+ v% Z& B. V( H. V      DisplayOneChar(8,1,DIS[3]);
4 ]; B4 H& b- n1 `) M7 C      DisplayOneChar(9,1,DIS[4]);
' L9 O" b4 ]& Q! s/ }( @      DisplayOneChar(10,1,DIS[5]);1 k! O1 d+ ?) E1 O* E( v& A
      DisplayOneChar(11,1,DIS[6]);/ [% k- v+ O* e1 u- W
      DisplayOneChar(12,1,'c');
6 S% ]' Y0 d: x. L# s      DisplayOneChar(13,1,'m');- A0 G, H) d# \
      flag=0;
$ a+ e7 ^, w& i6 k% z5 Z, _7 `; Y9 u      }
4 K, N2 W' _0 |9 e- ]6 G2 Y     else
1 w; W! I7 m8 h" O1 B     {* S$ h+ F$ ^  M, I3 ^
      DisplayListChar(5,1,"error!      ");* j- a. G  K0 n: z0 u+ M' y, l+ \. |
      flag=0;
! G7 ]6 @9 Y! ^* [% }: J/ e; m     }. h' a+ ~# ^3 {4 R- ~
     TH0=0;; ^/ W' N' ]+ g* b% a
     TL0=0;
. @* ?( x; Z& A  ~* d- R* r8 F& x  z    Delay100Ms();' K& l  [# ^! D; I, ^7 z3 ?2 f
    }
1 \4 D4 v6 ]- |) B! d, I6 N% d}3 y6 X7 N- i5 A" w4 j5 y
. _) f0 R$ R! ^
: E# p: I- j; \1 F" }" m9 }9 O3 I9 I

3 \7 u: M4 }9 w4 g( \5 ~6 C: Mvoid cs_r(void) interrupt 2
' M! k* T3 q+ F0 F: X8 I{
" j- ]# D/ `3 q$ d$ N; zTR0=0;
8 f9 }6 v* l% X, ]" u. fEX1=0;/ b3 \& s6 o1 H' A/ U
ET0=0;
8 i# t; q. @2 K( i! @9 Bflag=1;
) c+ l' k, q; n, X8 g- S5 U}2 m4 u7 b3 {1 w8 M% T
* O* ?+ E* j7 ?4 @
3 M2 n- i# x2 V1 S
void overtime(void) interrupt 1
$ c$ l' `* u. b{
9 i: i0 J# a& P3 K5 l* q0 HEX1=0;! a1 x& ~5 O; V& W
TR0=0;! C  U# F) Z! z
ET0=0;1 j- Z8 u# z" s4 D0 v3 K+ g( |
flag=2;
. V5 {1 ?0 H9 \7 r  b}
1 N* \- J# B5 y6 z2 H* H* |- o$ T' r  x6 }' q

# t) `  _  u& n7 s8 W//写数据
" [) g$ m5 b% }" uvoid WriteDataLCM(uchar WDLCM) 9 v9 ^- I' ~% \
{1 S  ~( ?& k% w5 j! b
    ReadStatusLCM(); //检测忙. _  E, A8 q" K8 `$ _( K) m: ~
    LCM_Data=WDLCM;
. r8 `. W' ]9 {* d- g( C    LCM_RS=1;
. n0 F' r9 `; N$ g    LCM_RW=0;
7 f9 p8 G& D9 Q+ [- c0 c    LCM_E=0; //若晶振速度太高可以在这后加小的延时. d1 y5 T% r: t, z# T
    LCM_E=0; //延时
% D/ G' @7 C( Y    LCM_E=1;
8 D3 L4 }- r+ A9 \}1 U& A6 F1 q# b$ Q" _1 i
/ q; [" S- G( Z* _
//写指令. u* {, Q& S" K# V( a, ?+ q
void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测, R+ C9 _+ z8 R/ ?
{: ^' e, v8 F: l1 |9 d7 ]
    if (BuysC) ReadStatusLCM(); //根据需要检测忙- {4 P7 C3 l- O4 l2 d1 _4 v
    LCM_Data = WCLCM;4 `/ C: m8 F3 [! o/ W4 p
    LCM_RS = 0;7 A  D$ w, Z" Y* U
    LCM_RW = 0;   
: X- k" x9 ~6 i5 |  Y0 w" ^    LCM_E = 0;
2 F: M. C% I5 [8 A8 D' \    LCM_E = 0;& Y% n- }; |& W: X1 i- Y
    LCM_E = 1;   
  h) p/ K" S' [, {' I}' B5 p) L" ?2 f, v: Y+ @
. B- S1 |6 L$ X7 q3 Y
//读数据3 D& o" g) j/ k) j) _; T/ w
uchar ReadDataLCM(void)
' g4 S0 V8 {# O6 Q7 i& @3 p% i9 w{
+ c& a, I# U# ^, s2 C    LCM_RS = 1; & a9 X- m8 k% U1 e6 L& ]. T
    LCM_RW = 1;
3 Z8 B1 O* }+ u6 ~+ m' L$ f5 V    LCM_E = 0;5 h0 T6 `8 J7 r0 w8 Z+ r% F
    LCM_E = 0;
  j  V# ^4 C& r/ S( ]9 F# Y; c    LCM_E = 1;: X8 }4 \& Q/ B. `. U( c
    return(LCM_Data);
, S+ v  H: D6 q% B}
# p6 D5 a) d8 C- j; U
3 S" ~$ B8 R. q$ C( z//读状态5 x; P' @" y6 x$ ]% [5 |/ X1 z
uchar ReadStatusLCM(void)( E0 m5 p; e6 L$ K9 {6 ]$ X
{7 s1 p! i% I; ^! m3 O
    LCM_Data=0xFF;
3 C; P) D, d" P9 z/ p, P    LCM_RS=0;
' t- o) `* u: }9 a+ c7 S    LCM_RW=1;* B" f, R& U0 Z2 Z+ S+ s' c
    LCM_E=0;- g9 n1 u0 y( c# q' y! m2 G  P
    LCM_E=0;
, e3 h! H0 r. w9 V% o3 Z& m    LCM_E=1;7 c8 }6 x. z, o% B' ?2 ~
    while(LCM_Data & Busy); //检测忙信号
+ x# |& P% g4 o/ B- s( ~    return(LCM_Data);
& @$ Q" r, |" L6 @" w. }}
, \( `4 p# F* A& e/ A
) ^( _9 w9 O$ A( e4 hvoid LCMInit(void) //LCM初始化% ^, }, Y5 M) A
{
# ~* M+ H5 l, j" v+ f    LCM_Data=0;
# M4 W* p( A" a2 |    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号# A; s0 H  U- `, u" r
    Delay5Ms();
' y' Y4 x' Y1 r6 S; Z% K+ E2 _    WriteCommandLCM(0x38,0);# |  ]7 H8 i9 m; A+ E  `) b- ?' |
    Delay5Ms();
0 ^( l- r" l8 g+ X7 U    WriteCommandLCM(0x38,0);
- ?/ b1 ~* f7 `2 K  o( N    Delay5Ms(); " k4 C6 G. L2 G0 M8 `# C+ W) u1 q
3 v2 t( L) _1 H0 N, j4 x( W
    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
6 I% t5 u5 l8 D    WriteCommandLCM(0x08,1); //关闭显示  D4 ], e* n5 S5 |- F4 D+ v0 Q
    WriteCommandLCM(0x01,1); //显示清屏8 l" {; u. o/ e8 ~: o- v5 L
    WriteCommandLCM(0x06,1); // 显示光标移动设置5 a7 Q, t* C3 S- s/ n
    WriteCommandLCM(0x0F,1); // 显示开及光标设置
3 [; O7 p) r: m* M5 \+ i}
5 u0 x0 S7 B* K1 E! e8 [; l
% C  a3 `/ D% d. e//按指定位置显示一个字符
0 Y- f' G" R" V, ]7 Fvoid DisplayOneChar(uchar X, uchar Y, uchar DData)6 @" R, _" R  W0 c# x
{
' F; p  R4 E0 V/ t7 I    Y &= 0x1;
9 S( |3 c  B) d  W9 D6 Q    X &= 0xF; //限制X不能大于15,Y不能大于1
/ ]; i" D3 ~; D: j( s- _3 D  T    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;% ?) Z* d; [. x5 o& K7 _" t: U/ [% x
    X |= 0x80; //算出指令码- U. g; O# W3 M
    WriteCommandLCM(X, 1); //发命令字
! Z& \2 K; z4 \; ~* H3 k    WriteDataLCM(DData); //发数据
5 G2 g' T+ J& @; M}! V) Q5 b, d' F% |- u0 k

( X1 f' W  ], C9 s% v//按指定位置显示一串字符
6 [' m- S; ~6 a9 F+ D* o0 ~void DisplayListChar(uchar X, uchar Y, uchar  *DData). f% i/ V! j4 ?) _/ e
{+ k% q6 [5 H$ K, ^$ ?( g" l% p$ T
    uchar ListLength;' ~5 l$ H" Y9 _, a, ?
: ^! C) D- B% ~! v' @
  ListLength = 0;" y6 H0 X1 l# v3 ]' |
    Y &= 0x1;
5 [4 c% F, @& z8 m7 w& F' {3 n5 f* o    X &= 0xF; //限制X不能大于15,Y不能大于1
# k' ]: o+ u5 D! ]- V    while (DData[ListLength]>0x20) //若到达字串尾则退出! J. ]% q9 Z, ^2 Q; a
        {
1 v! |  P4 s& D& y% j            if (X <= 0xF) //X坐标应小于0xF/ L8 j  P6 m0 ~* N2 W
                {2 Z: `1 m6 |& s. q
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符" K& m/ F; D: x
                    ListLength++;
3 p3 `  \) {7 }" j/ Y                    X++;4 E, X3 ^& l5 [; B2 C% Y
                }
' v% X9 ]9 R( Y5 p4 }        }
* y/ p- X0 d* p' _4 ^/ L8 U}0 y1 U" M& `0 w2 _" @) \! [7 e

$ {" r+ q: ?6 s3 J1 b//5ms延时
3 ^8 R, K+ m# ^$ Lvoid Delay5Ms(void), M: M( X: ^1 V# J1 ?/ [9 n
{; Z' Q' M2 h0 M" [. w% z# e* Y& {" J; c
    uint TempCyc = 200;
2 y6 L6 _; t+ h. O% M3 l* x0 Y    while(TempCyc--);
$ L/ @2 h, F4 d# F. j0 T}! k& L5 _, R& `( y! `1 c  R( D
8 t. s. y9 t* a. ]
//400ms延时
( s' Y6 F' `8 S- e8 y( Yvoid Delay100Ms(void)
' K( M' `, ~. N2 A2 B{
8 K5 S9 J7 F7 A5 g# h% m    uchar TempCycA = 1;
4 O: _% {8 Y2 }( q    uint TempCycB;, i1 ?/ u. J+ \* ^
    while(TempCycA--)' O# V. E+ p' M, r( J# d
        {
4 C. [4 }. }' E- g2 @            TempCycB=7269;
- X7 M7 `" U  f+ m0 ?0 a7 G7 _- c            while(TempCycB--);$ ^" q& w$ D; U# i
        }
& o  W& v- y4 _1 v. u* e}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

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

GMT+8, 2026-4-30 11:09

Powered by Discuz! X3.5 Licensed

© 2001-2026 Discuz! Team.

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