久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

51單片機(jī)超聲波四通道端口掃描方式測(cè)距

作者:未知   來源:不詳   點(diǎn)擊數(shù):  更新時(shí)間:2014年08月03日   【字體:

 超聲波四通道測(cè)距:超聲波測(cè)距實(shí)現(xiàn)分為三大塊:

其一是12864帶字庫的液晶驅(qū)動(dòng)程序:
代碼如下:
/////////////////12864驅(qū)動(dòng)程序///////////////////////////
//1寫數(shù)據(jù)
void WriteDataLCD(unsigned char WDLCD)
{
 ReadStatusLCD(); //檢測(cè)忙 
 LCD_RS = 1;
 LCD_RW = 0;
 LCD_Data = WDLCD;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 0;
}
 
//2寫指令
void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC為0時(shí)忽略忙檢測(cè)
{
 if (BuysC) ReadStatusLCD(); //根據(jù)需要檢測(cè)忙 
 LCD_RS = 0;
 LCD_RW = 0; 
 LCD_Data = WCLCD;
 LCD_E = 1; 
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 0;  
}
 
//3讀數(shù)據(jù)
unsigned char ReadDataLCD(void)
{
 LCD_RS = 1; 
 LCD_RW = 1;
 LCD_E = 0;
 LCD_E = 0;
 LCD_E = 1;
 return(LCD_Data);
}
 
//4讀狀態(tài)
unsigned char ReadStatusLCD(void)
{
 LCD_Data = 0xFF; 
 LCD_RS = 0;
 LCD_RW = 1; 
 LCD_E = 1;
 while (LCD_Data & Busy); //檢測(cè)忙信號(hào)
 LCD_E = 0;
 return(LCD_Data);
}
 
void LCDInit(void) //5LCM初始化
{
 WriteCommandLCD(0x30,1); //顯示模式設(shè)置,開始要求每次檢測(cè)忙信號(hào)
 WriteCommandLCD(0x01,1); //顯示清屏
 WriteCommandLCD(0x06,1); // 顯示光標(biāo)移動(dòng)設(shè)置
 WriteCommandLCD(0x0C,1); // 顯示開及光標(biāo)設(shè)置
}
void LCDClear(void) //6清屏
{
 WriteCommandLCD(0x01,1); //顯示清屏
 WriteCommandLCD(0x34,1); // 顯示光標(biāo)移動(dòng)設(shè)置
 WriteCommandLCD(0x30,1); // 顯示開及光標(biāo)設(shè)置
}
 
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
 if(Y<1)
  Y=1;
 if(Y>4)
  Y=4;
 X &= 0x0F; //限制X不能大于16,Y不能大于1
 switch(Y){
case 1:X|=0X80;break;
case 2:X|=0X90;break;
case 3:X|=0X88;break;
case 4:X|=0X98;break;
}
 WriteCommandLCD(X, 0); //這里不檢測(cè)忙信號(hào),發(fā)送地址碼
 WriteDataLCD(DData);
}
 
