找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6831|回復: 1
收起左側(cè)

基于59c52RC單片機的超聲波測距程序 已更新

[復制鏈接]
ID:143793 發(fā)表于 2016-12-27 21:17 | 顯示全部樓層 |閱讀模式
程序更新//2016年12月27日21點
修復bug
程序更新//2016年12月26日23點
修復閃爍問題
增加開機初始化顯示-AA-
增加超聲波模塊檢測  未收到信號時顯示-EE-
距離異常顯示----更改為-EE-
如大家發(fā)現(xiàn)bug記得給我留言!!

源文件還未更新

交流群中有源文件免費下載往下看群號

   
也不能完全說是原創(chuàng) 別人都做爛了
第一次在數(shù)碼之家發(fā)帖支持下哦
文章最后有程序源文件
可直接下載到單片機接上模塊使用
上電一直掃描 距離并顯示出來
因為我用的模塊是必須一直掃描才能顯示
所以測遠距離時候會一閃一閃的
程序限制4-300CM測量距離實際上最長可達到5.7M
具體修改限制的方法可留言問我
技術(shù)交流群533743590新群求zhichi么么噠

圖片

QQ圖片20161223222850.jpg
QQ圖片20161223222859.jpg
QQ圖片20161223222906.jpg
數(shù)碼管模塊簡介

1.采用2片595驅(qū)動數(shù)碼管,需要單片機3路IO口,根據(jù)數(shù)碼管動態(tài)掃描原理進行顯示;

2.寬工作電壓3.3V到5V;

3.PCB板尺寸:71mm*22mm

4.數(shù)碼管型號:0.36 4位共陽


超聲波模塊簡介

接線方式,VCC、trig(控制端)、  echo(接收端)、 GND地線

本產(chǎn)品使用方法:一個控制口發(fā)一個10US以上的高電平,就可以在接收口等待高電平輸出.一有

輸出就可以開定時器計時,當此口變?yōu)榈碗娖綍r就可以讀定時器的值,此時就為此次測距的時間,

方可算出距離.如此不斷的周期測,就可以達到你移動測量的值了~~

模塊工作原理:
(1)采用IO觸發(fā)測距,給至少10us的高電平信號;

(2)模塊自動發(fā)送8個40khz的方波,自動檢測是否有信號返回;

(3)有信號返回,通過IO輸出一高電平,高電平持續(xù)的時間就是

超聲波從發(fā)射到返回的時間.測試距離=(高電平時間*聲速(340M/S))/2


代碼區(qū)

/*



*************街角賣幸福原創(chuàng)****************************
*************轉(zhuǎn)載請注明出處*****************************
----------技術(shù)交流群533743590-------------------------
------------本人QQ1979466583------------------------
對應接線
數(shù)碼管模塊 型號【HC595驅(qū)動的8位數(shù)碼管】
SCLK-P1.2
RCLk-P1.1
DIO-P1.0
超聲波模塊 型號【HC-SR04】
echo--P3.2
trig--P3.3

*/
#include <AT89X51.H>                                                                //頭文件

unsigned char code fseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code segbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char  disbuf[8]={0,0,0,0,0,0,0,0};


//-----------------------------------------------------------------------------
// 函數(shù)原形定義
#define uchar unsigned char
#define uint unsigned int

void main (void);                    // 主函數(shù)
void LED4_Display (void);            // LED顯示
void LED_OUT(uchar X);                // LED單字節(jié)串行移位函數(shù)
void delayms(uint);                    //延時子函數(shù) ms
void jisuan(void);

unsigned char code LED_0F[];        // LED字模表

sbit DIO=P1^0;                //串行數(shù)據(jù)輸入
sbit RCLK=P1^1;                //時鐘脈沖信號——上升沿有效
sbit SCLK=P1^2;                //打入信號————上升沿有效
sbit echo=P3^2;                                                    //echo
sbit trig=P3^3;                                                    //trig



