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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2017|回復: 5
打印 上一主題 下一主題
收起左側

怎么在原有的超聲波避障程序里增加PWM調速的功能

[復制鏈接]
跳轉到指定樓層
樓主
ID:428425 發表于 2020-3-13 11:25 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

******************************************************************/
//上電后按下K4鍵程序運行,小車進行超聲波避障跑
//LCD1602液晶屏上顯示探測到的實時距離

/**************************************************************
//重要說明:沒有LCD1602液晶顯示屏的師兄,需要用杜邦線將P0.7接地程序才能正常運行
****************************************************************/

//注意程序只做參考之用,要達到最理想的避障效果,還需要師兄們細心調試。

#include <reg52.h>           //52芯片配置文件
#include <intrins.h>   //包含nop等系統函數
#include "bst_car.h"   //包含bst—v51智能小車頭文件

#define LCM_Data  P0   //定義液晶屏數據口
#define Busy    0x80   //用于檢測LCM狀態字中的Busy標識

sbit DU = P2^6;                   //數碼管段選
sbit WE = P2^7;                   //數碼管位選

sbit LCM_RW=P1^1 ;     //定義LCD引腳
sbit LCM_RS=P1^0 ;
sbit LCM_E=P2^5         ;

unsigned char code Range[] ="==Range Finder==";//LCD1602顯示格式
unsigned char code ASCII[13] = "0123456789.-M";
unsigned char code table[]="Distance:000.0cm";
unsigned char code table1[]="!!! Out of range";

unsigned char disbuff[4]={0,0,0,0};//用于分別存放距離的值0.1mm、mm、cm和m的值

unsigned int  time=0;//用于存放定時器時間值
unsigned long S=0;//用于存放距離的值
bit  flag =0; //量程溢出標志位
char a=0;

//=========================================================================================================================
void delay(unsigned int xms)                                
{
    unsigned int i,j;
        for(i=xms;i>0;i--)                      //i=xms即延時約xms毫秒
    for(j=112;j>0;j--);
}

void Delay10us(unsigned char i)            //10us延時函數 啟動超聲波模塊時使用
{
   unsigned char j;
do{
  j = 10;
  do{
   _nop_();
   }while(--j);
}while(--i);
}  

void cmg88()//關數碼管
{
    DU=1;  
    P0=0X00;
    DU=0;
}
/************************************LCD1602液晶屏驅動函數************************************************/
//*******************讀狀態*************************//
unsigned char ReadStatusLCM(void)
{
        LCM_Data = 0xFF;
        LCM_RS = 0;
        Delay10us(1);
        LCM_RW = 1;
        Delay10us(1);
        do{
        LCM_E = 0;
        Delay10us(1);
        LCM_E = 0;
        Delay10us(1);
        LCM_E = 1;
        Delay10us(1);
        }
        while (LCM_Data & Busy); //檢測忙信號
        return(LCM_Data);
}

/****************寫數據************************/
void WriteDataLCM(unsigned char WDLCM)
{
        ReadStatusLCM(); //檢測忙
        LCM_Data = WDLCM;
        LCM_RS = 1;
        Delay10us(1);
        LCM_RW = 0;
        Delay10us(1);
        LCM_E = 0; //若晶振速度太高可以在這后加小的延時
        Delay10us(1);
        LCM_E = 0; //延時
        Delay10us(1);
        LCM_E = 1;
        Delay10us(1);
}

//****************寫指令*************************//
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測
{
        if (BuysC) ReadStatusLCM(); //根據需要檢測忙
        LCM_Data = WCLCM;
        LCM_RS = 0;
        Delay10us(1);
        LCM_RW = 0;        
        Delay10us(1);
        LCM_E = 0;
        Delay10us(1);
        LCM_E = 0;
        Delay10us(1);
        LCM_E = 1;
        Delay10us(1);
}



//*******************LCM初始化**********************//
void LCMInit(void)
{
        LCM_Data = 0;
        WriteCommandLCM(0x38,0); //三次顯示模式設置,不檢測忙信號
        delay(5);
        WriteCommandLCM(0x38,0);
        delay(5);
        WriteCommandLCM(0x38,0);
        delay(5);

        WriteCommandLCM(0x38,1); //顯示模式設置,開始要求每次檢測忙信號
        WriteCommandLCM(0x08,1); //關閉顯示
        WriteCommandLCM(0x01,1); //顯示清屏
        WriteCommandLCM(0x06,1); // 顯示光標移動設置
        WriteCommandLCM(0x0c,1); // 顯示開及光標設置
}

