找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2824|回复: 0
打印 上一主题 下一主题
收起左侧

当距离变化过快这个程序就不执行电机的程序了,测量和显示还是可以进行的

[复制链接]
跳转到指定楼层
楼主
ID:194551 发表于 2017-5-28 18:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
附上程序
#include "reg52.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define FOSC 12000000L          //系统频率
#define BAUD 115200             //串口波特率
#define uint unsigned int
#define uchar unsigned char
#define Busy    0x80 //用于检测LCM状态字中的Busy标识
//////液晶屏数据口///////
sbit LCM_RS  =P2^0;//定义液晶屏信号引脚
sbit LCM_RW  =P2^1;
sbit LCM_E   =P2^2;
#define LCM_Data  P0//液晶数端口
unsigned char code uctech[] = {"0123456789ABCDEF:"};
sfr AUXR  = 0x8e;               //辅助寄存器
#define T1MS (65536-FOSC/8000)      //1000MS模式

sbit ONA                =P2^3;//电机1A
sbit ONB                =P2^4;//电机1B
sbit ONC                =P2^6;//电机2A
sbit OND                =P2^7;//电机2B

sbit Echo1              =P3^2;//超声波数据
sbit Trig1              =P2^5;//超声波启动
void delay(unsigned int z)//延时
{
   unsigned int x,y;
    for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}


//1ms延时
void Delay5Ms(void)
{
   delay(5);
}

void WriteDataLCM(unsigned char WDLCM)
{
//ReadStatusLCM(); //检测忙

LCM_RS = 1;
LCM_Data = WDLCM;
Delay5Ms();
LCM_RW = 0;
LCM_E = 1; //若晶振速度太高可以在这后加小的延时
Delay5Ms();
LCM_E = 0; //延时

}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
//if (BuysC) ReadStatusLCM(); //根据需要检测忙

LCM_RS = 0;
LCM_Data = WCLCM;
Delay5Ms();
LCM_RW = 0;
LCM_E = 1;
Delay5Ms();
LCM_E = 0;
}
#if 0
//读数据
unsigned char ReadDataLCM(void)
{
LCM_RS = 1;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
return(LCM_Data);
}

//读状态
unsigned char ReadStatusLCM(void)
{
LCM_Data = ~0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}
#endif
void LCMInit(uchar i) //LCM初始化
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();
WriteCommandLCM(0x38,0);
Delay5Ms();

WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(i,1); // 显示开及光标设置
}

void LCMInitc(uchar i)
{
WriteCommandLCM(0x06,0); //光标归位
WriteCommandLCM(i,0); //关光标,闪烁
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData,uchar i)
{

Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; // 算出指令码


WriteCommandLCM(X,0); //这里不检测忙信号,发送地址码
LCMInitc(i);
Delay5Ms();
LCMInitc(0x0c);
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]>0x20) //若到达字串尾则退出
  {
   if (X <= 0xF) //X坐标应小于0xF
    {
     DisplayOneChar(X, Y,DData[ListLength],0x0c); //显示单个字符
     ListLength++;
     X++;
    }
  }
}


void tim0init()
{

    //AUXR |= 0x80;                   //定时器0为1T模式
    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = 0x66;                  //初始化计时值
    TH0 = 0xfc;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断

     TMOD|=0x11;                   //设T1为方式1,GATE=1;
         EA=1;                           //开启总中断       
         TH1=0;
         TL1=0;         
         ET1=1;             //允许T1中断
         TR1=0;
     EA = 1;
}


WORD U16FLAG;
unsigned int time_c,Dista1;
unsigned char timeH,timeL;
bit succeed_flag;
/********************************************************/
void  StartModule()                         
  {
//    unsigned int distance;
     #if 1
         Trig1=1;   //启动模块              
         delay(1);
         Trig1=0;
     U16FLAG=58477;
     while((!Echo1)&&U16FLAG++);
     TR1=1;                            //开启计数
     U16FLAG=58477;
     while((Echo1)&&U16FLAG++);
     TR1=0;
         time_c=TH1*256+TL1;
         TH1=0;
         TL1=0;
         Dista1=(time_c*1.7)/100;//算出来是CM
         delay(50);
         #endif


  }