//9按指定位置顯示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
 unsigned char ListLength,X2;
  ListLength = 0;
  X2=X;
 if(Y<1)
  Y=1;
 if(Y>4)
  Y=4;
 X &= 0x0F; //限制X不能大于16,Y在1-4之內(nèi)
 switch(Y){
case 1:X2|=0X80;break; //根據(jù)行數(shù)來選擇相應(yīng)地址
case 2:X2|=0X90;break;
case 3:X2|=0X88;break;
case 4:X2|=0X98;break;
}
 WriteCommandLCD(X2, 1); //10發(fā)送地址碼
  while (DData[ListLength]>=0x20) //若到達(dá)字串尾則退出
  {
   if (X <= 0x0F) //X坐標(biāo)應(yīng)小于0xF
    {
     WriteDataLCD(DData[ListLength]); //
     ListLength++;
X++;
Delay5Ms();
    }
  }
}
其二是超聲波模塊的檢測(cè)部分程序:該部分程序的超聲波發(fā)射與接受程序沒有采用外部中斷的方式實(shí)現(xiàn)畢竟51單片機(jī)的外部中斷稀少比較珍貴,也最多只能驅(qū)動(dòng)2組,達(dá)不到預(yù)期所需要的。故在本程序中我是才用的端口掃描的方式實(shí)現(xiàn)的。
程序代碼如下:void tran4(void)///可通過設(shè)置K數(shù)值選擇執(zhí)行相應(yīng)的I0發(fā)射超聲波
{
uchar i;
float temp;
TMOD=0XF0;
TMOD |=0X01;
TL0=0X47;
TH0=0XFF;
TR0=0;
ET0=0;//關(guān)閉timme0中斷?
csb4=1;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
 
csb4=0;
TR0=0;
TH0=0;
TL0=0;
while(in4==0);
TR0=1;
while(in4==1);
TR0=0;
temp=(TH0*256+TL0)*1.08/58; //1.08為分頻之后的數(shù)
//蜂鳴器響
if(temp<20)beef=0;
delay_nms(60);
beef=1;
//
if(temp>4000)temp=4000;
dis =(unsigned int)temp;//dis將直接用于顯示函數(shù)
delay_nms(60);
display(dis);
shuju[0]=shuju[0]+3;
for(i=0;i<6;i++)
DisplayOneChar(i,4,shuju[i]); //顯示字庫中的中文數(shù)子
}
超聲波測(cè)距需要:現(xiàn)發(fā)送一組超聲波,當(dāng)超聲波受到障礙物被彈回后經(jīng)超聲波接受線路接受后根據(jù)高低電平進(jìn)行計(jì)算這段時(shí)間,并將該時(shí)間與超聲波傳輸?shù)乃俣戎g的關(guān)系換算成與物體之間的距離:
這就是其三:將接受到發(fā)揮的超聲波所需時(shí)間轉(zhuǎn)換程與物體之間的距離:
換算程序如下:
void display(uint dat)
{
 
uchar i,j,k;//定義變量
i=dat/100;//白
j=dat0/10;//十位
k=dat0;//個(gè)
 
shuju[0]=65;
shuju[1]=i+48;//根據(jù)asc碼值要加48才能正確在液晶上顯示字符(具體參考液晶手冊(cè))
shuju[2]='.';
shuju[3]=j+48;
shuju[4]=k+48;
shuju[5]=109;//或者shuju[4]='m';
}
 
以上三步完成程序也就相當(dāng)容易了:
完整超聲波四通道端口掃描方式測(cè)距程序如下:
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define nop _nop_()
#define LCD_Data P0
#define Busy    0x80 //用于檢測(cè)LCD狀態(tài)字中的Busy標(biāo)識(shí)
 
sbit csb1=P1^0;//tr 40KHz超聲波發(fā)射腳
sbit in1=P1^1;
 
sbit csb2=P1^2;
sbit in2=P1^3;
 
sbit  csb3=P2^2;
sbit  in3=P2^3;
 
sbit in4=P2^0;
sbit  csb4=P2^1;
 
sbit LCD_RS=P3^5;//定義引腳
sbit LCD_RW=P3^6;
sbit LCD_E=P3^4;
//sbit PSB =P3^7;
sbit PSB =P3^1; //PSB腳為12864-12系列的串、并通訊功能切換,我們使用8位并行接口,PSB=1
sbit beef =P2^6;
//LCD顯示字符函數(shù)
void WriteDataLCD(unsigned char WDLCD);
void WriteCommandLCD(unsigned char WCLCD,BuysC);
unsigned char ReadDataLCD(void);
unsigned char ReadStatusLCD(void);
void LCDInit(void);
void LCDClear(void);
//void LCDFlash(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
//void DisplayImage (unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
/////////////////////////////超聲波發(fā)射接收子函數(shù)體
 
