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

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

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

[复制链接]

该用户从未签到

尚未签到

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

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

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

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。+ r- ]! b, K, y/ g
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。: A* \0 w& q) D8 c3 r2 L6 }4 y4 i
液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。! I7 P; d4 G: p
超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。
. `( }% p5 ?/ i  z) Q超声波的接收电路包含一块CD40106处理芯片。3 ^; o1 y' w' a: T7 @8 a! k- y
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。
/ e* Y+ y( ~0 c6 T, w/ G#include<reg51.h>3 u5 H" `" E) C2 J
#include <intrins.h>
! B# @9 W8 L+ q, Z+ V' H#define Busy    0x80  //用于检测LCM状态字中的Busy标识" B$ t0 N' ?: g, B. d# n- E
#define LCM_Data  P0
2 M  E- p/ T" r* x, X#define uchar unsigned char
/ y  y( f% [4 B& W0 c#define uint  unsigned int
. {- _; E  n- @$ K( u#define ulong unsigned long
$ Y% f  U; t1 P% y2 A0 i! W2 t" A( [/ K6 }8 I. R
& Q% S" s: I+ Q
extern void cs_t(void);
* s4 O1 {, ~; S5 M8 [" e  o- N, N9 cextern void delay(uint);
; R+ w1 U+ [3 \3 z" ^7 B
; o1 c" u( v: o5 `
* u. F3 Z) [% g, V* G1 F% H" y% W8 I
void LCMInit(void);
" ]  p* G# j9 B* }5 [void DisplayOneChar(uchar X, uchar Y, uchar DData);- |4 o# b- m# c; ^$ |
void DisplayListChar(uchar X, uchar Y, uchar  *DData);
" d5 f& B# t# M) Q6 W9 F: `void Delay5Ms(void);) l. N$ O' r) k2 y+ L
void Delay100Ms(void);
* E' W! F$ w; i1 n" A6 b/ U: E) s9 M
% ~! V" |$ ^8 j0 ^void WriteDataLCM(uchar WDLCM);$ O7 F) Z  P, U/ G( h6 O
void WriteCommandLCM(uchar WCLCM,BuysC);
) \- U' r# U" w' n  e9 v, z' V/ K" ~+ [, t! h: N

! H/ ^. l% ]8 I) b) O+ i+ `& tdata float distant=0.0;8 Q# u! p- H# t' \( O& G
uchar ReadDataLCM(void);
% {# G' m6 H5 M& K2 Nuchar ReadStatusLCM(void);
) n% D) s$ U4 nuchar  cdle_net[] = {"--Daoche_Leida--"};
% L& K' m* A+ _; k0 `uchar  email[] = {"Juli:"};% p. a  o# V/ I5 Y* D: u* |5 x; Z/ M
uchar  cls[]={"         "};2 C* f: h/ c  F% v  G
uchar DIS[7];
8 C  Q! ?' B; I$ v! u2 P" xdata ulong time;% a8 v7 q4 H! p) x6 U
float distant;
$ j6 m$ B5 ?( @: S; Tsbit LCM_RS=P1^1;  //定义LCD引脚3 r& {* M" i' q
sbit LCM_RW=P1^2; 8 j& X! P5 w! N# Q% }
sbit LCM_E=P1^3;
6 ?) u; R5 R1 _- M2 Y, Csbit P10=P1^0;
4 G, R$ K# e" i3 r! m% q* T: A& E1 `4 `7 V. i0 [1 N: p

2 s* r+ G" F! v; d4 v0 W, idata uchar flag;
  t* M$ J$ [0 L5 l4 Z9 ^3 o6 ~/ E* a# q# Y9 U
void zhuanhuan(float juli)" R+ S1 }- x7 j6 j5 ?  |2 V/ U
{: |% i% j; m7 L3 _/ T
unsigned long juli1;0 K% U* S; X/ j% u0 ]0 V
juli1=juli*100;
0 d; M2 u& B/ P" H, wDIS[6]=juli1%10+0x30;
5 ~$ R4 V) H- d# ]juli1=juli1/10;5 P3 m% ^9 u; d# t% y" g
DIS[5]=juli1%10+0x30;! r& g4 n5 y5 d" c
juli1=juli1/10;
& W7 h5 I0 E2 \" b# PDIS[4]='.';
6 G. C, @; {8 N+ A( `9 zDIS[3]=juli1%10+0x30;
* Y8 U0 h/ h3 T/ Djuli1=juli1/10;
2 y, l5 i5 k* w6 j: F/ P8 B% gDIS[2]=juli1%10+0x30;4 U1 f0 k0 y; a
juli1=juli1/10;
4 F5 u) {$ ?( h& uDIS[1]=juli1%10+0x30;
- M; {: ]' y3 V( X6 KDIS[0]=juli1/10+0x30;
$ D! n4 _) T) ?# {' J" g9 r- `6 X2 \# Q4 _
}$ z# U, W+ q. R

0 H/ o+ S) E8 Z+ c$ Vvoid main(void)
6 |/ l: K8 }+ L7 ^$ D{' j$ Z+ w3 c2 Q, c% ^
   
' ^  [2 S7 _% n. e5 ]: [    Delay100Ms(); //启动等待,等LCM讲入工作状态
5 u$ W8 l0 v& F( J5 F+ |    P10=1;   
3 T1 |4 ~8 M; @    TMOD=0x01;             //计数器0工作在方式1
0 s- M- O5 V+ N, G6 a* _, H    TH0=0;
6 T, D2 O2 i" K- e    TL0=0;                  //计数值初始化& d* F3 @' R; Z5 A, t
    IT1=0;                 //低电平触发中断! j6 n1 z; w) |5 B. v' t4 G
    EA=1;                //开总中断# w8 |7 v/ }* C
    //IP=0x04;             //设置外部中断1为高优先级中断* n% ]; S) B* ~4 K1 K: E7 a! t' {
    flag=0;
* ?" @. ~5 j; L+ G$ E/ i    LCMInit(); //LCM初始化6 ^4 q/ d- c( @7 \9 t
    . Z0 X% Z% M0 w6 F9 r
    ; ?5 ^& O3 W: u, B1 d, K+ G- h. m. t
    while(1)+ n( ]& @. G6 Q2 ?; B
    {$ w& ]4 _" T# }. G' x
     cs_t();) h) t* C" M" _/ K0 I
     Delay5Ms();        
' ]; B& r5 a0 K$ Y* K     ET0=1;         //打开计数器0中断% ^9 r3 o* s+ H6 H9 R5 C
     EX1=1;         //打开外部中断1, A6 S6 n7 l  [# e4 [. ]* j) {
     TR0=1;+ b0 n6 b8 q; m7 m4 C% G
     while(!flag) : b" E" m0 }. d6 V
     {# f* L6 Z! V0 M
      DisplayListChar(0, 0, cdle_net);
- F) G' q# y0 k$ b      DisplayListChar(0, 1, email);
, D# y+ g# X: Q" _     }
2 q  }0 n3 ^" ^& L# a8 w8 s* D     if(flag==1)
: L2 T5 |7 ~# [' {- P  e" B     {
- M5 y3 i6 D2 p. v      time=TH0;& x' l' p6 P. w. u
      time=(time<<8)|TL0;- v- {, `8 ~' x
      distant=time*1.72/100;/ {) g( `/ Q# V8 V% n4 t
      zhuanhuan(distant);
, b& q% d7 J5 f5 Z      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');7 B, A5 h* Y& X) m, e4 C) t, f
      else   DisplayOneChar(5,1,DIS[0]);7 ]3 s# y0 ?0 t
      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');5 O/ q# d/ z! H! ?( ?' i( A
      else   DisplayOneChar(6,1,DIS[1]);
  `! F7 X/ i$ g8 f3 L& ?$ d      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');
1 [! f+ L* {. n      else   DisplayOneChar(7,1,DIS[2]);
, x3 ~+ D8 K& a' h' ^, a      DisplayOneChar(8,1,DIS[3]);
* R9 |  X; c* ^; w) g) X, x9 {' A      DisplayOneChar(9,1,DIS[4]);4 G) j, Z# ?$ t7 G) P% ]: A
      DisplayOneChar(10,1,DIS[5]);2 M7 O% V. A! q- J+ q
      DisplayOneChar(11,1,DIS[6]);+ r$ S4 n/ |! C) J# @6 `4 R
      DisplayOneChar(12,1,'c');
7 i* a8 W: ^+ p9 E, U1 f* u* K      DisplayOneChar(13,1,'m');7 Y6 c/ n' I& t1 X- Y
      flag=0;
$ }7 h' E3 s) i& d- f+ |  v2 @      }4 S; g, M1 e2 D1 ^' L6 F
     else" S) M5 F2 y* c* ~9 f, J. t, c
     {, Q, P% T( F% M6 A6 e. C
      DisplayListChar(5,1,"error!      ");& _9 ]; I$ f" t8 ?
      flag=0;8 H1 ^" V+ k3 {4 K1 N6 O
     }
