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

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

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

[复制链接]

该用户从未签到

尚未签到

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

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

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

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。
7 I' p) z: ]* Z! i硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。' j2 a2 c1 V; |* M. [4 O' ~
液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。
. A8 D* S) Q2 }( N! l4 D) b超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。
( J( T! @, D. G- F超声波的接收电路包含一块CD40106处理芯片。5 [& S3 y) u/ z+ Z5 O' w) d
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。
$ v# s3 l1 e2 ?1 o#include<reg51.h>% [+ f2 l4 \5 Y7 Y5 \$ h  }8 A
#include <intrins.h>9 G9 f0 D8 a+ `- n9 L
#define Busy    0x80  //用于检测LCM状态字中的Busy标识) P! F5 [' Q$ X) ~' p8 d
#define LCM_Data  P0 - U  R  w& t/ W3 K5 E) E4 q
#define uchar unsigned char# F  u) b5 y& h. a9 g/ W0 X1 W! N9 X
#define uint  unsigned int' K2 I4 ^" M2 w$ H# T# a
#define ulong unsigned long$ H2 j& O) V9 E2 O4 I
1 b+ x1 T) l% M+ u9 K
/ Y6 H, m9 A3 K9 j' \0 ^
extern void cs_t(void);. ?9 c1 g+ E+ e. S3 i
extern void delay(uint);; Q6 L* _( l! f1 t7 M# L

# v* M5 p- k, x7 ^, b. \5 a0 G9 _. m0 L9 N9 l

  O  ]: Y+ ?! g( _/ _1 Uvoid LCMInit(void);. P, R8 c& e! ^% U+ ]
void DisplayOneChar(uchar X, uchar Y, uchar DData);
' C8 C8 f- X: q; W* f3 Y6 Vvoid DisplayListChar(uchar X, uchar Y, uchar  *DData);2 i# b. R2 g4 U
void Delay5Ms(void);2 |- N8 Z! A1 X2 h
void Delay100Ms(void);( P/ v2 }2 Q3 w; z) h  S
8 X' {! x/ j* c3 c
void WriteDataLCM(uchar WDLCM);
$ S5 `$ j' u1 ]1 d& F: S" wvoid WriteCommandLCM(uchar WCLCM,BuysC);
. g. o' q& x( k" h1 q5 e- s. F( _# ^8 P1 ?- [$ x9 `

7 ]# O/ m! F2 }. P8 a1 Gdata float distant=0.0;; @: V: t# M% D1 d
uchar ReadDataLCM(void);- C0 ?) s6 [4 n7 ]; B, x0 c
uchar ReadStatusLCM(void);
0 b8 y- ?) c# [3 A  Z# `; xuchar  cdle_net[] = {"--Daoche_Leida--"};) O. Q6 L8 f; |3 k3 G
uchar  email[] = {"Juli:"};
  c/ k/ k0 }3 I* _7 R: S; u3 k( }uchar  cls[]={"         "};, B5 d' L1 j8 D/ L
