-
1.
超声波测距
//
晶振
=8M
//MCU=STC10F04XE
//P0.0-P0.6
共阳数码管引脚
//Trig
= P1^0
//Echo
= P3^2
#include
//
包括一个
52
标准内核的头文件
#define uchar unsigned char
//
定义一下方便使用
#define uint
unsignedint
#define ulong
unsigned long
//***********************
************************
sfr
CLK_DIV = 0x97; //
为
STC
单片机定义
,
系统时钟分频
//<
/p>
为
STC
单片机的
IO
口设置地址定义
sfr
P0M1
= 0X93;
sfr
P0M0
= 0X94;
sfr
P1M1
= 0X91;
sfr
P1M0
= 0X92;
sfr
P2M1
= 0X95;
sfr
P2M0
= 0X96;
//******************
*****************************
sbit Trig
= P1^0;
//
产生脉冲引脚
sbit
Echo
= P3^2;
//
回波引脚
sbit test
= P1^1;
//
测试用引脚
uchar code SEG7[10]={0xC0,0xF9,0xA4,0xB
0,0x99,0x92,0x82,0xF8,0x80,0x90};//
数码管<
/p>
0-9
uint distance[4];
//
测距接收缓冲区
ucharge,shi,bai,temp,flag,outcomeH,outcomeL,i;
//
自定义寄存器
bit succeed_flag;
//
测量成功标志
//********
函数声明
void conversion(uinttemp_data);
void delay_20us();
//void
pai_xu();
void main(void)
//
主程序
{
uintdistance_data,a,b;
uchar
CONT_1;
CLK_DIV=0X03; //
系统时钟为
1/8
晶振(
pdf-45
页
)
P0M1 = 0;
//
将<
/p>
io
口设置为推挽输出
P1M1 = 0;
P2M1 = 0;
P0M0 = 0XFF;
P1M0 = 0XFF;
P2M0 = 0XFF;
i=0;
flag=0;
test =0;
1
Trig=0;
//
首先拉低脉冲输入引脚
TMOD=0x11;
//
定时
器
0
,定时器
1
,
16
位工作方式
TR0=1;
//
启动定时器
0
IT0=0;
//
由高电平变低电平,触发外部中断
ET0=1;
//
打开
定时器
0
中断
//ET1=1;
//
打开
定时器
1
中断
EX0=0;
//
关闭外部中断
EA=1;
//
打开总中断
0
while(1)
//
程序循环
{
EA=0;
Trig=1;
delay_20us();
Trig=0;
//
产生
一个
20us
的脉冲,在
Trig
p>
引脚
while(Echo==0);
//
等待
Echo
回波引脚变高电平<
/p>
succeed_flag=0;
//
清测量成功标志
EX0=1;
//
打开外部中断
TH1=0;
//<
/p>
定时器
1
清零
TL1=0;
//<
/p>
定时器
1
清零
TF1=0;
//
TR1=1;
//
启动定时器
1
EA=1;
while(TH1 < 30);//
等待测量的结果,周期
65.535
毫秒(可用中断实现)
TR1=0;
//
关闭定时器
1
EX0=0;
//
关闭外部中断
if(succeed_flag==1)
{
distance_data=outcomeH;
//
测量
结果的高
8
位
distance_data<<=8;
//
放入
1
6
位的高
8
位
distance_data=d
istance_data|outcomeL;//
与低
8<
/p>
位合并成为
16
位结果数据
distance_data*=12;
p>
//
因为定时器默认为
12
分频
distance_data/=58;
//
微秒
的单位除以
58
等于厘米
}
//<
/p>
为什么除以
58
等于厘米,
Y
米
< br>=
(
X
秒
*344
)
/2
//
X
秒
=
(
2*Y
米)
/344 ==
》
X
秒
=0.0058*
Y
米
==
》
厘米
=
微秒
/58
if(succeed_flag==0)
{
distance_data=0;
//
没有回波则清零
test = !test;
//
测试灯变化
}
///
distance[i]=distance_data;
//
将测量结果的数据放入缓冲区
///
i++;
2
///
if(i==3)
///
{
///
dis
tance_data=(distance[0]+distance[1]+distance[2]+di
stance[3])/4;
///
pai_xu();
///
distance_data=distance[1];
a=distance_data;
if(b==a)
CONT_1=0;
if(b!=a) CONT_1++;
if(CONT_1>=3)
{ CONT_1=0;
b=a;
conversion(b);
}
///
i=0;
///
}
}
}
//***********
**************************************************
**
//
外部中断
0
,用做判断回波电平
INTO_()
interrupt 0
//
外部中断是
< br>0
号
{
outcomeH =TH1;
//
取出定时器的值
outcomeL =TL1;
//
取出定时器的值
succeed_flag=1;
//
至成功测量的标志
EX0=0;
//
关闭外部中断
}
//
**************************************************
**************
//
定时器
< br>0
中断
,
用做显示
timer0() interrupt 1
//
定时器
0
中断是
1
号
{
TH0=0xfd; //
写入定时器
0
初始值
TL0=0x77;
switch(flag)
{case 0x00:P0=ge; P2=0xfd;flag++;break;
case
0x01:P0=shi;P2=0xfe;flag++;break;
case 0x02:P0=bai;P2=0xfb;flag=0;break;
}
}
//
**************************************************
***************
/*
//
定时器
1
中断
,
用做超声波测距计时
timer1()
interrupt 3
//
定
时器
0
中断是
1
号
{
TH1=0;
TL1=0;
3
}
*/
//************************************************
******************
//
显示数据转换程序
void conversion(uinttemp_data)
{
ucharge_data,shi_data,bai_data
bai_data=temp_data/100
temp_data=temp_data%100;
//
取余运算
shi_data=temp_data/10
temp_data=temp_data%10;
//
取余运算
ge_data=temp_data;
bai_data=SEG7[bai_data];
shi_data=SEG7[shi_data];
ge_data =SEG7[ge_data];
EA=0;
bai = bai_data;
shi = shi_data;
ge
=ge_data
EA=1;
}
//************
**************************************************
****
void delay_20us()
{
ucharbt
for(bt=0;bt<100;bt++);
}
/*
voidpai_xu()
{
uint t;
if (distance[0]>distance[1])
p>
{t=distance[0];distance[0]=distance[1];di
stance[1]=t;} /*
交换值
if(distance[0]>distance[2])
{t=
distance[2];distance[2]=distance[0];distance[0]=t;
} /*
交换值
if(distance[1]>distance[2])
{t=
distance[1];distance[1]=distance[2];distance[2]=t;
} /*
交换值
}
*/
2.
超声波测距
LCD1602
显示
/*
SMC1602A(16*2)
模拟口线接线方式
连接线图
:
---
------------------------------------------------
|LCM-----51
|
LCM-----51
|
LCM------51
|
---------------------------
-----------------------|
4
|DB0-----P1.0 |
DB4-----P1.4
| RW-------P3.4
|
|DB1-----P1.1 |
DB5-----P1.5 | RS-------P3.3
|
|DB2-----P1.2 |
DB6-----P1.6
| E--------P3.5
|
|DB3-----P1.3 |
DB7-----P1.7 | VLCD
接
< br>1K
电阻到
GND|
---------------
------------------------------------
接线
:模块
TRIG
接
P3.7
ECH0
接
P3.6
本程序源码只供学习参考,不得应用于商业用途,如有需要请联系作者。
[
注
:st
c89c52
使用
12M
或
11.0592M
晶振
,
实测使用
11.0592M]
==============
===============================================*/
#include
//
器件配置文件
#include
#define
RX
P3_6
#define
TX
P3_7
#define LCM_RW
P2_3 //
定义
LCD
引脚
#define LCM_RS
P2_4
#define
LCM_E
P2_2
#define LCM_Data
P1
#define
Key_Data P3_3 //
定义
Keyboard
p>
引脚
#define Key_CLK
P3_2
#define Busy
0x80 //
用于检测
LCM
状态字中的
Busy
标识
voidLCMInit(void);
voidDisplayOneChar(unsigned char X,
unsigned char Y
, unsigned char DData);
voidDisplayListChar(unsigned char X,
unsigned char Y
, unsigned char code
*DData);
void Delay5Ms(void);
void Delay400Ms(void);
void
Decode(unsigned char ScanCode);
voidWriteDataLCM(unsigned char WDLCM);
voidWriteCommandLCM(unsigned char
WCLCM,BuysC);
unsigned char
ReadDataLCM(void);
unsigned char
ReadStatusLCM(void);
unsigned char code
mcustudio[] ={
unsigned char code
email[] =
{
unsigned char code Cls[] =
{
unsigned char
code ASCII[15] =
{'0','1','2','3','4','5','6
','7','8','9','.','-','M'};
static unsigned char DisNum = 0;
//
显示用指针
unsignedint
time=0;
unsigned
long S=0;
bit
flag =0;
unsigned char disbuff[4]
={ 0,0,0,0,};
5
//
写数据
voidWriteDataLCM(unsigned char WDLCM)
{
}
ReadStatusLCM();
//
检测忙
LCM_Data =
WDLCM;
LCM_RS = 1;
LCM_RW =
0;
LCM_E = 0;
//
若晶振速度太高可以在这后加小的延时
LCM_E = 0; //
延时
LCM_E = 1;
//
写指令
void WriteCommandLCM(unsigned char
WCLCM,BuysC) //BuysC
为
0
时忽略忙检测
{
}
if (BuysC) ReadStatusLCM();
//
根据需要检测忙
LCM_Data = WCLCM;
LCM_RS =
0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
//
读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E
= 1;
return(LCM_Data);
}
//
读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data =
0xFF;
LCM_RS =
0;
LCM_RW = 1;
LCM_E = 0;
LCM_E
= 0;
LCM_E = 1;
while (LCM_Data& Busy);
//
检测忙信号
6
}
return(LCM_Data);
void
LCMInit(void) //LCM
初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0);
//
三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
}
WriteCommandLCM(0x38,1); //
显
示模式设置
,
开始要求每次检测忙信号
WriteCommandLCM(0x08,1);
//
关闭显示
WriteCommandLCM(0x01,1);
//
显示清屏
WriteCommandLCM(0x06,1); //
显示光标移动设置
WriteCommandLCM(0x0F,1); //
显示开及光标设置
//
按指定位置显示一个字符
voidDisplayOneChar(unsigned char X,
unsigned char Y
, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //
限制
p>
X
不能大于
15
,
Y
不能大于
1
if (Y) X |= 0x40;
//
当要显示第二行时地址码
+0x40;
X |= 0x80;
//
算出指令码
WriteCommandLCM(X, 1);
//
发命令字
WriteDataLCM(DData);
//
发数据
}
//
按指定位置显示一串字符
voidDisplayListChar(unsigned char X,
unsigned char Y
, unsigned char code
*DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &=
0xF; //
限制
X
不能大于
15
,
Y
不能大于<
/p>
1
while
(DData[ListLength]>0x19)
//
若到达字串尾则退出
{
if (X <= 0xF)
//X
坐标应小于
0xF
{
DisplayOneChar(X,
Y
, DData[ListLength]);
//
显示单个字符
ListLength++;
X++;
}
7
}
}
//5ms
延时
void Delay5Ms(void)
{
unsignedintTempCyc = 5552;
while(TempCyc--);
}
//400ms
延时
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsignedintTempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
/*************************************************
*******/
voidConut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.8)/10;
//
算出来是
MM
if((S>=7000)||flag==1) //
超出测
量范围显示“
-
”
{
flag=0;
DisplayOneChar(0, 1, ASCII[11]);
DisplayOneChar(1, 1,
ASCII[10]);
//
显示点
DisplayOneChar(2, 1,
ASCII[11]);
DisplayOneChar(3, 1, ASCII[11]);
DisplayOneChar(4, 1,
ASCII[11]);
DisplayOneChar(5, 1, ASCII[12]);
//
显示
M
}
else
{
disbuff[0]=S/1000;
disbuff[1]=S/100%10;
disbuff[2]=S/10%10;
disbuff[3]=S%10;
DisplayOneChar(0, 1,
ASCII[disbuff[0]]);
8
DisplayOneChar(1, 1, ASCII[10]);
//
显示点
DisplayOneChar(2, 1,
ASCII[disbuff[1]]);
DisplayOneChar(3,
1, ASCII[disbuff[2]]);
DisplayOneChar(4, 1,
ASCII[disbuff[3]]);
DisplayOneChar(5, 1, ASCII[12]);
//
显示
M
}
}
/**************************************
******************/
void zd0() interrupt 1
//T0
中断用来计数器溢出
,
超过测距范围
{
flag=1;
//
中断溢出标志
RX=0;
}
/*************
*******************************************/
void
StartModule()
{
//
启动模块
TX=1;
//
启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
voidTimer_Count(void)
{
TR0=1;
//
开启计数
while(RX);
//
当<
/p>
RX
为
1
计数并
等待
TR0=0;
//
关闭计数
Conut();
//
计算
9
}
/**************************************
******************/
voiddelayms(unsigned intms)
{
unsigned char
i=100,j;
for(;ms;ms--)
{
while(--i)
{
j=10;
while(--j);
}
}
}
/*************************
********************************/
void
main(void)
{
unsignedintvalA;
unsigned char TempCyc;
Delay400Ms(); //
启动等待,等
LCM
讲入工作状态
LCMInit();
//LCM
初始化
Delay5Ms(); //
延时片刻
(
可不要
)
DisplayListChar(0, 0, mcustudio);
DisplayListChar(0, 1, email);
ReadDataLCM();//
测试用句无意义
for (TempCyc=0; TempCyc<10; TempCyc++)
Delay400Ms();
//
延时
DisplayListChar(0, 1, Cls);
TMOD=0x01;
//
设<
/p>
T0
为方式
1
,
GATE=1
;
TH0=0;
TL0=0;
ET0=1;
//
允许
T0
中断
EA=1;
//
开启总中断
while(1)
{
delayms(60);
RX=1;
StartModule();
for(valA=7510;valA>0;valA--)
{
if(RX==1)
{
Timer_Count();
10
}
}
}
}
3.
超声波测距
LCD12864
p>
显示
/***************
**************************************************
*************/
/*
Name:
LCD12864(S
t7920/St7921)+
超声波测距模块
+STC89C
52
*/
/*
hy-SRF05
超声波测距模块
DEMO
程序
*/
/*
晶振:
11.0592M
*/
/*
接线:模块
< br>TRIG
接
P3.7
ECH0
接
P3.6
*/
/*
RS
接
P24;
*/
/*
RW
接
P23;
*/
/*
E
接
P22;
*/
/*
PSB
接
P27;
*/
/************
**************************************************
****************/
#include
#include
//
引脚定义
sbit
RX
=
P3^6;
sbit
TX
=
P3^7;
sbit RS =
P2^4;
sbit RW = P2^3;
sbit E
= P2^2;
sbit RES
= P2^5;
sbit PSB = P2^7;
sbit PAUSE = P2^6;
#define DataPort P1
//MCU
P1<------> LCM
//Function
Definition
函数声明
voiddelayms(unsigned intms);
void Delay(intnum);
void Init_DS18B20(void);
unsigned char ReadOneChar(void);
voidWriteOneChar(unsigned char dat);
unsignedintReadTemperature(void);
voidclock_out(unsigned char dd);
unsigned char clock_in(void);
unsigned char read_clock(unsigned char
ord);
voidwrite_clock(unsigned char
ord, unsigned char dd);
voidDisp(void);
void id_case1_key(void);
void id_case2_key(void);
voidSet_time(unsigned char sel,bit
sel_1);
11
-
-
-
-
-
-
-
-
-
上一篇:超声波测距C程序
下一篇:LTE切换为题处理案例及切换参数总结