0 q+ S( R$ J1 T* N1 [3 Q, I     TH0=0;
9 _& b3 v6 O4 ~+ r4 g5 [4 }8 `     TL0=0;
3 _$ w' F1 X4 [9 m8 K" W    Delay100Ms();
6 ?% D7 m1 y4 p, u    }% l0 y+ N# e- [9 e
}
( a. v% a. h, i3 P8 `" N$ P# t7 U. v
. ~4 m" R2 [! M
3 Z: _8 D5 T4 B9 f& w5 B
void cs_r(void) interrupt 29 z/ x* Q4 ~$ d- e, }1 U% D
{
+ @  F8 r, _# ?% z) uTR0=0;) f4 Y, ?. L' X$ w% E3 e: I' p" Y
EX1=0;# @4 P. w; r$ N+ G' A0 d2 u2 A
ET0=0;! i7 q" b! M# w
flag=1;3 w0 @) @" w) O
}* k- N! H* h; [

. [( \" w& x/ X0 _$ T$ Y  V/ S) N. X3 Y0 m" v
void overtime(void) interrupt 1/ a' {' m( `) t. F& y" _
{% q: G) S4 N/ r( w# u3 M- ^! a0 A
EX1=0;) [6 g7 ]0 Y& c  Y( J
TR0=0;$ I, E  U$ ^7 R/ K
ET0=0;
. l0 X, C9 l6 l3 J' Kflag=2;- Z2 M3 b* v0 B4 u. A
}
3 A1 T- Z# {, C& O+ E
2 T" `3 z6 ]& o
1 M- B# `. ?* m6 w2 \. h& R6 n//写数据& p2 K* g  ~; g; i
void WriteDataLCM(uchar WDLCM)
$ R, N9 @6 ~9 m! k{6 d: a7 X0 N4 D& s8 e* ^- m+ R
    ReadStatusLCM(); //检测忙/ }5 U/ q8 P6 ^9 l" ~1 ^
    LCM_Data=WDLCM;, R+ ]& D1 f% \% _
    LCM_RS=1;
9 B: U* u4 C( k+ p    LCM_RW=0;3 B4 }0 S" K9 z
    LCM_E=0; //若晶振速度太高可以在这后加小的延时+ W8 N" u1 z0 Y5 k- h$ B6 e
    LCM_E=0; //延时+ N+ L. b$ Z& t9 @- a+ B1 R6 A
    LCM_E=1;6 b* e- V; ^- d0 }( s  V" z: B
}
0 I) P1 `. P6 M2 [, {& F4 [. H
% O; c8 f# K" d; @: L5 E! g//写指令
6 T+ U; @# h3 e9 j/ w5 pvoid WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测) D0 ?. H' {0 C/ A- Y' P
{
4 V' m& m5 W& ]3 X    if (BuysC) ReadStatusLCM(); //根据需要检测忙
4 a) f- L7 ?) e+ I2 H4 S! ~    LCM_Data = WCLCM;7 W8 `* V: v& q: r; s
    LCM_RS = 0;
- ?9 V3 f4 I5 J    LCM_RW = 0;      q. z' Z6 }' m* q1 y, e
    LCM_E = 0;* a& T" n5 `/ o  {/ u& }% ~
    LCM_E = 0;: j' f, Q# P9 w: Z4 A' \' j# {2 Y
    LCM_E = 1;   
6 `* M0 ~- t8 C5 T2 z5 ^$ {}6 t# U# l, v$ |$ w# E3 b
" K. B9 o: z0 x- @1 l
//读数据
' ~+ o0 V  ~9 {  M+ A! q; }- `8 duchar ReadDataLCM(void)
6 W& y# E) B. L9 H1 F3 y: w" g. C) b{
- ~% v7 [8 K+ }0 F7 `' u    LCM_RS = 1; 5 U7 E& N0 A2 s% k: ~8 ^
    LCM_RW = 1;! e) L/ e. w" W+ I5 \, ~( u
    LCM_E = 0;& p$ A8 ^+ Z3 `% a
    LCM_E = 0;
5 A$ W; |' O" a) m# I$ z. p5 p    LCM_E = 1;, q* T8 S8 h) y& l
    return(LCM_Data);
/ F4 k  L1 v5 Q}% J5 `0 Q! s2 I& l* ~6 z
/ o, R( t/ ~7 ^1 N* G
//读状态
$ y; r  T, c2 Luchar ReadStatusLCM(void), Q: j3 X6 N: H: c5 o8 ?: X; q, L
{
! z" p2 X9 l( d4 b2 s* {) n    LCM_Data=0xFF; 9 r2 Y: v( l! K8 w
    LCM_RS=0;* S. W- q$ y% h6 \
    LCM_RW=1;; r- r4 w. j' b( u: k
    LCM_E=0;9 b9 v4 F' _+ b: d4 H. b6 R
    LCM_E=0;5 h; F1 t! E7 Q  w
    LCM_E=1;
) N; t+ G5 H5 H$ B/ P$ }1 m1 Z) g    while(LCM_Data & Busy); //检测忙信号7 C& a7 p: O+ b; j8 U6 E% y
    return(LCM_Data);' Q, U( A8 F. s3 l! l
}
1 D" c. p' C& U. z; [" U% o% ?! e# u: I) i* _1 K+ X
void LCMInit(void) //LCM初始化
1 q1 A6 k+ U; ]{( ^5 }4 t6 ?' b* v4 ^2 L5 v
    LCM_Data=0;& e" o2 U/ e* Q" t1 B
    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号/ q/ I  X8 |( a9 X) K& a
    Delay5Ms();
1 O  z: M7 d# X1 o    WriteCommandLCM(0x38,0);  N+ V; `8 }! }. f
    Delay5Ms();
