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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2185|回復(fù): 5
收起左側(cè)

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

[復(fù)制鏈接]
ID:428425 發(fā)表于 2020-3-13 11:25 | 顯示全部樓層 |閱讀模式

******************************************************************/
//上電后按下K4鍵程序運(yùn)行,小車進(jìn)行超聲波避障跑
//LCD1602液晶屏上顯示探測(cè)到的實(shí)時(shí)距離

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

//注意程序只做參考之用,要達(dá)到最理想的避障效果,還需要師兄們細(xì)心調(diào)試。

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

#define LCM_Data  P0   //定義液晶屏數(shù)據(jù)口
#define Busy    0x80   //用于檢測(cè)LCM狀態(tài)字中的Busy標(biāo)識(shí)

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

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;//用于存放定時(shí)器時(shí)間值
unsigned long S=0;//用于存放距離的值
bit  flag =0; //量程溢出標(biāo)志位
char a=0;

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

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

void cmg88()//關(guān)數(shù)碼管
{
    DU=1;  
    P0=0X00;
    DU=0;
}
/************************************LCD1602液晶屏驅(qū)動(dòng)函數(shù)************************************************/
//*******************讀狀態(tài)*************************//
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); //檢測(cè)忙信號(hào)
        return(LCM_Data);
}

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

//****************寫指令*************************//
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時(shí)忽略忙檢測(cè)
{
        if (BuysC) ReadStatusLCM(); //根據(jù)需要檢測(cè)忙
        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); //三次顯示模式設(shè)置,不檢測(cè)忙信號(hào)
        delay(5);
        WriteCommandLCM(0x38,0);
        delay(5);
        WriteCommandLCM(0x38,0);
        delay(5);

        WriteCommandLCM(0x38,1); //顯示模式設(shè)置,開始要求每次檢測(cè)忙信號(hào)
        WriteCommandLCM(0x08,1); //關(guān)閉顯示
        WriteCommandLCM(0x01,1); //顯示清屏
        WriteCommandLCM(0x06,1); // 顯示光標(biāo)移動(dòng)設(shè)置
        WriteCommandLCM(0x0c,1); // 顯示開及光標(biāo)設(shè)置
}

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

//**********************按指定位置顯示一串字符*************************//
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) //若到達(dá)字串尾則退出
                {
                        if (X <= 0xF) //X坐標(biāo)應(yīng)小于0xF
                                {
                                        DisplayOneChar(X, Y, DData[ListLength]); //顯示單個(gè)字符
                                        ListLength++;
                                        X++;
                                }
                }
}


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


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

void Forward(void)//前進(jìn)
{

         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)         //向右旋轉(zhuǎn)
{
    IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;

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

void Conut(void)
{
         
    conut1();
        //========顯示部分===========================================
        if((S>=5000)||flag==1) //超出測(cè)量范圍
        {
            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)         ////////////////////////////  剎車障礙物距離        跟車速有關(guān) 可更改
         {        
              a++;
              if(a>=2)
              {
                  a=0;
                  FM=0;
                      Stop();
                      back();  //后退緩沖
                      delay(230);//////////////////////////////////////////        后退緩沖時(shí)間 跟車速有關(guān) 可更改

                  B:Turn_Right();
                        delay(50);                  ///////////////////////////////////  旋轉(zhuǎn)角度 跟環(huán)境復(fù)雜程度有關(guān) 可更改
                        Stop();
                        delay(100);                ////////////////////////////////////   旋轉(zhuǎn)頓挫時(shí)間 視覺效果 可更改
                        StartModule();                                 
                        while(RX==0);
                        TR1=1;                            //開啟計(jì)數(shù)
                    while(RX);                        //當(dāng)RX為1計(jì)數(shù)并等待
                    TR1=0;                                //關(guān)閉計(jì)數(shù)
                        conut1();


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

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

/********************************************************/
void zd0() interrupt 3                  //T0中斷用來計(jì)數(shù)器溢出,超過測(cè)距范圍
{
    flag=1;                         //中斷溢出標(biāo)志
        RX=0;
}

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

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

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

        unsigned int a;
        cmg88();//關(guān)數(shù)碼管
        delay(400); //啟動(dòng)等待,等LCM講入工作狀態(tài)
        LCMInit(); //LCM初始化
        delay(5);//延時(shí)片刻

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


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





智能小車超聲波避障實(shí)驗(yàn).zip

34.76 KB, 下載次數(shù): 5

源程序

回復(fù)

使用道具 舉報(bào)

ID:342451 發(fā)表于 2020-3-13 12:06 | 顯示全部樓層
首先,你一下子粘出來這么多程序,就知道你沒有好好看懂這個(gè)程序,可能不是你寫的吧。拋出那些固定的函數(shù),每個(gè)自定義函數(shù)抬頭都有注釋,你理解下功能,看懂壁障那部分,你就會(huì)改車速了。
回復(fù)

使用道具 舉報(bào)

ID:648281 發(fā)表于 2020-3-13 12:30 | 顯示全部樓層
你好!
PWM 控制會(huì)用到中斷,注意避免和超聲波中斷別產(chǎn)生沖突就好
回復(fù)

使用道具 舉報(bào)

ID:687694 發(fā)表于 2020-3-13 12:59 | 顯示全部樓層
使用帶PWM輸出的單片機(jī),配置好PWM就好,只需要將占空比設(shè)定值與你程序變量關(guān)聯(lián)即可。
回復(fù)

使用道具 舉報(bào)

ID:428425 發(fā)表于 2020-3-13 17:10 | 顯示全部樓層
之一知足 發(fā)表于 2020-3-13 12:06
首先,你一下子粘出來這么多程序,就知道你沒有好好看懂這個(gè)程序,可能不是你寫的吧。拋出那些固定的函數(shù), ...

是的,這個(gè)不是我寫的,本人還有沒有達(dá)到寫出代碼的能力,然而這里也確實(shí)沒有調(diào)速的代碼,所以來求助一下,想知道具體怎么編寫
回復(fù)

使用道具 舉報(bào)

ID:428425 發(fā)表于 2020-3-13 17:11 | 顯示全部樓層
51hei**1140 發(fā)表于 2020-3-13 12:30
你好!
PWM 控制會(huì)用到中斷,注意避免和超聲波中斷別產(chǎn)生沖突就好

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

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久精品久久久久久 | 午夜午夜精品一区二区三区文 | 色综合久久久 | www.888www看片 | 国产精品久久久久久一区二区三区 | 国产精品不卡一区 | 亚洲美女一区二区三区 | 伊人久操 | 成人影院在线观看 | 欧美a在线看 | 成人免费一级视频 | 精品国产一区二区国模嫣然 | 日本污视频 | 一区二区三区高清不卡 | 中文字幕日韩欧美一区二区三区 | 久草视频2 | 免费同性女女aaa免费网站 | 91麻豆蜜桃一区二区三区 | 国产亚洲高清视频 | 亚洲精品v日韩精品 | 9久久精品 | 99这里只有精品 | 91视频在线观看 | 黄色小视频大全 | 超碰一区二区 | 九九视频在线观看视频6 | 国产高清区| 久久久精品久久 | 色999视频| 超碰成人免费 | 视频在线日韩 | 国产成人99久久亚洲综合精品 | 97精品超碰一区二区三区 | 久久91| 欧美成人在线网站 | 91久久国产精品 | 二区av| 日韩在线视频观看 | 2018天天干天天操 | 岛国av一区二区 | 久久久久久久亚洲精品 |