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

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

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

[复制链接]

该用户从未签到

尚未签到

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

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

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

×
下面是一个超声波测距的程序,硬件电路由于电脑格盘已丢失,下面的代码是从样机上复制的。; E) v* Q3 p2 V, W0 d
硬件电路包括液晶显示、超声波的发射、超声波的接受、滤波、单片机处理。
" p# Y- m( b1 {) X) t8 X% o2 B& U液晶显示采用LCD1602模块,下面的代码里有液晶的驱动,可以拷贝用于它处。
4 [3 q. c0 M: T) q) H& u超声波发射电路包括压电换能器及其支持电路,发射约44KHz的超声波。- G" Q4 n$ F& ]$ A' b
超声波的接收电路包含一块CD40106处理芯片。' b; B* A# F2 l
技术指标大约是测距范围在三米左右,测量精度约在厘米级别。大量用于倒车雷达的测距中。
* W" [: U* o2 l6 S#include<reg51.h>7 X9 c; `/ K" W& r- u
#include <intrins.h>/ n! g& \2 W, {; B! C
#define Busy    0x80  //用于检测LCM状态字中的Busy标识
4 j% O" |" C; p1 S' E6 w#define LCM_Data  P0 % b5 P# f7 X( W& M9 y0 H$ N9 |
#define uchar unsigned char# v* Y* P; N- c* {9 H* _
#define uint  unsigned int3 ?1 K4 |! e" H0 c) o, C, o
#define ulong unsigned long9 p3 Q8 f- T' h+ U+ p9 u4 ~
' `! n: Z2 x+ }( G. ^$ e