( t* m) r$ J7 m7 y! H( o# |* L( o    WriteCommandLCM(0x38,0);
% M9 F  @$ q: W* ?, E( ]% c: ?5 ]    Delay5Ms();
- N# ~0 U0 |9 _% q' k2 R- h( X! B
' n; \/ v+ x( n1 ^/ X1 `7 g    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
# a/ e+ d) T' z0 Y1 U3 k+ c    WriteCommandLCM(0x08,1); //关闭显示
. N, y4 g/ \! w4 r' ~    WriteCommandLCM(0x01,1); //显示清屏1 ?1 u3 i. `! j2 }; f/ V$ ?
    WriteCommandLCM(0x06,1); // 显示光标移动设置8 X; [: T* W$ W
    WriteCommandLCM(0x0F,1); // 显示开及光标设置
0 _% n4 n4 t: E2 W& b}
7 C# `: v! j  D; ^* j5 _6 L
4 V; M  L( D1 P- }; A5 n//按指定位置显示一个字符
5 R& K5 S4 a1 S  z6 Q+ s( Svoid DisplayOneChar(uchar X, uchar Y, uchar DData)
1 `/ k, D! G" B4 Q. @{
* s9 C+ d4 r/ E$ j2 B$ _    Y &= 0x1;
7 A, {; @. R+ g! g0 q! i    X &= 0xF; //限制X不能大于15,Y不能大于19 t4 p5 \4 c% G% V& D# [; T- l
    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
& C' U+ B" ^. Z: x# k" r    X |= 0x80; //算出指令码: R/ U+ [4 D  M1 \
    WriteCommandLCM(X, 1); //发命令字
9 d5 r# r! O7 r9 o0 ]5 i    WriteDataLCM(DData); //发数据
# r7 ~6 B) R+ A}9 s0 I. e0 W$ D8 T

; H, r% |- p1 l4 P" C) N//按指定位置显示一串字符
' Q! C1 D) p( l5 @6 gvoid DisplayListChar(uchar X, uchar Y, uchar  *DData)
1 w& ]' B/ H" d& s: ^{
+ _/ B5 V7 o2 ^! n7 @( C' V; v( A    uchar ListLength;
/ }' ]' C4 @4 q$ u. |. f0 u* L1 B5 w7 s6 C8 ?* O" ?3 k3 s2 [
  ListLength = 0;
7 t- i3 u, W/ X: e% ?    Y &= 0x1;% u. o3 D4 S7 B, q) U! J
    X &= 0xF; //限制X不能大于15,Y不能大于1
9 {5 I9 x" M0 J& S. Q9 a    while (DData[ListLength]>0x20) //若到达字串尾则退出" `0 t, L- M  K8 D
        {
8 `  S) V& V$ i) V; s' t1 G            if (X <= 0xF) //X坐标应小于0xF" Y6 Q" j" X- _8 x
                {0 S5 D; J+ ^' z  p5 N
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符/ H9 N- z6 j' M. Y9 R1 K
                    ListLength++;6 E; I: V+ h- E7 c  s
                    X++;0 j/ l. Z! A% Z
                }
4 O" o% v" V- q2 n; X- I" D        }4 h$ x" m# s2 N' M7 l+ @
}
- ?0 R/ H& _0 ?1 P1 C: i: k
/ ]/ z& `8 }/ R9 A//5ms延时5 D) ]6 K. T3 t1 A! k7 W
void Delay5Ms(void)
% o& b- t9 Y  T. U4 _8 I{9 R/ F9 `1 {1 I. X! u( e4 C0 ~
    uint TempCyc = 200;
" G3 L& ]) z; R! q    while(TempCyc--);% i, r5 P/ C9 p  \) u. f0 ^
}
, a! E: \( Z6 a# K( Y; L9 M: g0 ?, S- z3 T" I# m
//400ms延时
( I, T) o/ B3 gvoid Delay100Ms(void)! x1 [1 \4 j" [; S! ~
{2 d& M) X" b9 s+ Q) p: M
    uchar TempCycA = 1;
# P3 `* r8 K+ w/ l    uint TempCycB;) S, X9 e. m- h' W
    while(TempCycA--)
! w1 L8 x/ I' O        {
. o% e0 C4 _+ J            TempCycB=7269;
7 m6 n' @0 j1 C5 Y1 ~            while(TempCycB--);
. r' p& A" \7 s6 N$ X' J        }
  K5 c, ]% i. D3 g}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

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

GMT+8, 2026-3-18 00:36

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

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