void timer1() interrupt 3 using 1
{       
  TH0=0;
  TL0=0;                                                         //中断溢出标志
}

                                                  
uint tim0[20];

//定时器中断
void tm0_isr() interrupt 1 using 1
{
        tim0[0]++;
       
   if(Dista1>110)//加速正转
   {
   tim0[3]=(Dista1-80);

   tim0[2]=65536-FOSC/(tim0[3]*200);
        TL0=tim0[2];
        TH0=tim0[2]>>8;
        switch(tim0[0])
        {
          case 1: ONA=0;ONB=1;ONC=1;OND=1;break;
          case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
          case 3: ONA=1;ONB=1;ONC=0;OND=1;break;
          case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0; break;
          
         
        }

  }
   if(Dista1>80&&Dista1<140)//匀速正转
   {
     tim0[2]=65536-FOSC/3000;
        TL0=tim0[2];
        TH0=tim0[2]>>8;
        switch(tim0[0])
        {
          case 1: ONA=0;ONB=1;ONC=1;OND=1;break;
          case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
          case 3: ONA=1;ONB=1;ONC=0;OND=1;break;
          case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0; break;
          
         
        }

  }
    else if(Dista1<=20)//加速反转
  {
       tim0[3]=(50-Dista1) ;
          
   tim0[2]=65536-FOSC/(tim0[3]*200);
          TL0=tim0[2];
          TH0=tim0[2]>>8;
      switch(tim0[0])
          {
          case 1: ONA=1;ONB=1;ONC=0;OND=1;break;
          case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
          case 3: ONA=0;ONB=1;ONC=1;OND=1;break;
          case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0;break;
          }
         
  }       
  else if(Dista1<=50)//匀速反转
  {  
   tim0[2]=65536-FOSC/3000;
          TL0=tim0[2];
          TH0=tim0[2]>>8;
      switch(tim0[0])
          {
          case 1: ONA=1;ONB=1;ONC=0;OND=1;break;
          case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
          case 3: ONA=0;ONB=1;ONC=1;OND=1;break;
          case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0;break;
          }
         
  }       



  else if(Dista1>50&&Dista1<80)//不转
  {
             
    ONA=1;ONB=1;ONC=1;OND=1;

    tim0[0]=0;

  }
   else if(Dista1>140)//         匀速转   
  {

         tim0[2]=65536-FOSC/6000;
        TL0=tim0[2];
        TH0=tim0[2]>>8;
        switch(tim0[0])
        {
          case 1: ONA=0;ONB=1;ONC=1;OND=1;break;
          case 2: ONA=1;ONB=0;ONC=1;OND=1;break;
          case 3: ONA=1;ONB=1;ONC=0;OND=1;break;
          case 4: ONA=1;ONB=1;ONC=1;OND=0;tim0[0]=0;break;
         
        }
        }


}

       

void main()
{

    tim0init();
        LCMInit(0x0c); //LCM初始化
    Delay5Ms(); //延时片刻(可不要
    DisplayListChar(8, 1,"C");//在指定,列显示字符串
           DisplayListChar(9, 1,"M");//在指定,列显示字符串
    while(1)
        {
          StartModule();
          DisplayOneChar(4,1,uctech[Dista1/1000%10],0x0c);//显示个位
      DisplayOneChar(5,1,uctech[Dista1/100%10],0x0c);//显示个位
      DisplayOneChar(6,1,uctech[Dista1/10%10],0x0c);//显示个位
      DisplayOneChar(7,1,uctech[Dista1%10],0x0c);//显示个位


        }
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表