9 H; I& q2 \/ ?3 [- V1 k0 textern void cs_t(void);; e+ \% q' m% U. ^* G. [1 d# t; m
extern void delay(uint);( c( e* v: ^9 C& i6 J& {

3 ]. l/ J/ T4 \+ g
; [* e8 E& ?! N8 E$ e# ?: }- c4 f/ j2 }2 ]$ Y1 J) V
void LCMInit(void);% {' _6 j) e8 x8 U6 i. z0 H
void DisplayOneChar(uchar X, uchar Y, uchar DData);  `2 e  h( L1 i$ _; [4 `6 v
void DisplayListChar(uchar X, uchar Y, uchar  *DData);; M; V, p$ C) K
void Delay5Ms(void);8 s% f/ P  @$ }. w
void Delay100Ms(void);, q5 O$ K  [6 r  T% r3 p

- C% P8 B+ w" z# C; |; @void WriteDataLCM(uchar WDLCM);
3 l1 b. Z. a- d1 Q$ Ivoid WriteCommandLCM(uchar WCLCM,BuysC);( }+ z/ ]+ p' ^0 m, h8 P/ M3 S' M

% O* _& o9 r% Z& H
! l  C+ ~; V! A/ H8 [( _data float distant=0.0;$ ?- @7 q# `  Y/ x2 H- n
uchar ReadDataLCM(void);5 Z  ^/ H1 w8 ]# _: ^# i
uchar ReadStatusLCM(void);
7 Y4 i7 S! E* v/ X- B0 M4 |& w: suchar  cdle_net[] = {"--Daoche_Leida--"};
! J8 M; U+ J6 d$ R( p* F# euchar  email[] = {"Juli:"};
6 a2 W( ~1 k; J9 N+ Quchar  cls[]={"         "};+ j2 W4 R  G& N/ y+ G; j* ~
uchar DIS[7];4 c- ]% A1 ]3 P
data ulong time;
) {) a6 R/ `$ z3 k* Gfloat distant;8 L0 K$ ?3 O4 q
sbit LCM_RS=P1^1;  //定义LCD引脚& f. T+ i% x; }* t
sbit LCM_RW=P1^2; $ J. }/ \" D! z. H+ m
sbit LCM_E=P1^3; ' \, `/ _9 q5 J, x; Y* W+ v
sbit P10=P1^0;3 l# W6 M% s: z! H( ]+ t; z
( F9 D( y% B. [# S" T

& A7 _$ Z5 I9 @2 Z7 P7 n2 Kdata uchar flag;
  [* f2 Q  z, I) }
+ N$ ~1 q" [  Cvoid zhuanhuan(float juli)2 G7 O1 Z) p9 P% B; m& ~1 d
{4 C, o; h4 B2 K2 G/ e. y" ^
unsigned long juli1;" {  Z- r  x6 i0 x0 C* c
juli1=juli*100;
& }1 P! r% @" u8 t% G* QDIS[6]=juli1%10+0x30;
  t2 B( r7 f) Y! mjuli1=juli1/10;
- H) ], a2 P. JDIS[5]=juli1%10+0x30;* Y" G0 f4 |% z' {: L
juli1=juli1/10;( ?) X1 n1 a8 W
DIS[4]='.';
8 @) i2 Q. M0 ^2 o6 S' y4 |+ @DIS[3]=juli1%10+0x30;3 P8 D7 Z- n+ r1 E
juli1=juli1/10;. [' r4 b  Q) l3 b" w3 k8 j2 K4 ^
DIS[2]=juli1%10+0x30;
* F5 ?4 s8 B1 u4 ljuli1=juli1/10;; e5 m& U7 H/ k- |) f
DIS[1]=juli1%10+0x30;
/ Y5 k) K+ k. @4 k$ W' \8 i* hDIS[0]=juli1/10+0x30;/ a& I6 k8 V3 j8 |( w

/ `  s+ h# l) m5 C! t: U}
. X" D, I# Z% g! F6 {5 Z* v8 a# w: s) W. N1 p1 U
void main(void)& c( w' I# V  j! v* Z7 v- T$ O2 [5 _* G
{
" g( p+ w; E' {; e* ^- P   
" S  b. ~8 l4 r3 P8 w9 s- }    Delay100Ms(); //启动等待,等LCM讲入工作状态5 \* t2 B) R2 O5 |: j/ r
    P10=1;    3 @  r  K5 \9 I" [/ R) W2 j" M
    TMOD=0x01;             //计数器0工作在方式1
: d2 P. v+ b1 S( C+ A# l- p5 p1 y    TH0=0;
, h1 C& P) i* S( N    TL0=0;                  //计数值初始化
5 Z: t5 Q. O8 N3 f    IT1=0;                 //低电平触发中断
- p& O# |! }) a+ A$ i  r# z    EA=1;                //开总中断
  G! h  D; r5 J: P5 _9 `* F    //IP=0x04;             //设置外部中断1为高优先级中断
  D/ t+ K0 i- {$ K# e    flag=0;$ E' t. g. C# H2 A' ]5 t* R; q
    LCMInit(); //LCM初始化4 x4 S. J6 Z1 X2 Y
   
* p/ T3 m9 D# Q( e4 w1 O   
) {; p3 M$ `% {/ {: ?( |    while(1)
, x  ?8 x) f8 t- v# c, ?    {' w7 w! y& x# i/ k0 ?) C1 {
     cs_t();1 v. a) a, C: d" g4 Q* e( ^
     Delay5Ms();        
. s: q6 f( H* j/ A- r     ET0=1;         //打开计数器0中断
  l6 V2 q. {7 i% Y- J* u; c) `     EX1=1;         //打开外部中断1
" D0 P3 {; s# D- |* @- |! l( ]' n; u     TR0=1;( l9 p- `, s  G# K+ [2 @$ q' W
     while(!flag)
& T% ^9 v6 G' m2 g- a3 ]0 Q     {
1 v1 m) Y0 `. Z7 g. z* s      DisplayListChar(0, 0, cdle_net);! ~- ], |, \: R) {! q8 s
      DisplayListChar(0, 1, email);1 n( X1 E8 p$ q/ N3 _
     }
0 Y% ?  l# U7 _) i" S& n0 c     if(flag==1)6 ^& C) }# {5 ^% v9 W! t; Q
     {
/ b9 W1 `9 A: `3 [      time=TH0;. h! t  a, L5 h, U& A' m$ @
      time=(time<<8)|TL0;# Q  b7 B7 j. K8 |' m
      distant=time*1.72/100;8 |9 c& \+ n) m) X& t$ S/ {
      zhuanhuan(distant);2 Q, W: m1 s+ w# N9 ~. _( `# [) h
      if(DIS[0]=='0')      DisplayOneChar(5,1,' ');+ E- p9 L5 Z. O" O! a; g
      else   DisplayOneChar(5,1,DIS[0]);( c/ ]6 O4 O+ [; D- e5 v: m
      if((DIS[0]=='0')&&(DIS[1]=='0'))      DisplayOneChar(6,1,' ');
9 j! P, ^6 Q6 @' k. Y; m+ r      else   DisplayOneChar(6,1,DIS[1]);, I4 R) |  v& T# v7 g0 l+ B
      if((DIS[0]=='0')&&(DIS[1]=='0')&&(DIS[2]=='0'))  DisplayOneChar(7,1,' ');
4 Q. M5 T( U, _; z8 ~: E      else   DisplayOneChar(7,1,DIS[2]);8 N" q6 g$ w7 h/ Q! W5 ?
      DisplayOneChar(8,1,DIS[3]);" ~1 P8 x/ I9 A- s% W7 A
      DisplayOneChar(9,1,DIS[4]);
$ p, F3 E: _8 k# s/ g6 z      DisplayOneChar(10,1,DIS[5]);! x+ K. _) J( l5 _0 ^  L# W
      DisplayOneChar(11,1,DIS[6]);
8 o/ K* v9 b5 W      DisplayOneChar(12,1,'c');
2 u. W0 w! U+ {/ _4 ?& A6 a. R      DisplayOneChar(13,1,'m');
- i+ a2 t, H  S- Q1 W      flag=0;
- `, c6 M9 O: m. N2 I1 L3 J      }# s6 R) ^9 \- y7 _  Z& h/ Y5 t
     else
' F4 ?% f4 C: I; k     {1 H6 }0 d  x0 {- w8 A1 l" G5 a
      DisplayListChar(5,1,"error!      ");
6 O7 T* F( I9 h2 P      flag=0;
# w0 e* u3 [) r" t8 e     }
( h' K0 v0 ]: V, q& L  X" a5 P     TH0=0;
) M( Q# ?: ~/ p  q% r9 a+ T& e  w     TL0=0;7 r1 p+ V7 [* r% X0 {( c0 A3 |# d; y
    Delay100Ms();
) k/ E5 p: {: k# X, Z0 Z    }
* J, B+ E- K# @* V}
% Y4 C0 ^" P6 W- u7 Y: z( t) ?3 E8 p0 c) S3 k7 ^; D" O. `: N

( ^; Y  j/ N% d7 }/ G1 Y0 R% {
" l; L* g) a6 A( Tvoid cs_r(void) interrupt 2
$ T) q$ A" k, ~$ w3 {% o) b{
, w8 ~* P9 O7 k: pTR0=0;
2 ]3 R7 ?+ C* }3 P* {+ L! P4 v& d' MEX1=0;
* A* F+ s4 E3 W/ }& z! KET0=0;
& Y4 x( Y. h* r3 kflag=1;
; }$ `/ b" H. p( w}) h6 K+ u9 F; w/ e

9 Z5 ^+ R% `& p' |& u  E" s& ?7 t' |: s' G' u
void overtime(void) interrupt 1* O; i7 |1 d: e9 ?) {9 w
{
  v# J2 g3 X2 I  b/ d+ d$ xEX1=0;" @. X9 h& s1 |- Y2 q5 g
TR0=0;  {, }& D% k( q$ l. G& m* t6 q7 D
ET0=0;
' ?1 o: y5 a3 qflag=2;5 o+ v& L& g7 C! C' \
}
! @, P  v" U3 {! a% U' i6 Z
% w0 ?  ^% ]5 z$ o/ l4 W
/ f  x9 C. D# U5 D' L//写数据
5 W$ r. m# e+ V- Y/ v( n6 \void WriteDataLCM(uchar WDLCM)
/ o) T0 ]2 M, |5 A- {) R8 B{3 j8 E4 t! I  B# I
    ReadStatusLCM(); //检测忙6 b7 l, m3 Q7 g# S) p
    LCM_Data=WDLCM;' E* D  H  o. C6 E- K
    LCM_RS=1;" c' N  a: k! R: C8 X
    LCM_RW=0;1 }/ R9 E; Z) m, h7 ]4 p$ a8 j) ~
    LCM_E=0; //若晶振速度太高可以在这后加小的延时