//-----------------------------------------------------------------------------
// 全局變量
uchar LED[8];    //用于LED的8位顯示緩存
uint temp;                                                                                       
uint temp1;
uint a,b;                                                            //定義一個變量a,b  后者用于判斷是否收到信號
//
// 主程序
//
void main(void)                                        //主函數(shù)開始
{   
        uint f;
    echo=0;                                            //先拉低echo,trig引腳
    trig=0;
        f=500;
    while(f>0);                                        //啟動延時  消除第一次上電產(chǎn)生的波動
        {
           LED[3]=16;
      LED[2]=15;
      LED[1]=15;
      LED[0]=16;
         f--;
       }
    EA=1;                                            //開總中斷
    TMOD=0x11;                                        //設(shè)置定時器為方式1
    ET0=1;        //允許定時器中斷  這里主要是防止超聲波模塊未發(fā)送信號
    ET1=1;
    while(1)
    {
        echo=0;//a賦值
        a=0;        
        b=1;
        TH0=0;                                        //定時器裝初值
        TL0=0;
        TH1=(65536-25000)/256;                        //定時器裝初值
        TL1=(65536-25000)%256;
        trig=1;                                        //trig送高
        LED4_Display ();                                //    延時3ms
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        trig=0;                                                                                   //trig送低
        TR1=1;
        while(echo==0);                                    //等待echo變?yōu)楦唠娖?/font>
                if(b==1)                                                                                  判斷是否收到信號
        {
                                                               
            TR1=0;                                        //關(guān)定時器1
            EX0=1;                                        //開外部中斷
            TR0=1;                                        //啟動定時器
            while(a==0);                                    //注意這里!    前面給a賦0 程序停在這里等待中斷
//本來是在這里加上掃描屏幕程序的  發(fā)現(xiàn)有重大BUG索性刪除  
        }
        else
        {
        
            LED[3]=16;
            LED[2]=15;
            LED[1]=15;
            LED[0]=16;
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();

        
        }
    }
}
void waibu() interrupt 0                                //外部中斷服務子程序
{
    temp=TH0;                                    //取出定時器的值
    temp1=TL0;                                                                                    
    EX0=0;                                        //關(guān)閉外部中斷
    TR0=0;                                        //關(guān)閉定時器
    jisuan();                                        //運行計算子程序
    a=1;                                            //a賦值1    程序回到剛才的  while(a)  中因為a的值已變?yōu)?,程序從頭開始
}
void time1() interrupt 1                                  //定時器中斷服務子程序
{
    TH0=0;                                        //重裝初值
    TL0=0;
}

void time2() interrupt 3
{
    TR1=0;
    TH0=(65536-25000)/256;                        //定時器裝初值
    TL0=(65536-25000)%256;
    b=0;
    echo=1;
   
}
void jisuan(void)                                    //計算子程序
{
    uint c,d;                                        //定義一個變量c,d 用來判斷距離
    c=0;                                            //賦值0
    d=0;                                         //給b重新賦值
    LED4_Display ();                                //掃描一下數(shù)碼管
    temp=(temp<<8)+temp1;                            //TH0 TL0合并
    temp=temp/5;                                    //我沒有精確計算 直接除5得出大概值
   
    if(temp>40)                                    //判段距離是否過近
        {
            c=1;
        }
        LED4_Display ();                            //掃描一下數(shù)碼管
    if(temp<40)
        {
         c=0;
        }
        LED4_Display ();
        if(temp<3000)                                            //判斷距離是否過遠
        {
            d=1;
        }
        LED4_Display ();
    if(temp>3000)
        {
         d=0;
        }
    c=c&d;                                                //與運算
    if(c==1)                                                //判斷距離是否正常
        {
                                                            
            LED[3]=temp/1000;                                //數(shù)值分離顯示
            LED[2]=temp%1000/100;
            LED[1]=(temp%1000%100/10)+20;    //這個為什么要加上20呢?  因為這是個位  需要顯示小數(shù)點  
            LED[0]=temp%1000%100%10;
        }
    if(c==0)                                            //判斷距離是否正常
        {
   
            LED[3]=16;
            LED[2]=14;
            LED[1]=14;
            LED[0]=16;
        }
   
}
void delayms(uint xms)                    //延時子函數(shù) ms
    {
        uint i,j;
        for(i=xms;i>0;i--)
            for(j=110;j>0;j--);
    }
   
    //下面的程序是hc595模塊顯示程序
    //每個模塊的程序可以到資料的例程中移植
    //*******************************************************//
void LED4_Display (void)                                //屏幕掃描子函數(shù)   

{
    unsigned char code *led_table;          // 查表指針
    uchar i;
    //顯示第1位
    led_table = LED_0F + LED[0];
    i = *led_table;

    LED_OUT(i);            
    LED_OUT(0x01);        

    RCLK = 0;
    RCLK = 1;
    //顯示第2位
    led_table = LED_0F + LED[1];
    i = *led_table;

    LED_OUT(i);        
    LED_OUT(0x02);        

    RCLK = 0;
    RCLK = 1;
    //顯示第3位
    led_table = LED_0F + LED[2];
    i = *led_table;

    LED_OUT(i);            
    LED_OUT(0x04);   

    RCLK = 0;
    RCLK = 1;
    //顯示第4位
    led_table = LED_0F + LED[3];
    i = *led_table;

    LED_OUT(i);            
    LED_OUT(0x08);        

    RCLK = 0;
    RCLK = 1;

}

void LED_OUT(uchar X)
{
    uchar i;
    for(i=8;i>=1;i--)
    {
        if (X&0x80) DIO=1; else DIO=0;
        X<<=1;
        SCLK = 0;
        SCLK = 1;
    }
}
//下面是顯示數(shù)組
unsigned char code LED_0F[] =
{// 0      1       2       3     4      5       6       7     8      9       A       b     C    d      E    F     -        .
    0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0x8e,0xbf,0x7f,0x00,0x00,
//    20    21     22   23   24   25   26    27   28  29   30
    0x40,0x79,0x24,0x30,0x19,0x12,0x12,0x78,0x00,0x10,0xbf,
};

回復

使用道具 舉報

ID:158248 發(fā)表于 2016-12-28 09:31 來自觸屏版 | 顯示全部樓層
很好的東西,自己嘗試做一個
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表