void  delay100us();
void delay_nms(uint n);
void tran1(void);
void tran2(void);
void tran3(void);
void tran4(void);
void display(uint dat);
unsigned char  shuju[5];//////////////////////////////字符定義;
 
////////////////////////////////////////////////超聲波發(fā)射接收全局變量
unsigned char flag;
unsigned int tmp,dis,high_time ,low_time ;
///////////////////////////////////////////////
/////////////////////////////////////////////////主程序函數(shù)
void main(void)
{
 
Delay400Ms(); //啟動(dòng)等待,等LCD講入工作狀態(tài)
 LCDInit(); //LCM初始化
 Delay5Ms(); //延時(shí)片刻(可不要)
 
while(1)
{
// uint i;
tran1( );
 
// Delay400Ms();
// Delay400Ms();//通過延時(shí)防止因csb1接收引起中斷
//// display(200);
// for(i=0;i<5;i++)
// DisplayOneChar(i,1,shuju[i]); //顯示字庫中的中文數(shù)子
tran2( );
// Delay400Ms();
// Delay400Ms();//通過延時(shí)防止因csb1接收引起中斷
tran3( );
// Delay400Ms();
// Delay400Ms();//通過延時(shí)防止因csb1接收引起中斷
tran4( );
Delay400Ms();
Delay400Ms();
// Delay400Ms();
// Delay400Ms();//通過延時(shí)防止因csb1接收引起中斷
// LCDClear();//清屏
// Delay400Ms();
// LCDClear();
 
}
}
////////////////////////////////////////////////////
 
//延時(shí)函數(shù)體
void  delay100us()
{
    uchar i;
        for(i=0;i<50;i++)
            ;
}
void delay_nms(uint n)
{
uchar i; 
while(n--)
{
for(i=123;i>0;i--);
}
}
//////超聲波發(fā)射程序
void tran1(void)///可通過設(shè)置K數(shù)值選擇執(zhí)行相應(yīng)的I0發(fā)射超聲波
{
uchar i;
float temp;
TMOD=0XF0;
TMOD |=0X01;
TL0=0X47;
TH0=0XFF;
TR0=0;
ET0=0;//關(guān)閉timme0中斷?
csb1=1;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
 
csb1=0;
TR0=0;
TH0=0;
TL0=0;
while(in1==0);
TR0=1;
while(in1==1);
TR0=0;
temp=(TH0*256+TL0)*1.08/58; //1.08為分頻之后的數(shù)
//蜂鳴器響
if(temp<20)beef=0;
delay_nms(60);
beef=1;
//
if(temp>4000)temp=4000;
dis =(unsigned int)temp;//dis將直接用于顯示函數(shù)
delay_nms(60);
display(dis);
for(i=0;i<6;i++)
DisplayOneChar(i,1,shuju[i]); //顯示字庫中的中文數(shù)子
}
 
