找回密码
 立即注册

QQ登录

只需一步,快速开始

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

循迹小车 1602显示 与测速

[复制链接]
跳转到指定楼层
楼主
ID:385084 发表于 2018-8-10 17:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
        /****************************************************************************
         硬件连接
         P1_6 接驱动模块ENA        使能端,输入PWM信号调节速度
     P1_7 接驱动模块ENB        使能端,输入PWM信号调节速度

     P3_4 P3_5 接IN1  IN2    当 P3_4=1,P3_5=0; 时左电机正转         驱动蓝色输出端OUT1 OUT2接左电机
     P3_4 P3_5 接IN1  IN2    当 P3_4=0,P3_5=1; 时左电机反转               
     P3_6 P3_7 接IN3  IN4         当 P3_6=1,P3_7=0; 时右电机正转         驱动蓝色输出端OUT3 OUT4接右电机
     P3_6 P3_7 接IN3  IN4         当 P3_6=0,P3_7=1; 时右电机反转

     P1_0接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1
     P1_1接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2       
     P1_2接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3
         P1_3接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4
         四路寻迹传感器有信号(白线)为0  没有信号(黑线)为1
         四路寻迹传感器电源+5V GND 取自于单片机板靠近液晶调节对比度的电源输出接口
                                                                                                                                                                                         
         关于单片机电源:本店驱动模块内带LDO稳压芯片,当电池输入最低的电压6V时候可以输出稳定的5V
         分别在针脚标+5 与GND 。这个电源可以作为单片机系统的供电电源。
        ****************************************************************************/

        #include<AT89x51.H>
        #include<intrins.h>

        #define Left_moto_pwm     P1_0           //接驱动模块ENA        使能端,输入PWM信号调节速度
        #define Right_moto_pwm    P1_1           //接驱动模块ENB
        #define Left_moto_go      {P3_4=0,P3_5=1;} //P3_4 P3_5 接IN1  IN2    当 P3_4=0,P3_5=1; 时左电机前进
        #define Left_moto_back    {P3_4=1,P3_5=0;} //P3_4 P3_5 接IN1  IN2    当 P3_4=1,P3_5=0; 时左电机后退               
        #define Right_moto_go     {P3_6=0,P3_7=1;} //P3_6 P3_7 接IN1  IN2         当 P3_6=0,P3_7=1; 时右电机前转
        #define Right_moto_back   {P3_6=1,P3_7=0;} //P3_6 P3_7 接IN1  IN2         当 P3_6=1,P3_7=0; 时右电        

        #define RS_CLR RS=0
    #define RS_SET RS=1

          #define RW_CLR RW=0
          #define RW_SET RW=1

          #define EN_CLR EN=0
          #define EN_SET EN=1

          #define DataPort P0
       
        #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
        #define uchar unsigned char
        #define uint  unsigned int

    uchar display[] =  {0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    uchar display2[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        unsigned char code ASCII[12] =  {'0','1','2','3','4','5','6','7','8','9'};//字库
       

    uchar code  cdis3[ ] = {"TIME:            "};
        uchar code  cdis4[ ] = {"Distants:     cm"};

    unsigned char pwm_val_left  =0;//变量定义
        unsigned char push_val_left =0;// 左电机占空比N/10
        unsigned char pwm_val_right =0;
        unsigned char push_val_right=0;// 右电机占空比N/10
        bit Right_moto_stop=1;
        bit Left_moto_stop =1;
        unsigned  int  time=0;
       
        unsigned char  count1=0;         //计左电机码盘脉冲值
        unsigned char  count2=0;         //计右电机码盘脉冲值
        unsigned char disbuff[5]={0};                                                                                                  //显示缓存
        unsigned char  route=0;
        unsigned char  route1=0;
        unsigned char  route2=0;
        unsigned char cir=0;
        unsigned char cir1=0;


               
  sbit LCD_RS=P2^6;
  sbit LCD_RW=P2^5;
  sbit LCD_EN=P2^7;
       
void delay1(int ms)
{
   unsigned char n;
   while(ms--)
   {
     for(n = 0; n<250; n++)
    {
      _nop_();
      _nop_();
      _nop_();
      _nop_();
    }
   }
}

void Delay(uint num)//延时函数
{
  while( --num );
}

        /****************************LCD1602************************************/
        bit lcd_busy()
{                          
    bit result;
    LCD_RS = 0;
//   LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}

void lcd_wcmd(uchar cmd)
{                          
//   while(lcd_busy());
    LCD_RS = 0;
//    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
    Delay(10);
}

void lcd_wdat(uchar dat)
{                          
//  while(lcd_busy());
    LCD_RS = 1;
//    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
    Delay(10);
}

void lcd_init()
{   
    LCD_RW = 0;
    delay1(15);   
    lcd_wcmd(0x01);      //清除LCD的显示内容            
    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);

    lcd_wcmd(0x0c);      //开显示,不显示光标  
    delay1(5);

    lcd_wcmd(0x01);      //清除LCD的显示内容
    delay1(5);
}

void lcd_pos(uchar pos)
{                          
  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量

}

void play()
{
   uchar  i;
   for(i=0;i<6;i++)
   {
    display2[i]=display[i]+0x30;          
   }
/*         for(j=0;j<2;j++)
   {
    disbuff[j]=disbuff[j]+0x80;          
   }  */

   display2[7]=display[6]/10+0x30;   //时单位数据处理
   display2[6]=display[6]%10+0x30;
         
            
   lcd_pos(0x45);
  // lcd_wdat(display2[7]);   //显示时
  // lcd_wdat(display2[6]);
  // lcd_wdat(0x3a);          //显示':'

   lcd_wdat(display2[5]);   //显示分
   lcd_wdat(display2[4]);
   lcd_wdat(0x3a);          //显示':'

   lcd_wdat(display2[3]);   //显示秒
   lcd_wdat(display2[2]);
   lcd_wdat(0x3a);          //显示':'

   lcd_wdat(display2[1]);   //显示毫秒
   lcd_wdat(display2[0]);  
         
         lcd_pos(0x09);
         lcd_wdat(ASCII[disbuff[3]]);
         lcd_wdat(ASCII[disbuff[2]]);
//         lcd_wdat(0x2E);          //显示'.'
         lcd_wdat(ASCII[disbuff[1]]);
         lcd_wdat(ASCII[disbuff[0]]);
         
          
       
}


/************************************************************************/
    void  run(void)        //前进函数
{
    push_val_left  =10;  //PWM 调节参数1-10   1为最慢,10是最快  改这个值可以改变其速度
          push_val_right =10;         //PWM 调节参数1-10   1为最慢,10是最快         改这个值可以改变其速度
          Left_moto_go ;                 //左电机前进
          Right_moto_go ;         //右电机前进
}

/************************************************************************/
/*                    PWM调制电机转速                                   */
/************************************************************************/
/*                    左电机调速                                        */
/*调节push_val_left的值改变电机转速,占空比            */
                void pwm_out_left_moto(void)
{  
   if(Left_moto_stop)
   {
    if(pwm_val_left<=push_val_left)
               Left_moto_pwm=1;
         else
               Left_moto_pwm=0;
         if(pwm_val_left>=10)
             pwm_val_left=0;
    }
    else  Left_moto_pwm=0;
}
/******************************************************************/
/*                    右电机调速                                  */  
   void pwm_out_right_moto(void)
{
  if(Right_moto_stop)
   {
    if(pwm_val_right<=push_val_right)
               Right_moto_pwm=1;
        else
               Right_moto_pwm=0;
        if(pwm_val_right>=10)
        pwm_val_right=0;
   }
   else    Right_moto_pwm=0;
}
/***************************************************/
///*TIMER0中断服务子函数产生PWM信号         */
/*        void timer0()interrupt 2   using 0
{  
     TH1=0xdc;          //1Ms定时  0XF8         
         TL1=0x00;         //0X30
       
         time++;
          display[0]++;         //0.01S

   if(display[0]==10)
   {
    display[0]=0;
        display[1]++;         //0.1S
   }
   if(display[1]==10)
   {
    display[1]=0;
    display[2]++;         //秒个位
   }
   if(display[2]==10)
   {
    display[2]=0;
    display[3]++;         //秒十位
   }
   if(display[3]==6)
   {
    display[3]=0;
    display[4]++;         //分个位
   }
   if(display[4]==10)
   {
    display[4]=0;
    display[5]++;         //分十位
   }
   if(display[5]==6)
   {
    display[5]=0;
    display[6]++;        //时
   }
   if(display[6]==24)
   {
     display[6]=0;
   }                  
         
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_moto();
         pwm_out_right_moto();
}                 */
/***************************************************/
void Time0(void) interrupt 1 using 1
{
         
   TH0=0xdc;               //10ms定时  0xdc
   TL0=0x00;

   display[0]++;         //0.01S

   if(display[0]==10)
   {
    display[0]=0;
        display[1]++;         //0.1S
   }
   if(display[1]==10)
   {
    display[1]=0;
    display[2]++;         //秒个位
   }
   if(display[2]==10)
   {
    display[2]=0;
    display[3]++;         //秒十位
   }
   if(display[3]==6)
   {
    display[3]=0;
    display[4]++;         //分个位
   }
   if(display[4]==10)
   {
    display[4]=0;
    display[5]++;         //分十位
   }
   if(display[5]==6)
   {
    display[5]=0;
    display[6]++;        //时
   }
   if(display[6]==24)
   {
     display[6]=0;
   }
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_moto();
         pwm_out_right_moto();          
}                  
/***********************测速**************************/
  void intersvr1(void) interrupt 0 using 2

{

                 count1++;
        if(count1>=20) //计到20归零        一圈
          {
                        count1=0;
                        cir++;
                   route=16*cir;
                   if(cir>6)
                   {
                                   cir= 0;
                   }
         }

/* if(route1>9)
         {
            route1=0;
                  route2++;
         }        */       
//          disbuff[3]=route2;
          disbuff[2]=route1%10;
          disbuff[1]=route/10%10;          
    disbuff[0]route%10=;        //

               
       
}


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


        void main(void)
{
   uchar m;
       
        TMOD=0X01;          //设置定时器0为工作方式1
       
        TR0= 1;        //启动定时器0
        ET0= 1;                  //开启定时器0中断
        EA = 1;              //开总中断
       
// TR1= 1;
//        ET1= 1;
       
       
   EX0=1;           //开启外部中断0
   IT0=1;           //下降沿有效
       
        // IE0=0;           //清中断标志位
         //IE1=0;
         
       
        lcd_init();

        lcd_pos(0x40);
   for(m=0;m<16;m++)       
        lcd_wdat(cdis3[m]);
       
        lcd_pos(0x00);             //设置显示位置为第一行
         for(m=0;m<16;m++)
        lcd_wdat(cdis4[m]);        //显示字符
       
       
        while(1)                                                        /*无限循环*/
        {        
                 run();       
                play();
                 
  }
}       

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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