uchar DIS[7];
0 B; t7 b$ B0 P6 W( B* d+ w' pdata ulong time;; |  b6 l3 j! R: o
float distant;' }' Z: ^1 \/ L# W# n6 Z
sbit LCM_RS=P1^1;  //定义LCD引脚
9 c8 v; k9 R' jsbit LCM_RW=P1^2;
3 n' \5 V7 t. S4 U* H6 x8 osbit LCM_E=P1^3; ; T4 Y% y3 B: z5 }
sbit P10=P1^0;  U' F: M) l9 B/ ]
6 j# n3 _, g5 E9 X' B

4 q/ t2 s7 |# [data uchar flag;
. p. d9 `; H. L) s: W
! x+ W3 @* U0 p( O) e! Rvoid zhuanhuan(float juli)
8 a) r) z9 W0 a2 \& S4 C8 \{; C1 J2 \0 G2 u0 {6 p9 U: ^
unsigned long juli1;
! Q5 O9 N" }7 e' {, A  Z& Fjuli1=juli*100;
$ A0 j# \  D: x( d" I  m- D% Y) }* ODIS[6]=juli1%10+0x30;: D5 X4 T. m" g9 |0 `* w0 m
juli1=juli1/10;
* j7 X# p; z" Z6 Z8 d% UDIS[5]=juli1%10+0x30;
1 m  {$ R/ Q% z, tjuli1=juli1/10;7 i, X5 P9 @( H: t% ?. [
DIS[4]='.';
. V, \/ [5 @* X" `DIS[3]=juli1%10+0x30;
& _% s/ t5 L; I( O. y6 g; ]; k+ ]juli1=juli1/10;
) z" b) h5 X' n" g, ODIS[2]=juli1%10+0x30;
- r7 O4 ]' y: i, q' A& y2 y" V0 `juli1=juli1/10;- c% W* i4 t2 g3 h8 W/ D
DIS[1]=juli1%10+0x30;1 x7 H7 Y% l$ X! r9 ]% N
DIS[0]=juli1/10+0x30;7 a* {& L$ k3 U& g. Z+ L  D2 o
9 E0 {8 b# A$ `6 S# ?8 S* T
}
1 T# a, a- S' K1 s+ K, M% ]
+ N& r  v4 [; B# c  E3 vvoid main(void), |9 B- x/ f, p+ ?2 X0 ?
{. j& B& h/ m% ^
   
3 e: a% p: T0 H1 R( d. ^$ r! N0 c    Delay100Ms(); //启动等待,等LCM讲入工作状态
. u  c/ ^6 \, k5 n$ b! D8 i    P10=1;    2 O( I9 f5 l* C# u' w+ B# W' f3 V
    TMOD=0x01;             //计数器0工作在方式1& E; H- |/ @* Q0 U
    TH0=0;
2 O; t( X. q1 E3 V- W3 M4 ]    TL0=0;                  //计数值初始化
& a' W9 ]# y9 Y0 X+ v    IT1=0;                 //低电平触发中断0 x  i$ J: ]: q3 T; I6 K! |+ K
    EA=1;                //开总中断
1 g/ g1 \  U9 G+ P) Y5 c4 J    //IP=0x04;             //设置外部中断1为高优先级中断
$ F" g" d8 A1 p8 p; U5 O    flag=0;
  D6 c- G  H" G5 _; M% t    LCMInit(); //LCM初始化  K- F; [- A. {4 L
    9 n# v3 ?* \8 p; h
    % z# u& n$ r, C  M0 g
    while(1)5 B/ A/ l1 v. [6 d' {
    {
# \$ D, E6 s% \0 o1 s; Q: w     cs_t();' f' R$ J( z& \+ Z: ~, a
     Delay5Ms();        . A( s1 c! N  ~: D. n
     ET0=1;         //打开计数器0中断
" S$ s- Z1 z: Q     EX1=1;         //打开外部中断1: M' m1 Q. Q/ E& \! `
     TR0=1;
* T3 S, v2 E* s( b     while(!flag)
: D. a7 {% I; R9 p; P( U     {
4 ]+ B4 p& {9 Z2 c; c& A- B      DisplayListChar(0, 0, cdle_net);
. f* b; _1 g8 O      DisplayListChar(0, 1, email);
) u/ T9 d# \6 G( e. b4 d     }
' h5 F6 {9 I0 Y; x2 T     if(flag==1)
4 y5 }. h" L$ {. t" H3 N     {3 A8 f6 N! h8 f4 O: R( X. }4 n
      time=TH0;
- ~! d0 l% ]- i& ^2 v& V      time=(time<<8)|TL0;
7 ]" R6 O6 x; _      distant=time*1.72/100;
* r9 P4 E+ ?9 d. i0 X0 A      zhuanhuan(distant);# t7 K% u8 b/ l' U
      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');* e* ]% A1 j" W# a  L
      else   DisplayOneChar(5,1,DIS[0]);
5 o2 F* k  `, {0 z      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');- r) k* b, o* D
      else   DisplayOneChar(6,1,DIS[1]);, R- Z# o* P9 q
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');" E* g# |4 z1 Q
      else   DisplayOneChar(7,1,DIS[2]);8 W! Z5 W1 t& D) w% F9 q& g
      DisplayOneChar(8,1,DIS[3]);
4 F' i/ d- n1 x' X" z# O% C, h3 B      DisplayOneChar(9,1,DIS[4]);
0 `4 U0 W6 J* T3 K  X      DisplayOneChar(10,1,DIS[5]);
* P, v) U5 M& N% X' D# \+ L9 G      DisplayOneChar(11,1,DIS[6]);/ d. I% k) l4 r
      DisplayOneChar(12,1,'c');
  q6 g/ D5 c) D- x% S1 d( n; d9 e% m      DisplayOneChar(13,1,'m');1 [" r/ v6 C+ ]! T0 ^
      flag=0;
' C" E$ M1 h3 G, x- q5 D! o      }
+ I% ^" R9 r) G$ \& Y* n# ^     else7 w7 c6 D: z) p4 i! F  e
     {
$ b+ W! [' d5 r1 b) ^/ Z4 c      DisplayListChar(5,1,"error!      ");; K' E. z; v/ C4 {; ^  [
      flag=0;
' R" R7 G( Z$ A" ~& L     }
$ s  P* j* U! n6 m, ~$ K     TH0=0;
5 `* \" K* K. x4 q- S6 m     TL0=0;
, u. _1 e; y% Q; b" v7 m    Delay100Ms();
* [( N$ ^9 D3 N: v, {8 w9 M, K    }
: t+ [5 E, Q7 |+ Z; s( \+ u: h3 c1 H}, M6 t2 z! `) n8 x. l, h

  G) T1 m6 d/ S2 c2 J/ D- O6 r$ H! ^  w/ a6 C1 m
0 ?. c# g( U, J7 M# }% ?  p- R
void cs_r(void) interrupt 28 W( G( P: C* w. }
{# E, H$ ?& _7 t
TR0=0;$ r' Y$ b0 c% ^! d- q' I
EX1=0;
9 t$ m$ f+ l1 LET0=0;
# v  s8 O+ z9 Y4 }  Hflag=1;
8 u* h- ]  Z4 E. b* a" h}9 g# F7 t' N- q( C1 A/ p( R
& r9 l9 M1 A$ l' [& J* ~9 R5 I6 p( Z

( v/ e+ p3 F% P! p- X9 }" {void overtime(void) interrupt 14 Z* n3 g" v! w: s; `6 v
{
9 V5 P9 s# E6 [- S" X: K3 j7 Z' VEX1=0;
2 |/ ~# p1 Y2 d, m' |! p3 }/ Q4 [TR0=0;
5 G5 O7 Z: f$ c: f% o, A3 I( \0 hET0=0;3 }$ e* }( e: c% X% U$ _
flag=2;
% R/ |7 R3 C& ?, o! }: b2 e6 E}
4 R$ Q, U4 \7 c) O0 t1 F4 Q0 v* o- I5 Q4 ~+ ~" f

9 Z1 A0 _; V; z//写数据
3 U. X' A" t* l* O1 \& ]' L7 uvoid WriteDataLCM(uchar WDLCM) 5 \* o$ e# p4 N9 g7 U1 g  o1 J# ~- z
{
7 O7 ?$ M  Y7 h8 Q' O& p    ReadStatusLCM(); //检测忙
. z- @4 i- f- O4 e7 H0 b- Z    LCM_Data=WDLCM;
7 u. D! g- Z0 @. k    LCM_RS=1;8 w+ b! n/ a/ i4 Y/ |
    LCM_RW=0;: q- A( H, Y- L6 ^. v
    LCM_E=0; //若晶振速度太高可以在这后加小的延时& {; t( p/ t: V! e& R' u2 U3 ^1 n; c
    LCM_E=0; //延时
( `6 j) q, F* x5 g    LCM_E=1;
) Y: O# E6 I( R0 s}
$ ^5 w1 k- n* V5 e3 S
3 b5 O2 y# N! W5 [4 J" x! L//写指令
& q) V: S  C4 Y8 @# Vvoid WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测
/ J( e2 I9 J$ N4 _{% h' D1 ]4 E" V9 @& N) ~3 p
    if (BuysC) ReadStatusLCM(); //根据需要检测忙- K5 p! z0 g9 h  e* x# H0 t% B
    LCM_Data = WCLCM;
" v4 F. `" R5 E* i7 s    LCM_RS = 0;
! S( `- f2 x8 k0 O0 ?    LCM_RW = 0;    7 B5 C% q) u' B$ \2 X* p
    LCM_E = 0;
- d5 g/ [1 b. U  G. |5 K& \& N    LCM_E = 0;
' t; L2 g+ K9 u6 ?  `    LCM_E = 1;    1 `4 S  b7 H5 u9 w* Z0 V
}" f, o* ]& w- P0 a1 c; U$ s

) q/ G: v( I' O, p//读数据
' U1 Y/ k7 n- d' @& e8 s! z: ouchar ReadDataLCM(void)
4 S9 u7 v1 v" t% p{$ {4 b( W, A$ c( m
    LCM_RS = 1;
/ u+ k: n+ F( p7 }3 l5 d# H    LCM_RW = 1;
$ Q. g/ N+ l' E# s$ b' R5 ]    LCM_E = 0;& m# u; Z1 c6 t; M& f/ P' S; `$ S
    LCM_E = 0;
% t- e- f1 Y) z    LCM_E = 1;
* k3 V" q& {9 _& r    return(LCM_Data);) b) s& D- |1 I
}
1 ^' F& m0 B% R7 b9 b+ w. y- c  [( ]  T! H9 Q) U$ y7 B9 _
//读状态
8 S% X+ b- ^6 juchar ReadStatusLCM(void)% H: p& d( P$ t2 a: \1 M7 _
{( Q9 z( R+ _6 U' q- K0 @
    LCM_Data=0xFF; 7 i+ ^3 P5 G- K1 f
    LCM_RS=0;
: z6 K; c, C5 B+ q    LCM_RW=1;
; g9 h1 V6 F$ x0 Z& ^    LCM_E=0;
: _3 \. z4 D% P    LCM_E=0;
1 M+ ^( ?# w  \! R, K) X8 H, F    LCM_E=1;4 E# t6 l7 i, W( c0 K
    while(LCM_Data & Busy); //检测忙信号! l3 v7 S3 s3 D& `) E3 ]
    return(LCM_Data);( U2 c5 H. E# l8 T$ `# o2 O
}
% M/ f1 d4 ?7 y
: `4 W. T/ i% ~2 m1 H+ d, lvoid LCMInit(void) //LCM初始化
6 T# ]# L) v; x  S) |+ x{
, y) A! g* p+ e    LCM_Data=0;
5 B1 n- w* l1 {! ^9 f    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
! a' a* B9 m8 S    Delay5Ms();
" }8 W+ ~) O% S, e    WriteCommandLCM(0x38,0);
( ~) L! r6 t3 {9 z    Delay5Ms(); 2 Y' T5 Y6 u( ^7 \6 F
    WriteCommandLCM(0x38,0);
6 u  Y& P* e- D; g# `2 J    Delay5Ms();
' Y8 X! v3 S2 l" M3 _1 y6 N# F+ c5 Z" f2 z) a( U
    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
) E: M+ N, ]+ V# v' {: T    WriteCommandLCM(0x08,1); //关闭显示
4 [. E1 K  [- O6 f4 K1 Y    WriteCommandLCM(0x01,1); //显示清屏' N& p; d: M# l
    WriteCommandLCM(0x06,1); // 显示光标移动设置$ b8 k6 a8 ~0 a' h+ a7 r
    WriteCommandLCM(0x0F,1); // 显示开及光标设置
3 a$ ~; ^% b) r/ b) N}
' g3 B2 L0 g3 q
( j) D: n% n: c7 d4 H0 [3 K//按指定位置显示一个字符9 L3 F% J0 B) p9 t. T3 x% L
void DisplayOneChar(uchar X, uchar Y, uchar DData)
2 J9 ?" R: I3 i! O9 p{, w- W7 ?# X# V2 u$ Z( I
    Y &= 0x1;" S/ \' S9 V( l- G: u5 Q" Q1 h: p
    X &= 0xF; //限制X不能大于15,Y不能大于1
, z2 ~+ X, m. J+ E: G# u* g    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;! D6 B9 A+ h; m- x
    X |= 0x80; //算出指令码  ~/ Y/ O! ^( ^# h
    WriteCommandLCM(X, 1); //发命令字/ ]1 @/ {& T; Y  }% c) w
    WriteDataLCM(DData); //发数据" B9 x- T( X  B5 z
}: k# v3 @7 s: Z" W% c; j
- u$ b$ w" \6 R/ W& R: p* \
//按指定位置显示一串字符; O6 C# X+ }: m0 ?* }
void DisplayListChar(uchar X, uchar Y, uchar  *DData); n5 _3 ^) q. g8 L/ G' }
{
; @$ w! r$ g7 \: s! j, k    uchar ListLength;
, D1 `/ B$ r  a5 c, Q
4 C- z7 s0 X4 Q$ T8 y  V- @# D+ N1 J  ListLength = 0;5 H5 |9 \3 F: L* W" H4 S7 ~
    Y &= 0x1;
# l3 t! n% L( W$ L8 Z    X &= 0xF; //限制X不能大于15,Y不能大于19 `$ c& u" e2 N( Q& P; [  H
    while (DData[ListLength]>0x20) //若到达字串尾则退出- y, W' \+ y4 U$ T
        {
1 |9 S. X  \% Z2 U9 e" |' ^            if (X <= 0xF) //X坐标应小于0xF$ `1 X8 l, X" N1 |  x7 P
                {
$ m% l/ ~2 M9 U3 u0 A                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
8 O. a9 e0 Y+ i' T1 l2 U                    ListLength++;" s6 Y! j' L+ J
                    X++;
/ G2 ?0 M; e  u/ [1 C8 g/ n                }
) J$ k9 J$ g# `" x; R- j        }5 U6 _! _4 Z4 P
}
( _1 p6 G" ?. J5 N! A1 I0 r6 g4 V
3 c) B% ~% Z6 G  J: i, {$ u3 B//5ms延时
5 P- w  t! `4 Y) M- K8 R6 h. Avoid Delay5Ms(void)
3 Y& B3 A3 _; ~% K  Z8 X{% Y" {; \% X7 p2 Q
    uint TempCyc = 200;
. y5 K0 v5 o+ |" E+ L6 a9 b+ T    while(TempCyc--);4 _& |) N3 q+ o% o" o  e
}
! |6 e* r. n, K( N: J
6 \1 a3 i9 E! p0 _9 ]5 J//400ms延时5 Y2 {. t  O: I% i9 i+ W, }
void Delay100Ms(void)
' G% o: p- v" [! L1 D. G{* W6 g/ ~) x6 A1 V$ o
    uchar TempCycA = 1;
* ?7 L( B/ k! B" D+ _/ X    uint TempCycB;
. n: J( L* S3 p% r    while(TempCycA--)) e8 N5 b4 s! l; S2 I) u
        {
4 i2 {" R! U4 P, T( [) v! d            TempCycB=7269;* X/ Q7 X, Y( p5 g* s, n
            while(TempCycB--);
8 k: t2 o+ }0 r; k6 b        }( _( x6 c$ {) s0 o7 k: E) x) {
}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

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

GMT+8, 2024-5-2 06:39

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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