& Z3 C- R% n. M# O' w9 \7 s2 J' i    LCM_E=0; //延时
6 I/ i( F+ l( e' Z9 z! `  A    LCM_E=1;$ r, Q: H  ~  J0 b$ t/ A
}
% A/ t+ n2 J" D1 E% d4 ~2 C3 T9 `3 l
//写指令
6 I5 y# m8 E0 }. p2 {  C' L# R" nvoid WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测* r# v4 ]; m& [/ L+ R
{* F5 h8 ^+ n3 h
    if (BuysC) ReadStatusLCM(); //根据需要检测忙- U* L0 n( k, R6 U3 l$ f/ i$ y
    LCM_Data = WCLCM;
" r& ]8 c- Q3 R" C% U+ w  F0 ]    LCM_RS = 0;
3 v: O( O( p$ h& Q  A! Z- z6 Y    LCM_RW = 0;    , g9 X9 G4 U5 h
    LCM_E = 0;' ?3 ~& G6 q/ }5 y! Q7 z
    LCM_E = 0;
! h! u7 c3 ^7 @1 C    LCM_E = 1;   
% P, I1 p5 N9 d  ]8 ^}6 q0 Y: x6 S1 j  n3 W% T

, `; S' Q: m4 j  {+ R' n//读数据
8 J, C) z  Y0 X) A8 b* O" ruchar ReadDataLCM(void)  a1 h: i! g& K2 e' _9 ^/ e" u
{' u. B2 G/ d) g) b% Z
    LCM_RS = 1;
8 z& C; j/ b6 u8 |+ ~$ E4 L2 Z; h; B( N    LCM_RW = 1;
2 Z$ {6 A& a6 M: n: ~+ t, c    LCM_E = 0;
3 ^1 @4 L) k# G    LCM_E = 0;
( M; p1 P4 W5 ?6 s# B8 y. H    LCM_E = 1;
' G5 v: \9 e* b0 Z4 A& p" w    return(LCM_Data);* S  [2 b4 M) |) }9 p
}5 a' ~$ |. ^3 x

& F: {- |6 @; h% b8 H) I7 J//读状态; h7 w5 O- _, C3 o, M7 a5 t0 A0 s
uchar ReadStatusLCM(void)+ t6 D1 d) |! [3 S. p% M7 S; `. `
{. U7 j! I) L4 W$ x
    LCM_Data=0xFF;
' w3 |: l5 c8 K    LCM_RS=0;$ F" e9 p) N" n, ?1 Y
    LCM_RW=1;
" n5 X# g* G2 m+ p' a- K0 y. k    LCM_E=0;$ Z& I+ p- |" X% m
    LCM_E=0;
8 Z# s4 P  {7 `$ A( P1 z# g    LCM_E=1;
$ M9 U# E  L# I8 ?$ f7 p* E    while(LCM_Data & Busy); //检测忙信号
( o# Q- Q6 ?0 F. I$ J& C0 }    return(LCM_Data);1 ]- T+ v% s6 y7 H+ k( {; `
}
2 q4 E  a# l) Q% D7 u+ Q) g3 G" x' G/ c, `9 e
void LCMInit(void) //LCM初始化
8 B- O- G7 A0 {' Q! P{* g( V: {5 F* `! g: g
    LCM_Data=0;
% F: ]7 |0 O! m4 P; r    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号0 e0 }' s6 B4 Q  e- n3 M
    Delay5Ms();
: B. s, v" ?% x0 I- ?    WriteCommandLCM(0x38,0);
' K8 J% S  T0 f' m: t    Delay5Ms(); " U1 |0 ^; [$ ^0 p
    WriteCommandLCM(0x38,0);
1 U7 ?  R& M- i0 i9 ?  L    Delay5Ms();
9 l) w- q$ S6 r9 Y' ^$ w2 {) [( z- B
    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