//*********************按指定位置顯示一個字符***********************//
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
        Y &= 0x1;
        X &= 0xF; //限制X不能大于15,Y不能大于1
        if (Y) X |= 0x40; //當要顯示第二行時地址碼+0x40;
        X |= 0x80; //算出指令碼
        WriteCommandLCM(X, 1); //發命令字
        WriteDataLCM(DData); //發數據
}

//**********************按指定位置顯示一串字符*************************//
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
        unsigned char ListLength;

  ListLength = 0;
        Y &= 0x1;
        X &= 0xF; //限制X不能大于15,Y不能大于1
        while (DData[ListLength]>0x19) //若到達字串尾則退出
                {
                        if (X <= 0xF) //X坐標應小于0xF
                                {
                                        DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符
                                        ListLength++;
                                        X++;
                                }
                }
}


/***************************************************************************/


void  StartModule()                          //啟動超聲波模塊
{
          TX=1;                                             //啟動一次模塊
      Delay10us(2);
          TX=0;
}

void Forward(void)//前進
{

         IN2=1;
         IN3=1;
         IN1=0;
         IN4=0;
}

void Stop(void)        //停車
{

         IN1=0;
         IN2=0;
         IN3=0;
         IN4=0;
}

void back(void)        //后退
{

         IN1=1;
         IN2=0;
         IN3=0;
         IN4=1;
}   
void Turn_Right(void)         //向右旋轉
{
    IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

}
//=========================================================================================================================
/********距離計算程序***************/
void conut1(void)
{
        time=TH1*256+TL1;
        TH1=0;
        TL1=0;
        
                       //此時time的時間單位決定于晶振的頻率,外接晶振為11.0592MHZ
                               //那么1us聲波能走多遠的距離呢?1s=1000ms=1000000us
                                   // 340/1000000=0.00034米
                                   //0.00034米/1000=0.34毫米  也就是1us能走0.34毫米
                                   //但是,我們現在計算的是從超聲波發射到反射接收的雙路程,
                                   //所以我們將計算的結果除以2才是實際的路程
    S=time*0.17+10;//此時計算到的結果為毫米,并且是精確到毫米的后兩位了,有兩個小數點
}

void Conut(void)
{
         
    conut1();
        //========顯示部分===========================================
        if((S>=5000)||flag==1) //超出測量范圍
        {
            a=0;        
            flag=0;
        DisplayListChar(0, 1, table1);
        }
        else
        {
        disbuff[0]=S%10;
            disbuff[1]=S/10%10;
            disbuff[2]=S/100%10;
            disbuff[3]=S/1000;
            DisplayListChar(0, 1, table);
            DisplayOneChar(9, 1, ASCII[disbuff[3]]);
            DisplayOneChar(10, 1, ASCII[disbuff[2]]);        
            DisplayOneChar(11, 1, ASCII[disbuff[1]]);
        DisplayOneChar(12, 1, ASCII[10]);
            DisplayOneChar(13, 1, ASCII[disbuff[0]]);
         }
         //========避障部分===========================================
         if(S<=240)         ////////////////////////////  剎車障礙物距離        跟車速有關 可更改
         {        
              a++;
              if(a>=2)
              {
                  a=0;
                  FM=0;
                      Stop();
                      back();  //后退緩沖
                      delay(230);//////////////////////////////////////////        后退緩沖時間 跟車速有關 可更改

                  B:Turn_Right();
                        delay(50);                  ///////////////////////////////////  旋轉角度 跟環境復雜程度有關 可更改
                        Stop();
                        delay(100);                ////////////////////////////////////   旋轉頓挫時間 視覺效果 可更改
                        StartModule();                                 
                        while(RX==0);
                        TR1=1;                            //開啟計數
                    while(RX);                        //當RX為1計數并等待
                    TR1=0;                                //關閉計數
                        conut1();


                        if(S>340)         ////////////////////////         可直行方向無障礙物距離 跟環境有關 可更改
                        {
        
                            Turn_Right();
                            delay(90);        
                        Stop();                                  //微調前進方向 避免車寬對前進影響
                            delay(200);                  
                            FM=1;
                            Forward();
                        }               
                        else
                       {
                           goto B;                                //若沒轉到空曠方向 回到B點 繼續旋轉一次
                       }
               
               }
               else
                   {
                   Forward();        //無障礙物 直行
               }
        
         }

         else
         {
              a=0;
                   Forward();           //無障礙物 直行
         }
         //=======================================
         
}

/********************************************************/
void zd0() interrupt 3                  //T0中斷用來計數器溢出,超過測距范圍
{
    flag=1;                         //中斷溢出標志
        RX=0;
}

