具有实时语音播报功能的超声波测距仪(C程序)_超声波语音测距仪
具有实时语音播报功能的超声波测距仪(C程序)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“超声波语音测距仪”。
#include
//调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255 #define uint unsigned int //无符号整型 宏定义 变量范围0~65535 #include
//数码管段选定义
06 7 uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};//断码 //数码管位选定义
uchar code smg_we[]={0xe0,0xd0,0xb0,0x70};uchar dis_smg[8]
={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
sbit smg_we1 = P3^4;
//数码管位选定义 sbit smg_we2 = P3^5;sbit smg_we3 = P3^6;sbit smg_we4 = P3^7;
sbit c_send
= P3^2;//超声波发射 sbit c_recive = P3^3;//超声波接收
uchar smg_i = 3;
//显示数码管的个位数 bit flag_300ms;
long distance;
//距离 uint set_d;
//距离
uchar flag_csb_juli;
//超声波超出量程
uint flag_time0;
//用来保存定时器0的时候的/***********************语音模块控制IO口的定义************************/ sbit VRST = P2^3;sbit VBUSY= P2^7;sbit VSDA = P2^6;sbit VCS = P2^5;
sbit VSCL = P2^4;uchar yujing[3];
/***************************
语音地址的安排 0-9 :
对应数字0到9 0b
: 点 0c
: 米
0d
: 已超出量程 **************************/
/***********************1ms延时函数*****************************/ void delay_1ms(uint q){ uint i,j;for(i=0;i
for(j=0;j
/***********************小延时函数**************************/ void delay_us(unsigned int us){
while(us--){
_nop_();} }
/***********************三线发码子程序************************/ void Send_threelines(unsigned char addr){
unsigned char i;VRST=0;delay_1ms(5);VRST=1;delay_1ms(20);/* 复位拉高20ms*/ VCS=0;delay_1ms(5);/* 片选拉低5ms */
for(i=0;i
VSCL=0;
if(addr&0x01)
{
VSDA=1;
}
else
VSDA=0;
addr>>=1;
delay_us(150);/* 150us */
VSCL=1;
delay_us(150);/* 150us */ } VCS=1;delay_1ms(200);while(VBUSY == 0);
//忙等待 }
/***********************数码位选函数*****************************/ void smg_we_switch(uchar i){ switch(i){
case 0: smg_we1 = 0;smg_we2 = 1;smg_we3 = 1;smg_we4 = 1;break;
case 1: smg_we1 = 1;smg_we2 = 0;smg_we3 = 1;smg_we4 = 1;break;
case 2: smg_we1 = 1;smg_we2 = 1;smg_we3 = 0;smg_we4 = 1;break;
case 3: smg_we1 = 1;smg_we2 = 1;smg_we3 = 1;smg_we4 = 0;break;} }
/***********************数码显示函数*****************************/ void display(){ static uchar i;
i++;if(i >= smg_i)
i = 0;
smg_we_switch(i);//位选
P1 = dis_smg[i];
//段选
}
/******************小延时函数*****************/ void delay(){ _nop_();
//执行一条_nop_()指令就是1us _nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();}
/*********************超声波测距程序*****************************/ void send_wave(){ c_send = 1;
//10us的高电平触发
delay();c_send = 0;
TH0 = 0;
//给定时器0清零
TL0 = 0;TR0 = 0;
//关定时器0定时
while(!c_recive);
//当c_recive为零时等待
TR0=1;while(c_recive)
//当c_recive为1计数并等待
{
flag_time0 = TH0 * 256 + TL0;
if((flag_time0 > 40000))
//当超声波超过测量范围时,显示3个888
{
TR0 = 0;
flag_csb_juli = 2;
distance = 888;
break;
}
else
{
flag_csb_juli = 1;
} } if(flag_csb_juli == 1){
TR0=0;
//关定时器0定时
distance =flag_time0;
//读出定时器0的时间
distance *= 0.017;
// 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
if((distance > 500))
//距离 = 速度 * 时间
{
distance = 888;
//如果大于3.8m就超出超声波的量程
} }
}
/***********************处理距离函数****************************/ void smg_display(){ dis_smg[0] = smg_du[distance % 10];
//距离取出来放在缓冲区了
dis_smg[1] = smg_du[distance / 10 % 10];dis_smg[2] = smg_du[distance / 100 % 10] & 0x7f;yujing[0] = distance % 10;
//距离放到语音的变量里
yujing[1] = distance / 10 % 10;
yujing[2] = distance / 100 % 10;}
/*********************定时器0、定时器1初始化******************/ void time_init()
{ EA = 1;
//开总中断
TMOD = 0X11;
//定时器0、定时器1工作方式1 ET0 = 0;
//关定时器0中断
TR0 = 1;
//允许定时器0定时
ET1 = 1;
//开定时器1中断
TR1 = 1;
//允许定时器1定时
}
/***************主函数*****************/ void main(){ static uchar value = 5;P0 = P1 = P2 = P3 = 0xff;
//初始化单片机IO口为高电平
send_wave();//测距离函数
smg_display();//处理距离显示函数
time_init();//定时器初始化程序
send_wave();//测距离函数
send_wave();//测距离函数
while(1){
if(flag_300ms == 1)
{
flag_300ms = 0;
send_wave();//测距离函数
smg_display();//处理距离显示函数
value ++;
if(value > 10)//3秒钟自动播放一次
{
value = 0;
if(distance == 888)
{
Send_threelines(0x0d);
//语音播放已超出量程
}
else
{
Send_threelines(yujing[2]);
//语音播放
Send_threelines(0x0b);
Send_threelines(yujing[1]);
Send_threelines(yujing[0]);
Send_threelines(0x0c);
}
}
} } }
/*********************定时器1中断服务程序************************/ void time1_int()interrupt 3 {
static uchar value;
//定时2ms中断一次
TH1 = 0xf8;TL1 = 0x30;
//2ms display();//数码管显示函数
value++;if(value >= 150){
value = 0;
flag_300ms = 1;} }