5 y6 z! d# y( [1 S2 c" N) g' |- M    WriteCommandLCM(0x08,1); //关闭显示7 W7 e: x' b4 P5 s
    WriteCommandLCM(0x01,1); //显示清屏0 @, @0 m& @6 D4 ?  m2 {5 S
    WriteCommandLCM(0x06,1); // 显示光标移动设置  f8 L( S& L8 y
    WriteCommandLCM(0x0F,1); // 显示开及光标设置
3 w, `0 C  N6 ?' h6 s7 Q$ D; T/ @}
2 |+ P; W) m  @* B6 r
! j' S& M% X: [1 j* `/ B//按指定位置显示一个字符
9 m6 L: c' U( c- |5 U3 k8 E% `2 hvoid DisplayOneChar(uchar X, uchar Y, uchar DData)
4 ^( q& o2 Q& K4 B; f: |9 F/ A{
# h: v5 r2 N6 t+ f( M    Y &= 0x1;
. \1 ^6 c9 ^& H2 \' E; ]( C3 \6 M    X &= 0xF; //限制X不能大于15,Y不能大于1
+ O: @2 y4 h" k( |8 y  |' C7 j    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;3 l" c# q1 {" W6 R* |
    X |= 0x80; //算出指令码: t4 H5 Q  L7 B/ c& i" {
    WriteCommandLCM(X, 1); //发命令字  W0 N: B# `. I' u. ~
    WriteDataLCM(DData); //发数据
- W  G' G7 {9 a}2 u' W5 P3 X; f: A

9 K' m  O( r7 @+ f% E' |. k4 x2 Y//按指定位置显示一串字符
% L9 X( M9 X; m$ W  x6 j+ o- ^void DisplayListChar(uchar X, uchar Y, uchar  *DData)3 O+ u: |! j! F# b! P
{: b6 L( P4 u% @' r, E' G; e5 r" B
    uchar ListLength;2 U7 P" X1 {' h  A, L7 @# p

1 }& M: y' \: T2 X  ListLength = 0;* T/ v3 C$ x, q) s/ H) i
    Y &= 0x1;
1 f1 k9 S( d& P  S  j6 v& u4 }    X &= 0xF; //限制X不能大于15,Y不能大于1
5 ~9 ]' w1 {8 R: w" l    while (DData[ListLength]>0x20) //若到达字串尾则退出
. V6 ^# d9 ?% w4 y        {! ~! X7 K2 e/ n' c
            if (X <= 0xF) //X坐标应小于0xF
* V. `: p/ B1 a+ c- y3 N: Z) k8 m                {
0 B. h+ E; \, O8 a0 L# S                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符( ~0 d9 u7 H3 A/ b% W; o
                    ListLength++;6 y1 S- I- {# n8 [) V: x- P: J
                    X++;2 W# c" o0 H! k( o
                }
# {2 [4 x. g2 F+ e% O, A        }' m' L$ r, E3 e5 Y9 R( z/ E
}
5 @/ ~6 J0 Q8 N
9 ]) x8 ]7 m9 a3 f* ]  _//5ms延时6 K8 K; Y& n+ l+ n$ o$ F
void Delay5Ms(void)
+ T* y1 X* X3 Q. e8 f9 ?5 q* j{- k6 j  l" g( ^( ^6 M% Z
    uint TempCyc = 200;: q+ b: {$ V  [9 u: o/ c6 P
    while(TempCyc--);
4 u, A' O4 o4 N/ T- I8 g: n}% [4 V( y: q* r7 i
  X2 A( U$ @0 C5 |6 F! P
//400ms延时
6 c5 k  F. U7 l% l# [) l: s% uvoid Delay100Ms(void)8 P, w- w; h: e
{) _- ^( u/ w8 e: X0 Q
    uchar TempCycA = 1;
! v; k" T2 H+ @# V    uint TempCycB;
! O+ `* v# ^1 Y( O    while(TempCycA--)
" J+ w" j4 v# _        {
& ?0 Q2 h2 b* b5 s  @. S            TempCycB=7269;
# f) ^: ?! P% x* Y            while(TempCycB--);
0 r* y* e" }" E$ [$ I/ |8 \+ n. C        }. f. N, b) \' g! F$ M: B) k
}
"真诚赞赏,手留余香"
还没有人打赏,支持一下
楼主热帖
帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

招聘斑竹

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

GMT+8, 2025-4-20 08:40

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

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