void tran2(void)///可通過設(shè)置K數(shù)值選擇執(zhí)行相應(yīng)的I0發(fā)射超聲波
{
uchar i;
float temp;
TMOD=0XF0;
TMOD |=0X01;
TL0=0X47;
TH0=0XFF;
TR0=0;
ET0=0;//關(guān)閉timme0中斷?
csb2=1;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
 
csb2=0;
TR0=0;
TH0=0;
TL0=0;
while(in2==0);
TR0=1;
while(in2==1);
TR0=0;
temp=(TH0*256+TL0)*1.08/58; //1.08為分頻之后的數(shù)
//蜂鳴器響
if(temp<20)beef=0;
delay_nms(60);
beef=1;
//
if(temp>4000)temp=4000;
dis =(unsigned int)temp;//dis將直接用于顯示函數(shù)
delay_nms(60);
display(dis);
shuju[0]=shuju[0]+1;
for(i=0;i<6;i++)
DisplayOneChar(i,2,shuju[i]); //顯示字庫中的中文數(shù)子
}
void tran3(void)///可通過設(shè)置K數(shù)值選擇執(zhí)行相應(yīng)的I0發(fā)射超聲波
{
uchar i;
float temp;
TMOD=0XF0;
TMOD |=0X01;
TL0=0X47;
TH0=0XFF;
TR0=0;
ET0=0;//關(guān)閉timme0中斷?
csb3=1;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
 
csb3=0;
TR0=0;
TH0=0;
TL0=0;
while(in3==0);
TR0=1;
while(in3==1);
TR0=0;
temp=(TH0*256+TL0)*1.08/58; //1.08為分頻之后的數(shù)
//蜂鳴器響
if(temp<20)beef=0;
delay_nms(60);
beef=1;
//
if(temp>4000)temp=4000;
dis =(unsigned int)temp;//dis將直接用于顯示函數(shù)
delay_nms(60);
display(dis);
shuju[0]=shuju[0]+2;
for(i=0;i<6;i++)
DisplayOneChar(i,3,shuju[i]); //顯示字庫中的中文數(shù)子
}
void tran4(void)///可通過設(shè)置K數(shù)值選擇執(zhí)行相應(yīng)的I0發(fā)射超聲波
{
uchar i;
float temp;
TMOD=0XF0;
TMOD |=0X01;
TL0=0X47;
TH0=0XFF;
TR0=0;
ET0=0;//關(guān)閉timme0中斷?
csb4=1;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
 
csb4=0;
TR0=0;
TH0=0;
TL0=0;
while(in4==0);
TR0=1;
while(in4==1);
TR0=0;
temp=(TH0*256+TL0)*1.08/58; //1.08為分頻之后的數(shù)
//蜂鳴器響
if(temp<20)beef=0;
delay_nms(60);
beef=1;
//
if(temp>4000)temp=4000;
dis =(unsigned int)temp;//dis將直接用于顯示函數(shù)
delay_nms(60);
display(dis);
shuju[0]=shuju[0]+3;
for(i=0;i<6;i++)
DisplayOneChar(i,4,shuju[i]); //顯示字庫中的中文數(shù)子
}
///////////////////////////////////
void display(uint dat)
{
 
uchar i,j,k;//定義變量
i=dat/100;//白
j=dat0/10;//十位
k=dat0;//個(gè)
 
shuju[0]=65;
shuju[1]=i+48;
shuju[2]='.';
shuju[3]=j+48;
shuju[4]=k+48;
shuju[5]=109;//或者shuju[4]='m';
}
 
 
 
////////////////////////////////////////////
//1寫數(shù)據(jù)
void WriteDataLCD(unsigned char WDLCD)
{
 ReadStatusLCD(); //檢測(cè)忙 
 LCD_RS = 1;
 LCD_RW = 0;
 LCD_Data = WDLCD;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 0;
}
 
//2寫指令
void WriteCommandLCD(unsigned char WCLCD,BuysC) //BuysC為0時(shí)忽略忙檢測(cè)
{
 if (BuysC) ReadStatusLCD(); //根據(jù)需要檢測(cè)忙 
 LCD_RS = 0;
 LCD_RW = 0; 
 LCD_Data = WCLCD;
 LCD_E = 1; 
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 0;  
}
 
//3讀數(shù)據(jù)
unsigned char ReadDataLCD(void)
{
 LCD_RS = 1; 
 LCD_RW = 1;
 LCD_E = 0;
 LCD_E = 0;
 LCD_E = 1;
 return(LCD_Data);
}
 
//4讀狀態(tài)
unsigned char ReadStatusLCD(void)
{
 LCD_Data = 0xFF; 
 LCD_RS = 0;
 LCD_RW = 1; 
 LCD_E = 1;
 while (LCD_Data & Busy); //檢測(cè)忙信號(hào)
 LCD_E = 0;
 return(LCD_Data);
}
 
