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

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

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

[复制链接]

该用户从未签到

尚未签到

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

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

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

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。/ A4 `& @% \1 M( t2 }
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。
4 e0 m' x; X- m/ @  M  M液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。
- l& K% g9 H' c. x超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。. P7 ^+ m5 C1 t; y7 v' i! A" ^0 r
超声波的接收电路包含一块CD40106处理芯片。! A7 M( j% |( c2 l1 O$ Q$ c. H
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。. d, d/ G' W9 D$ d/ g6 q' x
#include<reg51.h>
* C; P* K* e1 r" \#include <intrins.h>
! ]& N' B& j' U9 s$ F$ H#define Busy    0x80  //用于检测LCM状态字中的Busy标识
3 V* }1 O8 b- o8 x0 h# e#define LCM_Data  P0 ! e+ `3 g! f* o4 D! l$ m
#define uchar unsigned char
) w  s& Z  X$ |" J: E; t#define uint  unsigned int# q. f9 q: [- I0 S/ n) X+ g
#define ulong unsigned long
' d0 X5 Y9 @* t( @! P
! U: N! J; Y3 t3 o6 u' d" P! s4 ~* ~0 l% r5 P6 f, V+ N" t7 d
extern void cs_t(void);
' C5 _0 F: L  p4 x( C5 F  |2 B" textern void delay(uint);
6 ?% U" I# I$ W+ J" u
5 k. U3 }4 r. k1 G4 b3 r
8 z8 b* i1 @/ S4 F6 a$ I; B  {
$ \" S& T) X* d& p4 i+ Ovoid LCMInit(void);" [+ q+ @9 s0 w4 R2 ^& \4 X
void DisplayOneChar(uchar X, uchar Y, uchar DData);
4 }' L: w0 G( I5 q+ t/ B) g! ~void DisplayListChar(uchar X, uchar Y, uchar  *DData);
% [7 k+ ]) X  O" Y4 ?void Delay5Ms(void);
8 b% h6 q+ U  W3 z6 o) Nvoid Delay100Ms(void);
! e# r7 j9 @# ?" F$ a) ~9 j' B3 i+ o4 d/ f& D( Z1 |' a( R0 e# s1 a
void WriteDataLCM(uchar WDLCM);
  i& {* P+ i$ u1 ]void WriteCommandLCM(uchar WCLCM,BuysC);+ ~6 B0 B6 t2 t/ V% Q  X5 t
5 e6 x8 A: N/ l9 W7 |

9 E0 a0 x3 Y* j2 F( L& }- X2 jdata float distant=0.0;. @8 D9 ]8 s* Y0 t$ ]
uchar ReadDataLCM(void);
  V& R* {9 D' U7 F, g! puchar ReadStatusLCM(void);# |6 ~& r; F) z$ W
uchar  cdle_net[] = {"--Daoche_Leida--"};' v2 C0 b' A' L9 t# l1 G0 |
uchar  email[] = {"Juli:"};1 V% \- l( Z0 f/ G- S
uchar  cls[]={"         "};8 A9 m/ `) ?  Q" t( P
uchar DIS[7];$ c2 ~: E9 B; M8 H2 n* Z! T& b4 d
data ulong time;
' G; u9 Q. a& y2 C+ ofloat distant;
# @. U5 n- M" n* x+ J2 wsbit LCM_RS=P1^1;  //定义LCD引脚
7 x3 T. _, J. D# G" Lsbit LCM_RW=P1^2;
6 h' A* N+ i7 R& W5 P( U5 usbit LCM_E=P1^3;
; {9 n$ G3 I2 M3 g) Vsbit P10=P1^0;- _. c' U  @# R# W# [1 T. J9 L- e: A

- c! ~$ Y- y3 S: d0 k9 h5 u1 P  U, a, _- o3 V& t3 K
data uchar flag;
' ?* ?, o- o/ P. f5 `
9 `' e4 a3 I# Cvoid zhuanhuan(float juli)
1 A3 D4 ?, ~7 u6 d% S{7 ]) c5 R- L- k" ?7 Z+ [0 h
unsigned long juli1;
/ h; e! M$ A# J. C- K; mjuli1=juli*100;5 O- i* Z2 x7 N' r6 i3 T4 X( K
DIS[6]=juli1%10+0x30;
0 c1 m. u1 [; f9 M) p+ qjuli1=juli1/10;
8 _- }9 Q2 Q8 [DIS[5]=juli1%10+0x30;
7 o* R' D- s; C$ J! gjuli1=juli1/10;0 Q) `; `! ^: D
DIS[4]='.';
" ]* W  s6 r# q& w% `DIS[3]=juli1%10+0x30;. k% }/ G& W+ S7 _7 q' {* k; y
juli1=juli1/10;
! m! w- j' J, KDIS[2]=juli1%10+0x30;- K) N( A* J2 K* y, z
juli1=juli1/10;  N% ]0 c" a8 b# P+ R  _
DIS[1]=juli1%10+0x30;! m; A! @& _. w& H' I
DIS[0]=juli1/10+0x30;7 |! _5 L  L& B  j' v

  {0 v5 d1 f- M2 ~}
