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

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

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

[复制链接]

该用户从未签到

尚未签到

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

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

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

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。! y, m3 F+ O) @+ t1 R0 D
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。  v# m" d+ n7 i9 o) \5 V
液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。/ K) n, k: h6 v. w4 \
超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。. ^$ s* X5 j- ?9 _7 z  H, S1 V
超声波的接收电路包含一块CD40106处理芯片。
6 ^+ {8 k4 r' }技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。+ ?: X5 z9 [; p# ~
#include<reg51.h>
5 m9 U+ g" y% @7 O+ b#include <intrins.h>, ?. h  c$ z4 G, q' e
#define Busy    0x80  //用于检测LCM状态字中的Busy标识
: M4 c7 |* b& ~6 L  U$ H. A! H#define LCM_Data  P0   r- f, [8 x% ~3 s% r4 x% I
#define uchar unsigned char+ p) }/ F$ o% S, O) W0 w
#define uint  unsigned int
$ S( @- b6 N  B. |- e( h9 T9 M#define ulong unsigned long1 I: z& ~. }3 E" |

7 d: B! L9 B8 m1 K# n6 B* N: B
! i! x7 O3 p9 [) u7 L& _extern void cs_t(void);+ |4 z2 Z& j( D& o$ |
extern void delay(uint);8 f: W. ?! Y2 \! N: `; ?
! A- n0 @% m1 ~
& K- n' _' H8 q8 U9 V6 O+ h
7 N. E! o. m9 x- A, J0 W% d8 D, N/ \
void LCMInit(void);5 S( g2 {! _( s$ p% N/ P8 L
void DisplayOneChar(uchar X, uchar Y, uchar DData);
3 J! j3 j* W8 d  zvoid DisplayListChar(uchar X, uchar Y, uchar  *DData);3 v7 }: V  ]" A, k: W  T
void Delay5Ms(void);4 \& _6 _1 r/ s
void Delay100Ms(void);
8 a4 w& M6 R( [( c
" y7 |+ X% @: F! k; cvoid WriteDataLCM(uchar WDLCM);
  X. x" |: n+ k' C! p" j) i' cvoid WriteCommandLCM(uchar WCLCM,BuysC);% y5 p+ P; B6 p) [1 K$ @! s1 K4 c7 K

( L* B; X0 @$ Z" f
0 g6 J  w& ~4 K. L4 E6 n1 d1 Xdata float distant=0.0;
' c2 a- f' `  O; A4 d. b2 N) E0 Duchar ReadDataLCM(void);
+ U7 m( \' s! H! Guchar ReadStatusLCM(void);: e, ^9 i6 A# b9 A, D- m
uchar  cdle_net[] = {"--Daoche_Leida--"};
) Y5 P" l% k- ^$ }uchar  email[] = {"Juli:"};6 ?8 e4 n! W! T4 ~2 q
uchar  cls[]={"         "};
: a  x4 j; p$ E' uuchar DIS[7];( m1 I' T1 b; S; o* B* }% S1 r
data ulong time;
1 j/ E# N9 L# a! A6 q) b1 ffloat distant;
* I' v- I& P( Z1 `+ Ksbit LCM_RS=P1^1;  //定义LCD引脚9 _0 g: Z! H8 T6 G8 i1 w+ A* k/ l
sbit LCM_RW=P1^2;
( W) C" S) Y) q8 A/ G: ysbit LCM_E=P1^3; * ]- K* ?* w/ u0 r
sbit P10=P1^0;, d* B* B4 M7 {3 z
7 ?; P8 t& U' U4 b5 [& {1 i# L

7 W1 d0 B+ m2 J7 V3 J7 x- j' n; Gdata uchar flag;5 g) Q" Q$ A9 y! D/ w4 x  G
; O1 ^8 _8 P" |( [8 l& ~9 q# ^
void zhuanhuan(float juli)% W5 s0 q; Z8 X+ L
{
5 E6 j3 O4 C( n7 funsigned long juli1;( G: V: K' o* ~0 K1 _1 k1 c
juli1=juli*100;. K" q9 j7 c- P( m# y
DIS[6]=juli1%10+0x30;" g. ^6 e+ Z7 x" x
juli1=juli1/10;
9 j: e! W5 M9 J1 j* [DIS[5]=juli1%10+0x30;
6 j) x4 h, f9 S8 F7 w6 Vjuli1=juli1/10;
% a0 x+ s+ z7 E5 q8 LDIS[4]='.';% M# R9 R2 ]5 s* W  x
DIS[3]=juli1%10+0x30;
1 B% l' q& |6 V5 V6 sjuli1=juli1/10;
7 c% V* }3 c) \DIS[2]=juli1%10+0x30;; ]0 ^; I8 j7 F  v, j+ _5 X. W
juli1=juli1/10;3 M" o+ L3 g: v  \3 t0 A6 {
DIS[1]=juli1%10+0x30;4 P0 H# s( ?: n1 \1 K
DIS[0]=juli1/10+0x30;
4 a$ w' v* e. e& Q1 ~8 {5 P; U- C* `5 i! |! r
}
5 G) B5 D; ]+ y! \) N
7 r, Y, _. d; M& ~8 i: U# E8 Uvoid main(void)
" G6 W7 d7 {# R{7 D) {1 x3 L1 f
   