void LCDInit(void) //5LCM初始化
{
 WriteCommandLCD(0x30,1); //顯示模式設(shè)置,開始要求每次檢測(cè)忙信號(hào)
 WriteCommandLCD(0x01,1); //顯示清屏
 WriteCommandLCD(0x06,1); // 顯示光標(biāo)移動(dòng)設(shè)置
 WriteCommandLCD(0x0C,1); // 顯示開及光標(biāo)設(shè)置
}
void LCDClear(void) //6清屏
{
 WriteCommandLCD(0x01,1); //顯示清屏
 WriteCommandLCD(0x34,1); // 顯示光標(biāo)移動(dòng)設(shè)置
 WriteCommandLCD(0x30,1); // 顯示開及光標(biāo)設(shè)置
}
 
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
 if(Y<1)
  Y=1;
 if(Y>4)
  Y=4;
 X &= 0x0F; //限制X不能大于16,Y不能大于1
 switch(Y){
case 1:X|=0X80;break;
case 2:X|=0X90;break;
case 3:X|=0X88;break;
case 4:X|=0X98;break;
}
 WriteCommandLCD(X, 0); //這里不檢測(cè)忙信號(hào),發(fā)送地址碼
 WriteDataLCD(DData);
}
 
//9按指定位置顯示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
 unsigned char ListLength,X2;
  ListLength = 0;
  X2=X;
 if(Y<1)
  Y=1;
 if(Y>4)
  Y=4;
 X &= 0x0F; //限制X不能大于16,Y在1-4之內(nèi)
 switch(Y){
case 1:X2|=0X80;break; //根據(jù)行數(shù)來選擇相應(yīng)地址
case 2:X2|=0X90;break;
case 3:X2|=0X88;break;
case 4:X2|=0X98;break;
}
 WriteCommandLCD(X2, 1); //10發(fā)送地址碼
  while (DData[ListLength]>=0x20) //若到達(dá)字串尾則退出
  {
   if (X <= 0x0F) //X坐標(biāo)應(yīng)小于0xF
    {
     WriteDataLCD(DData[ListLength]); //
     ListLength++;
X++;
Delay5Ms();
    }
  }
}
//125ms延時(shí)
void Delay5Ms(void)
{
 unsigned int TempCyc = 5552;
 while(TempCyc--);
}
 
//13400ms延時(shí)
void Delay400Ms(void)
{
 unsigned char TempCycA = 5;
 unsigned int TempCycB;
 while(TempCycA--)
 {
  TempCycB=7269;
  while(TempCycB--);
 };
}
 
以上代碼經(jīng)本人親自測(cè)試基本功能都能實(shí)現(xiàn)最大測(cè)量距離是5米,精度達(dá)到1厘米:
關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 国产片侵犯亲女视频播放 | 一区二区免费 | 欧美最猛性xxxxx亚洲精品 | 97精品国产97久久久久久免费 | 天堂久久久久久久 | 成人一区二区三区视频 | 精品久久久久久亚洲综合网 | 91精品国产色综合久久 | 亚洲综合三区 | 成人三级视频 | 波多野结衣在线观看一区二区三区 | 亚洲bt 欧美bt 日本bt | 黑人巨大精品欧美一区二区一视频 | 日韩电影免费在线观看中文字幕 | 精品日韩一区 | 久久精品一区二区三区四区 | 精品欧美一区二区精品久久久 | 精品1区2区3区4区 | 成人福利网站 | 成人小视频在线观看 | 69福利影院 | 日韩a v在线免费观看 | 亚洲视频一区在线 | 波多野结衣二区 | 成人毛片视频免费 | 视频一二三区 | 91 在线 | 亚洲一区二区三区四区视频 | 99久久婷婷国产综合精品电影 | 人人99 | 日本在线看片 | 亚洲国产一区在线 | 国产午夜精品理论片a大结局 | 涩涩视频网站在线观看 | 第一区在线观看免费国语入口 | 在线视频国产一区 | 全免费a级毛片免费看视频免费下 | 亚洲精品二区 | 国产精品视频导航 | 91精品国产99 | 精品国产乱码久久久久久闺蜜 |