2 t0 [/ x% B$ R" A$ @" a4 I, A8 y' q( Q
void main(void)
7 u' p/ s; S/ p/ _0 B6 y/ H8 H' T{
  b, |- g% |/ e% d& B# F# r2 W   
  l; w7 f- R8 p* g& K    Delay100Ms(); //启动等待,等LCM讲入工作状态/ h& R- E% j, n1 P% n8 q
    P10=1;   
+ K! Z5 u' ?8 K$ E2 g+ {    TMOD=0x01;             //计数器0工作在方式1
0 ]- z0 n$ _* M. r8 T    TH0=0;
" H! n& J' B( a    TL0=0;                  //计数值初始化
3 U0 i" I6 Q" g- i! c    IT1=0;                 //低电平触发中断
8 T8 Z7 f: X' f+ m: E+ d' \    EA=1;                //开总中断
: j- M" m8 {  V- t. s; h' F. ?    //IP=0x04;             //设置外部中断1为高优先级中断
% A5 i3 z# n/ o8 V4 P    flag=0;
6 K3 f+ \8 j1 W9 \, y7 W    LCMInit(); //LCM初始化% X. p' X' h$ g3 o: h
   
# K2 s/ ^& j4 {" p: @   
" h3 q, J/ F: F6 r" m    while(1)
3 g, }/ |1 D1 [& q0 Z1 C    {- y* C3 n) Q* B; J! k# C
     cs_t();
. J1 g3 p! p% F* q" u/ n0 V2 f     Delay5Ms();        
) J3 L9 r# h3 D3 Z# W3 Q$ J2 u% o     ET0=1;         //打开计数器0中断
3 G  M; g3 X% z/ N     EX1=1;         //打开外部中断1
3 u, \; S' h0 o* K4 _& K( f! R* w     TR0=1;* M# f! i7 h  Z7 f
     while(!flag) % L: a- b3 L% O7 r$ H. D
     {" R6 [) R  F* }) r2 ~/ R: I0 k
      DisplayListChar(0, 0, cdle_net);
' L. ]" W# o0 J1 c      DisplayListChar(0, 1, email);$ P0 e5 t6 J% H3 X
     }: s4 z: b2 W5 \/ W' _* m+ D$ u
     if(flag==1)0 @* |- m8 z- i* M. ]5 o8 y; F- R6 I
     {: R+ U! ^% C: W. ~* h9 m
      time=TH0;
2 G4 |, S' V3 e/ _9 N  F. C      time=(time<<8)|TL0;
" J: H5 R1 h+ K9 k3 p0 [. e      distant=time*1.72/100;
; n8 V& f2 u! D' g) h' ?, Q      zhuanhuan(distant);
2 T- ~' c- W% k3 m: W$ q0 d      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');, \& A$ h7 S, t, F3 w6 F6 A9 o' A
      else   DisplayOneChar(5,1,DIS[0]);