/********超聲波高電平脈沖寬度計算程序***************/
void Timer_Count(void)
{
        TR1=1;                            //開啟計數
        while(RX);                        //當RX為1計數并等待
        TR1=0;                                //關閉計數
    Conut();                        //計算

}
/********************************************************/
void keyscan(void)              //按鍵掃描函數
{
    A:    if(K4==0)                        //判斷是否有按下信號
                {
                    delay(10);                  //延時10ms
                        if(K4==0)                        //再次判斷是否按下
                         {
                            FM=0;               //蜂鳴器響                  
                            while(K4==0);        //判斷是否松開按鍵
                            FM=1;               //蜂鳴器停止  
                          }
                    else
                     {
                       goto A;        //跳轉到A重新檢測
                      }
                }
                else
                {
                  goto A;             //跳轉到A重新檢測
                }
}
/********************************************************/

/*************主程序********************/
void main(void)
{

        unsigned int a;
        cmg88();//關數碼管
        delay(400); //啟動等待,等LCM講入工作狀態
        LCMInit(); //LCM初始化
        delay(5);//延時片刻

        DisplayListChar(0, 0, Range);
        DisplayListChar(0, 1, table);
    TMOD=TMOD|0x10;//設T0為方式1,GATE=1;
    EA=1;                                           //開啟總中斷
    TH1=0;
    TL1=0;         
    ET1=1;             //允許T0中斷
    keyscan() ;  //按鍵掃描


        //=======================================================================================================================                        
         while(1)
        {
                RX=1;
            StartModule();                                 //啟動模塊
        for(a=951;a>0;a--)
            {
                  
               if(RX==1)
                   {
              Timer_Count();                 //超聲波高電平脈沖寬度計算函數
                   }
             }
           }
}





智能小車超聲波避障實驗.zip

34.76 KB, 下載次數: 5

源程序

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:342451 發表于 2020-3-13 12:06 | 只看該作者
首先,你一下子粘出來這么多程序,就知道你沒有好好看懂這個程序,可能不是你寫的吧。拋出那些固定的函數,每個自定義函數抬頭都有注釋,你理解下功能,看懂壁障那部分,你就會改車速了。
回復

使用道具 舉報

板凳
ID:648281 發表于 2020-3-13 12:30 | 只看該作者
你好!
PWM 控制會用到中斷,注意避免和超聲波中斷別產生沖突就好
回復

使用道具 舉報

地板
ID:687694 發表于 2020-3-13 12:59 | 只看該作者
使用帶PWM輸出的單片機,配置好PWM就好,只需要將占空比設定值與你程序變量關聯即可。
回復

使用道具 舉報

5#
ID:428425 發表于 2020-3-13 17:10 | 只看該作者
之一知足 發表于 2020-3-13 12:06
首先,你一下子粘出來這么多程序,就知道你沒有好好看懂這個程序,可能不是你寫的吧。拋出那些固定的函數, ...

是的,這個不是我寫的,本人還有沒有達到寫出代碼的能力,然而這里也確實沒有調速的代碼,所以來求助一下,想知道具體怎么編寫
回復

使用道具 舉報

6#
ID:428425 發表于 2020-3-13 17:11 | 只看該作者
51hei**1140 發表于 2020-3-13 12:30
你好!
PWM 控制會用到中斷,注意避免和超聲波中斷別產生沖突就好

想知道怎么編寫,代碼不是我編寫,我還有沒能編寫代碼的能力,所以來求助下
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 美女日批免费视频 | 欧美老少妇一级特黄一片 | 国产精品国产成人国产三级 | 亚洲成人在线免费 | 99reav | 日韩中文视频 | 91免费电影 | 日韩日韩日韩日韩日韩日韩日韩 | 日韩一区二区三区精品 | 国产精品久久久久久久久久了 | 国产日产精品一区二区三区四区 | 久久久久久久香蕉 | 91精品久久久久久久久99蜜臂 | 亚洲精品免费看 | 狠狠av| 久久久福利 | 久久国内精品 | 久久精品国产a三级三级三级 | 国产真实乱对白精彩久久小说 | 国产视频久 | 国产一区二区在线看 | 日本高清中文字幕 | 成人99| 黑人巨大精品欧美一区二区免费 | 久久狠狠 | 国产福利在线播放麻豆 | 日本精a在线观看 | 亚洲国产精品一区二区三区 | 欧美视频二区 | 成人性视频免费网站 | 在线成人 | 激情国产视频 | 久久一 | 精品久久一区 | 99re6在线视频精品免费 | 日韩欧美视频 | 久久麻豆精品 | 午夜在线小视频 | 亚洲精品一区二区三区丝袜 | 精品国产乱码久久久久久牛牛 | 91五月天 |