2 B' `- ]& o' S0 s0 p/ r2 V7 v    Delay100Ms(); //启动等待,等LCM讲入工作状态
8 ^4 H8 k( ~# W    P10=1;    . |+ v. `# P* q2 h# \  i, q+ E
    TMOD=0x01;             //计数器0工作在方式11 z. C7 y+ @, d% E0 U9 @4 n. N
    TH0=0;
" b1 m1 \9 _# q4 r0 n: G    TL0=0;                  //计数值初始化. d. w% s) n; o) d. V
    IT1=0;                 //低电平触发中断; h& y4 w7 L; T- W$ ?
    EA=1;                //开总中断
8 `3 _$ n. o1 k" _2 m    //IP=0x04;             //设置外部中断1为高优先级中断) y3 ]; N, ~" W& U4 l+ K
    flag=0;. M) \+ j1 ?3 ^
    LCMInit(); //LCM初始化7 T) f, K4 c. A: N1 R) e
      Z$ L2 y. K+ E' _) V
    8 U5 w3 _) j' F2 X/ {" S
    while(1)
' E1 N, G$ G) p: f4 M* h$ V+ M    {2 I! d2 A+ l+ G, H& N' J
     cs_t();
6 b5 a  ]2 T; _2 t     Delay5Ms();        
2 E- ^4 X4 P! ^( h" f, R9 N' v     ET0=1;         //打开计数器0中断% a6 `/ Y5 g# [
     EX1=1;         //打开外部中断1
0 V0 S' n5 z: `/ R% D     TR0=1;
& k- r# }- Y+ g( ]2 A7 U4 d     while(!flag)
' d( W2 ~( J' H3 c% K  z' ]0 A: c     {7 i, @* z2 K, m# R% ^  J  _! E
      DisplayListChar(0, 0, cdle_net);7 n* m( H/ z6 H! r+ Q7 {, U8 Z
      DisplayListChar(0, 1, email);& r$ x: A# Q" f+ S! [
     }
& W9 B7 r# {. b; `& m2 a" N$ W: W     if(flag==1)1 }5 J0 C5 ?4 R7 e6 N( Z8 j
     {
8 M! F& C* E3 N# O; R      time=TH0;5 ^* B6 Q  w" I/ W! [" s9 U
      time=(time<<8)|TL0;: ~& i& X& D6 _% a7 b
      distant=time*1.72/100;2 Q. N5 y& g" ]: ?5 ?! }- Z3 q
      zhuanhuan(distant);) v( _3 |* U" q) H& p8 U( C
      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');
- E0 _% N' L- Y( K! y1 C8 Q      else   DisplayOneChar(5,1,DIS[0]);
/ d/ [( I5 D! Q% \& k      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');7 l# ?# V! s* Q# K1 u% w7 ^
      else   DisplayOneChar(6,1,DIS[1]);
: f0 d9 t$ m% `      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');
5 q: s% ], T' p% Y( j$ W; d      else   DisplayOneChar(7,1,DIS[2]);
1 K* {* x# l% Q! j1 e- N* M4 F. `      DisplayOneChar(8,1,DIS[3]);' f$ ]+ K8 I& |
      DisplayOneChar(9,1,DIS[4]);
1 q% Y0 D5 o# T) k. A5 U- {      DisplayOneChar(10,1,DIS[5]);
$ M) A, s9 D8 @' R9 ~      DisplayOneChar(11,1,DIS[6]);
" {: j$ R! _& i      DisplayOneChar(12,1,'c');
4 n0 m( B: e6 Q  L. i      DisplayOneChar(13,1,'m');* l9 T' K" E) N- C
      flag=0;
  n' q" D7 f8 s) y0 _1 }, J" h) T      }
( @; F5 ?) _+ G" N' y     else
6 g4 q, j2 {1 J     {$ _+ \$ F3 b! P$ l2 n7 ~
      DisplayListChar(5,1,"error!      ");
7 G% l5 u+ k' d1 L; l      flag=0;+ W1 N) C/ {) C) S# ]. |
     }& N/ K; V7 i4 G6 ~. d
     TH0=0;, f7 L9 k, D) R! Z3 Y& K9 Z
     TL0=0;. u, L. u: n" K6 V6 s  ^1 K2 l
    Delay100Ms();: g5 h% k6 X( b, t9 i
    }
5 b) o' a; T# g}( g+ \* d* @7 P5 b3 |2 j! N, u* ^

) ?% q- L' K' {- C2 i- @9 ?. V4 v  V8 ~* D/ Q; s
; l  `+ Q/ V& F% r
void cs_r(void) interrupt 2
, Q* A  z/ X5 Y4 B, w{1 B# K/ a& C6 j9 f6 k; j' C
TR0=0;* M5 M% N5 j9 R7 \5 b
EX1=0;# y5 {3 H' W+ W  ]
ET0=0;1 N+ h. F" [, t- s/ h4 T
flag=1;! e1 m& Y' l& A1 \$ q
}
" p: g% @3 q! w: y* i# F
& E( L; s* D) `, [( `# ]- ^
5 y* ?  s; O8 Z/ X5 a3 }void overtime(void) interrupt 1
7 i/ E$ a) l& l' H{8 h9 N  S! e" h! f: b/ a
EX1=0;; Q4 x- j  [/ Q6 G8 E7 a1 ^9 l8 p
TR0=0;
9 N6 [9 C7 a  b  i/ {! A8 NET0=0;# ?3 r. q8 M" O( w
flag=2;. K0 ?/ l: i1 t7 l
}
4 Z, x! b+ N: c4 R0 r# _4 S  j
  `7 @0 E: t9 A/ E0 ~$ l
: v, r! B) R" n: ~9 {//写数据
: q6 d# H$ L* K# y: R3 N7 @void WriteDataLCM(uchar WDLCM) 4 V0 f! L, O" C! P
{
2 s7 y. l/ n  L    ReadStatusLCM(); //检测忙
4 V. p/ `9 E1 \) d5 j0 Y1 p$ _; O    LCM_Data=WDLCM;: R. X; \0 J1 M7 r
    LCM_RS=1;: o! e& W+ C; ]8 G
    LCM_RW=0;
- w$ v: }7 U4 ?/ e' y! V" G% j    LCM_E=0; //若晶振速度太高可以在这后加小的延时3 s! S' y8 p( T! {
    LCM_E=0; //延时
  \& j3 G6 P- L* v* n/ `    LCM_E=1;
, @9 x5 @( O( ?5 q+ p/ T1 E}0 _8 ]: y. K: r. H
( p9 F1 X6 h$ E* Q7 u
//写指令
. T3 K% ?5 ]6 E8 b. P0 a9 b$ F! Dvoid WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测) R% ^9 s8 j) N- p7 u: n
{( D! y% i! I8 @
    if (BuysC) ReadStatusLCM(); //根据需要检测忙5 z, X3 M) _; A* G
    LCM_Data = WCLCM;
4 F# ~4 c- {9 A4 ]5 ~6 j% ~0 A) {4 r8 p    LCM_RS = 0;$ o1 `6 a2 w7 L& P
    LCM_RW = 0;    ( J/ Q0 D& y" b6 J( i' x6 T! W) ^4 {
    LCM_E = 0;$ @" O) E. A  L! y
    LCM_E = 0;
, r- L. a- J" t6 D: D0 }    LCM_E = 1;    - m& C: C3 f4 I: `
}
* |$ M; J1 _; }( [  c0 A# N; }' I1 a* Q: O9 V' g$ j5 X9 F8 S
//读数据* [. Z7 n% J+ X
uchar ReadDataLCM(void)
1 \/ Y! g$ v( Q6 g  k{
& G% D7 H7 p/ O    LCM_RS = 1;
7 O4 G& J1 m; X' b4 I    LCM_RW = 1;
1 l7 O5 y, }  \+ i$ m; s  `! N! Y    LCM_E = 0;
* \( F& m  ^( M, a, o/ h7 ^: d    LCM_E = 0;' q9 d4 I  |0 }# q/ q+ ~( r
    LCM_E = 1;! a  W  G8 I7 S1 P* r
    return(LCM_Data);
$ s- ^' d$ ?& M" w1 o) J# z! Z}" H; A/ z/ m) s

. |0 I$ z' p. t- C//读状态/ }) [3 h$ b2 d/ A
uchar ReadStatusLCM(void)6 ^" E( O6 d; |- |( v
{" O  S6 M6 Z7 @5 k9 Q  w1 @( p$ B
    LCM_Data=0xFF; ! s. q: O# J: G6 @5 R- K; N! Z
    LCM_RS=0;! B2 S9 g7 A; L% r/ K
    LCM_RW=1;
- l6 E; q/ x4 {8 ~: C1 b    LCM_E=0;3 O! r0 {% `. H2 [" c- K4 R
    LCM_E=0;# [$ {2 h1 ~# K# T- h; a0 c
    LCM_E=1;8 M3 C8 c6 j% ]- ^* i8 i  @$ e
    while(LCM_Data & Busy); //检测忙信号( y) c, L" m9 A# R: _- O# {4 \1 ?
    return(LCM_Data);8 k! |& O# |% S) n. j# q% f
}
; X* }5 Q; I( Q: z% w
) [, i) N6 C. Q+ f0 O! ?, t2 fvoid LCMInit(void) //LCM初始化0 L! M9 t: A. n+ q. e9 Y
{
7 Y- R7 x8 Q- m- ~# g    LCM_Data=0;7 I# N% c, D  d# {
    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号: K7 k3 Y* d! U. i+ P
    Delay5Ms();
% \, T/ v- {+ j* S1 C    WriteCommandLCM(0x38,0);
5 n5 U  g: k; X    Delay5Ms();
+ O1 |9 c4 ?9 z    WriteCommandLCM(0x38,0);
; ?) d& ]3 v$ W2 k, K    Delay5Ms(); 2 W: u5 `2 _; q7 U+ F

0 m; i( Z4 q$ F& U! Q0 w    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号- Q4 \# t/ _' n. p; q. o& z: T
    WriteCommandLCM(0x08,1); //关闭显示
  U; H4 U$ V8 y& F    WriteCommandLCM(0x01,1); //显示清屏4 a( _6 b( k+ b$ E4 G- a. {- ]1 q
    WriteCommandLCM(0x06,1); // 显示光标移动设置
6 i' C; y3 g0 k9 b    WriteCommandLCM(0x0F,1); // 显示开及光标设置, G% z8 c- w4 T+ h( {
}
( M/ Q' U( X+ h  H7 Q0 o  |) W6 z# s0 u$ E3 Z' u2 n
//按指定位置显示一个字符& D' [" z( D7 J/ k6 `1 \
void DisplayOneChar(uchar X, uchar Y, uchar DData)+ |2 J& p, z( y* q
{# q( `3 N8 @* j/ u7 O
    Y &= 0x1;
8 A1 I4 `* B0 w4 v: a0 \4 f6 B    X &= 0xF; //限制X不能大于15,Y不能大于17 ^+ l6 z  D9 K; T& x' [* q/ W, B
    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
5 f/ T; e& F! Z, C( V6 |    X |= 0x80; //算出指令码7 d2 U* y4 V& X$ r0 ~4 {  u: F
    WriteCommandLCM(X, 1); //发命令字) w+ W0 g! {6 O" Z& B4 @+ I
    WriteDataLCM(DData); //发数据+ ?$ `1 T4 c/ {- x) R* U8 x4 p
}+ A8 A& F6 R4 q' s+ p
2 O7 i9 z  c: S% J0 ]+ Z
//按指定位置显示一串字符
/ g8 f7 f( K8 N0 }" qvoid DisplayListChar(uchar X, uchar Y, uchar  *DData)
' ^+ D, m: r- Y* @( P: z{1 u; _# U2 S( ?% e7 b7 i7 }7 h
    uchar ListLength;3 E$ j& U! |9 m  _0 M' R

6 ~0 B( x/ U( ?  ListLength = 0;, [) b+ U( }/ E+ n% c  a
    Y &= 0x1;
1 l2 W" U! _7 {4 b( ?    X &= 0xF; //限制X不能大于15,Y不能大于1
) P5 O8 x! k+ x5 T3 ]    while (DData[ListLength]>0x20) //若到达字串尾则退出
1 W( s8 W+ e% u  z+ X5 h9 L3 m        {9 ?1 q6 }6 x1 G9 B( }! L% s
            if (X <= 0xF) //X坐标应小于0xF* p8 O; `' u& a
                {- F- `4 j* g; E
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
- M" X& n& y% V6 I) ]1 |7 z+ U! ~+ _                    ListLength++;
8 ?" y$ X5 Q) w! w1 b' |7 }5 f' y                    X++;/ _6 K, t0 y( G  F9 M/ N
                }
' }! Q3 l) Q) Y  B  L1 b& m        }7 f7 N0 W$ i- {# X
}" }. D; ?2 e) K2 o8 P1 V
  i  e( w; `8 ]2 V4 O) D
//5ms延时
( t/ x, c! B  ?0 e" Rvoid Delay5Ms(void)- T  e9 ?6 A. D( T2 W1 W! l( e' j  X
{
5 o1 _6 ?1 t0 b/ @0 n    uint TempCyc = 200;
7 d% Y$ }2 P8 T3 J* I! @    while(TempCyc--);
3 S! \  n" N; F7 x2 R, y& P, E}
4 O: G+ p( Y! ^6 h" c" d( a1 {% o1 @" T+ ~5 q
//400ms延时
- ]! G" I# S; C$ Rvoid Delay100Ms(void)
* y0 R  K: L7 ~' H$ w7 q{
6 n! i3 S  g# R1 q    uchar TempCycA = 1;
1 V# m- `. [+ N    uint TempCycB;
2 \  T0 @: B& s1 g$ s  D9 T    while(TempCycA--)1 M4 x; t3 r" r* `# B0 F) n+ z
        {
7 z5 M7 x0 U! f8 q* {' q            TempCycB=7269;3 c1 W: d8 F+ @5 \6 U, R/ b  y
            while(TempCycB--);' R& F$ ^8 ~2 @+ j$ Y( D
        }
" U$ r/ S0 b5 d. n- I3 W: M}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

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

GMT+8, 2025-6-7 05:52

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

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