" n2 K! P: R2 e$ X, N+ |      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');
0 _8 J, n+ _* j  m9 T      else   DisplayOneChar(6,1,DIS[1]);8 D! T$ ^3 k6 {; z
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');
3 k$ A$ ?8 h7 z6 V" ^      else   DisplayOneChar(7,1,DIS[2]);
4 }$ e. c- w( L  {' s9 s/ B      DisplayOneChar(8,1,DIS[3]);
+ Y( V! H3 u& a# F5 j      DisplayOneChar(9,1,DIS[4]);4 a' l: g: d7 }+ b) B" S
      DisplayOneChar(10,1,DIS[5]);
& K( W1 |( Z* @) d2 _8 Z% P      DisplayOneChar(11,1,DIS[6]);
- E9 h3 R" W  J. ?3 y      DisplayOneChar(12,1,'c');
% k* J6 Z; z+ n6 R+ N& C# ^      DisplayOneChar(13,1,'m');* W% A- r3 Z' Y
      flag=0;
6 S7 v- m, O5 I- l1 r( m      }! m: I1 k* m' @* J( l6 G
     else8 ]- q& ]% ~8 r" m5 J% Y! l
     {4 E8 B+ z. z3 [5 d7 ^
      DisplayListChar(5,1,"error!      ");
# D4 J6 U& X- {2 W/ J  r      flag=0;4 F& j& D4 B% ~( n, q
     }# d6 x" ]3 _" @1 G' Q
     TH0=0;
! f7 Q# w$ c! g" g+ \     TL0=0;0 }3 M/ m" h2 z# Q
    Delay100Ms();
; |4 ^# S2 \4 }0 n4 v6 b$ a) V    }
  y  E# G* e/ L- M( x2 |5 Z3 l% O}
7 _) d+ P& b% ^+ |  ^7 S( |0 V. B5 h4 ]8 O1 S, W

$ {. ~# z4 v7 Z5 I$ V* c# h2 X) p1 \& _6 h
void cs_r(void) interrupt 2
1 G9 o' E) X8 p' P1 d8 c# {' Y{
' c8 y2 n+ _  v9 Q4 O6 Z7 O4 bTR0=0;
! ^# G- G  |* _$ h7 p. C; sEX1=0;. f& C7 @& a! q
ET0=0;
. t' [; @9 e1 T) Qflag=1;8 @- g, Y% f0 ~2 m6 G
}
  k% I2 \3 R( F
0 Q3 B! x; B& D/ h5 n7 J$ v0 q) N' U1 ]& t1 c- r9 k
void overtime(void) interrupt 1! D. G% w8 B6 K1 Z
{, r' T. Y% b, y% Q9 r/ J
EX1=0;
! j* S4 m' m- P5 }1 a+ fTR0=0;# g+ @1 A& k: `; F4 j( \
ET0=0;
: S5 d- Z# K( g2 ^flag=2;
, Y- m  ^, [! a( Y2 r4 `: O- d+ O}+ _  |! \/ m' Q  G

, A& L1 P7 K; S7 q5 V! o9 t. i# F3 Q$ I/ B
//写数据
6 ^; b/ w5 }2 C. Tvoid WriteDataLCM(uchar WDLCM) ! k- F" c1 u7 K( r5 y
{4 `+ \2 c& B, p: _( e) y. T' i
    ReadStatusLCM(); //检测忙/ _" |: ^1 p7 P+ k1 L' J) z
    LCM_Data=WDLCM;9 b# _* \" q8 e5 e4 I! ^
    LCM_RS=1;3 P- U. l9 T2 o9 [  k: i. ^
    LCM_RW=0;, V7 Q( o/ J2 r) U! [+ R* S: y
    LCM_E=0; //若晶振速度太高可以在这后加小的延时
7 _+ n! F3 L; L% z) z8 H4 B( s    LCM_E=0; //延时
& R5 y% v/ `9 Q5 g* a. E0 y- d+ H7 t    LCM_E=1;5 @9 {' _9 u; p; m9 k7 W+ g
}; z" U3 S% U8 N: z6 y6 O5 S

9 i& v+ d( N; x" v1 H) i- _/ {//写指令
/ x! ]' k- O1 ?: Pvoid WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测6 u& u8 X8 r9 _( q+ E& r
{, l% ~% [% a5 e6 h# i
    if (BuysC) ReadStatusLCM(); //根据需要检测忙7 Q* M8 W# h% R5 ]9 S" s, K& b& J. H
    LCM_Data = WCLCM;4 H- U2 `5 u/ [$ A2 S+ X% _7 @) @
    LCM_RS = 0;4 y& a! r; |% e2 m
    LCM_RW = 0;   
- k& F( \2 _! ~: K7 y9 |3 p    LCM_E = 0;1 e  c6 T9 b0 ?+ q  l3 P
    LCM_E = 0;) \$ d; A, h  _
    LCM_E = 1;    / H! j0 _. k6 b1 h* d8 N. G( x# p" E
}0 C0 V( {7 p' a% b! l5 j0 m4 u. r
4 @* f, C) E. j0 [
//读数据
/ d, a) H) E7 [7 s* X7 ]0 r# G9 `uchar ReadDataLCM(void)
1 U4 \/ @6 I9 @$ @/ A& d# ?3 |{
+ A6 j( z$ w- G    LCM_RS = 1;
& [# K% H) O* P% I& R+ r    LCM_RW = 1;: l  F5 y5 E# R
    LCM_E = 0;
7 A, U& \, Y( R+ \0 A( v    LCM_E = 0;
' y, A. ]+ ?2 l# Z, w    LCM_E = 1;
' |& o% L  k; ~    return(LCM_Data);% {2 @3 E# W  u+ B
}% @% G$ y/ W, D4 M' ~* E

, k: `8 K3 V1 g6 R6 m+ E7 Q) [2 p//读状态% {. J( u0 B" {
uchar ReadStatusLCM(void)
" z0 c% V/ p( o9 P9 r. b. G: h, _{0 @3 V, F0 q; G, f7 c; V- A6 v
    LCM_Data=0xFF; 2 R# L0 j. k' R
    LCM_RS=0;
3 ?% O* j* E; t9 Z: L6 ^    LCM_RW=1;' K6 t! ~6 E* Y+ ?2 L" U3 V
    LCM_E=0;* U$ T! g" ^$ R9 D$ o, n5 G$ f0 j# F
    LCM_E=0;- R* l+ s0 q; T# @; U
    LCM_E=1;
+ ]% \0 J  s% \0 R    while(LCM_Data & Busy); //检测忙信号8 ?7 ~! _2 ~4 r2 L% ~4 E
    return(LCM_Data);
3 T) R7 Y# c" L  T* ^" k# o}/ ?* E$ W; ~% V: e# c* G
1 M6 m) h/ [& g' Y
void LCMInit(void) //LCM初始化
2 b( k. f+ i$ I! m7 W  c( ^" i, q2 H{
+ s/ \2 ?0 ]! k& J    LCM_Data=0;0 }7 G) ]8 O7 G& p3 i' ^5 ^& j
    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号! O5 z7 |- {8 a/ a2 M
    Delay5Ms();
. z* Y! ~6 ]! e, c6 @  g    WriteCommandLCM(0x38,0);9 h0 A/ C5 P1 R, ~% C( u
    Delay5Ms();
0 X( I% `, R: }( n8 c    WriteCommandLCM(0x38,0);
4 u) ]7 A6 I% ?1 @  I" f1 K    Delay5Ms();
5 i5 e& m8 Z5 i4 {0 o2 {
2 _% R1 `! Z' G) `1 E    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
! X7 _3 ]- M$ s3 N9 E) I5 v    WriteCommandLCM(0x08,1); //关闭显示
. B1 V' @! ~" \! {" E- y    WriteCommandLCM(0x01,1); //显示清屏. i8 J1 a  }* i  ^# G9 V
    WriteCommandLCM(0x06,1); // 显示光标移动设置
4 D" T; n* j/ Q- `( O    WriteCommandLCM(0x0F,1); // 显示开及光标设置# I' T) x; V7 e( g
}
7 @9 i! J" G5 J# h% j* K
' P: M2 `$ A, m5 @/ }//按指定位置显示一个字符
& J5 K$ m8 G4 O: C8 hvoid DisplayOneChar(uchar X, uchar Y, uchar DData)
7 _' G( W) H8 r/ t0 J% O1 T# [{
$ X! |; I7 d9 L% ?    Y &= 0x1;& P6 U8 n2 `1 }& k: s( U0 n
    X &= 0xF; //限制X不能大于15,Y不能大于1. s* m$ a4 T" j1 b  ~
    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;- F8 y& H$ z# i) o! ]0 j
    X |= 0x80; //算出指令码# a3 r% s% M, A) F5 Y: j
    WriteCommandLCM(X, 1); //发命令字
. g# }$ r3 z9 h9 e1 q) R6 |  M6 e    WriteDataLCM(DData); //发数据! J' X6 ]8 @' {1 {) e5 f
}
( o( `& H) K2 N: W. h) t/ y+ f4 S/ e/ B! o  Y7 v5 v& l
//按指定位置显示一串字符7 P# n1 _- c9 S0 C' g2 ^
void DisplayListChar(uchar X, uchar Y, uchar  *DData)* ^; M( `/ |; H3 F7 u$ K) G
{* [% t4 d# e" _$ ~, @- t
    uchar ListLength;
+ [& v! k9 A3 u5 h+ M' b$ p' {# L8 d+ W/ w: B' _
  ListLength = 0;
1 B8 }& x% r& T3 v    Y &= 0x1;
+ a3 t3 {7 P% \/ r8 x    X &= 0xF; //限制X不能大于15,Y不能大于1" o! F# d1 k; R- |' g2 q
    while (DData[ListLength]>0x20) //若到达字串尾则退出7 ^( C" `5 G1 U' ?, z' S4 {6 U
        {9 d! k8 c2 B6 [6 Y' P
            if (X <= 0xF) //X坐标应小于0xF$ p4 {, O0 I: ?  W3 |6 ^" B( [
                {  \: ]+ o8 I1 u
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
* v0 J* ^0 \0 X& y; c+ s. m                    ListLength++;
% [) c' C9 N, T: I8 M                    X++;
( r1 X9 M9 X. b$ t& [( ]9 b                }
* C. \: E8 e# `. u1 M; C        }
) U& y  b9 |4 L" O}% Q. I9 f& R# @

% `  N/ u+ I$ _: _5 c* b//5ms延时; y! V- `5 R5 W7 b1 j
void Delay5Ms(void)
. ^5 F. ~+ P7 g6 J6 _{
% A- j: V5 B$ N: ^4 e    uint TempCyc = 200;* W- R4 B  i0 ^5 [
    while(TempCyc--);2 T( ]& x6 t# @
}$ P& G- h5 I3 a" o6 G

  o, F! C6 j3 w//400ms延时# A' O4 B, `8 W: v
void Delay100Ms(void)# H% Q6 v* z6 n+ W
{( f* G- {4 e8 u% h
    uchar TempCycA = 1;
  ]0 _) d$ i) q2 ?! ^% d    uint TempCycB;
  V9 u4 }3 r9 z6 c( C: b    while(TempCycA--)
+ b4 o2 D7 g( ?* \2 v4 g1 X7 h        {8 q0 W5 n9 d$ I2 W% q
            TempCycB=7269;9 [- x- V: X" \9 C4 ?5 \' L
            while(TempCycB--);* E; E( K9 j' Z' b+ Z
        }
  p" g- ?; r/ d- f) \' k4 E4 S0 W}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

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

GMT+8, 2025-5-13 02:49

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

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