找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4733|回复: 4
收起左侧

金属循迹小车,1602显示行驶距离及时间

[复制链接]
ID:247090 发表于 2017-11-30 14:58 | 显示全部楼层 |阅读模式
/****************************************************************************
         硬件连接
         P3_6 接驱动模块ENA        使能端,输入PWM信号调节速度
     P3_7 接驱动模块ENB        使能端,输入PWM信号调节速度
         P3_5 接驱动模块ENA        使能端,输入PWM信号调节速度
     P3_4 接驱动模块ENB        使能端,输入PWM信号调节速度

     P0_4 P0_5 接IN1  IN2    当 P0_4=1,P0_5=0; 时左电机正转         驱动蓝色输出端OUT1 OUT2接左电机
     P0_4 P0_5 接IN1  IN2    当 P0_4=0,P0_5=1; 时左电机反转               
     P0_6 P0_7 接IN3  IN4         当 P0_6=1,P0_7=0; 时右电机正转         驱动蓝色输出端OUT3 OUT4接右电机
     P0_6 P0_7 接IN3  IN4         当 P0_6=0,P0_7=1; 时右电机反转

          P0_0 P0_1 接IN1  IN2    当 P0_0=1,P0_1=0; 时左电机正转         驱动蓝色输出端OUT1 OUT2接左电机
     P0_0 P0_1 接IN1  IN2    当 P0_0=0,P0_1=1; 时左电机反转               
     P0_2 P0_3 接IN3  IN4         当 P0_2=1,P0_3=0; 时右电机正转         驱动蓝色输出端OUT3 OUT4接右电机
     P0_2 P0_3 接IN3  IN4         当 P0_2=0,P0_3=1; 时右电机反转
         INT0为P3.2                INT1为P3.3

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

        #include<reg52.h>
        #define uchar unsigned char
        #define uint unsigned int
        sbit P0_4 = P0^4;                 //后轮输入口
        sbit P0_5 = P0^5;
        sbit P0_6 = P0^6;
        sbit P0_7 = P0^7;

        sbit P0_0 = P0^0;                //前轮输入口
        sbit P0_1 = P0^1;
        sbit P0_2 = P0^2;
        sbit P0_3 = P0^3;
               
        sbit P3_6 = P3^6;          //电机使能
        sbit P3_7 = P3^7;
        sbit P3_5 = P3^5;
        sbit P3_4 = P3^4;

        sbit P20 = P2^0;          //金属检测器I/O口                 //左
        sbit P21 = P2^1;                                                        // 中
        sbit P22 = P2^2;                                                        //右
                                                                                       
        sbit rw=P2^5;         //1602
        sbit rs=P2^6;
        sbit en=P2^7;

        uchar code table[]="Distance";
        uchar code table1[]="Time";

        unsigned int motor1=0;         //计左电机码盘脉冲值         (码盘值为20)
        unsigned int motor2=0;         //计右电机码盘脉冲值

        #define Left_moto_pwm     P3_6           //接驱动模块ENA        使能端,输入PWM信号调节速度         (左马达调节PWM)  前
        #define Right_moto_pwm    P3_7           //接驱动模块ENB         (右马达调节PWM)
        #define Left_moto_pwm2     P3_5           //接驱动模块ENA        使能端,输入PWM信号调节速度         (左马达调节PWM)  后
        #define Right_moto_pwm2    P3_4           //接驱动模块ENB         (右马达调节PWM)

        #define Left_moto_go      {P0_4=0,P0_5=1;} //  左电机前进         后          P0_4=0,P0_5=1;
        #define Left_moto_back    {P0_4=1,P0_5=0;} // 左电机后退  后        P0_4=1,P0_5=0                      
        #define Right_moto_go     {P0_6=1,P0_7=0;} //右电机前转         后                P0_6=1,P0_7=0;
        #define Right_moto_back   {P0_6=0,P0_7=1;} //右电机后退         后                P0_6=0,P0_7=1

        #define Left_moto_go2      {P0_2=0,P0_3=1;} //左电机前进        P0_2=0,P0_3=1                           
        #define Left_moto_back2    {P0_2=1,P0_3=0;} //左电机后退          P0_2=1,P0_3=0                      
        #define Right_moto_go2     {P0_0=1,P0_1=0;} //右电机前转        P0_0=1,P0_1=0        
        #define Right_moto_back2   {P0_0=0,P0_1=1;} //右电机后退         P0_0=0,P0_1=1

        #define Left_moto_stop22    {P0_2=0,P0_3=0;} //左电机后退          P0_2=0,P0_3=0                      
        #define Right_moto_stop22     {P0_0=0,P0_1=0;} //右电机前转        P0_0=0,P0_1=0
        #define Left_moto_stop21    {P0_4=0,P0_5=0;} // 左电机后退  后        P0_4=0,P0_5=0                      
        #define Right_moto_stop21     {P0_6=0,P0_7=0;} //右电机前转         后                P0_6=0,P0_7=0;

           unsigned char pwm_val_left  =0;//变量定义
        unsigned char push_val_left =0;// 左电机占空比N/20         推动                           //计算占空比时N的值(人工改变值)
        unsigned char pwm_val_right =0;                                                                                      //通过它来实现PWM的改变(通过FOR循环)
        unsigned char push_val_right=0;// 右电机占空比N/20

        unsigned char pwm_val_left2  =0;//变量定义
        unsigned char push_val_left2 =0;// 左电机占空比N/20         推动                           //计算占空比时N的值(人工改变值)
        unsigned char pwm_val_right2 =0;                                                                                      //通过它来实现PWM的改变(通过FOR循环)
        unsigned char push_val_right2=0;// 右电机占空比N/20

        bit Right_moto_stop=1;
        bit Left_moto_stop =1;

        bit Right_moto_stop2=1;
        bit Left_moto_stop2 =1;
        unsigned  int  time=0;
        uchar num2,shi=0,fen=0,miao=0;           //num2用于时钟部分  
        uint num,num1,num3,sum,num7;  //num,num1,num3用于距离处理部分
        unsigned long num6,S=0,S1=0,S2=0;
        uchar jc; //检测
/**************************1602显示**********************************************/
void delayms(uint xms)//延时函数
{
uint i,j;
for(i=xms;i>0;i--)
        for(j=110;j>0;j--);
}
void write_com(uchar com)
{
rs=0;
en=0;
P1=com;
delayms(5);
en=1;
delayms(5);
en=0;
}
void write_date(uchar date)
{
rs=1;
en=0;
P1=date;
delayms(5);
en=1;
delayms(5);
en=0;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x00+add);                                                  
write_date(0x30+shi);                                                         
write_date(0x30+ge);                                                         

}
void write_juli(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);                                                  
write_date(0x30+shi);                                                         
write_date(0x30+ge);                                                         

}
void led_1602_init()  //1602初始化函数
{
rw=0;
en=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);

               
}
        void timer1()interrupt 3
        {
         TH1=(65536-45872)/256;
         TL1=(65536-45872)%256;
                 num2++;
                if(num2==20)
                {
                 num2=0;
                 miao++;
                 }
                 if(miao==60)
                         {
                         miao=0;
                         fen++;
                         }
                         if(fen==60)
                                 {
                                 fen=0;
                                 shi++;
                                 }
                                 if(shi==24)
                                         {
                                         shi=0;
                                        }
                                
//                write_sfm(8,miao);
//                write_sfm(5,fen);
//                write_sfm(2,shi);
        }
void deal_juli() //测距函数
{
// S=S1*100+S2;
// uint sum;                 
sum=motor1+motor2;        // 求和
num=sum/2.0;          // 求平均值
num1=num/80.0;//求轮子旋转圈数
num3=num1*22.5;//轮子走过的距离 算出来的是cm
S2=num3;
S=S2/100;
S1=S2%100;
// write_juli(9,S);
// write_juli(12,S1);
}
/*********************************************************************************************
外部中断INT0计算电机1的脉冲
/********************************************************************************************/
void intersvr1(void) interrupt 0 using 1
{
        motor1++;       
        if(motor1>=9999)
                motor1=0;       
}
/*********************************************************************************************
外部中断INT1计算电机2的脉冲
/********************************************************************************************/
void intersvr2(void) interrupt 2 using 3
{
        motor2++;
        if(motor2>=9999)
                motor2=0;
}
/************************************************************************/
     void  run(void)        //前进函数
{
     push_val_left  =4;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right =4;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度

         push_val_left2  =4;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right2 =4;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度

         Left_moto_go ;                 //左电机前进
         Right_moto_go ;         //右电机前进

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

         push_val_left2  =0;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right2 =0;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度

         Left_moto_stop21 ;                 //左电机
         Right_moto_stop21 ;         //右电机

         Left_moto_stop22 ;                 //左电机
         Right_moto_stop22 ;         //右电机
}
        void  zuozhuan()
{
         push_val_left  =10;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right =5;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度

         push_val_left2  =5;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right2 =5;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度
         Right_moto_go;
         Right_moto_go2;
         Left_moto_back;
//         Left_moto_back2;
}
        void  youzhuan()
{
         push_val_left  =5;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right =10;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度

         push_val_left2  =5;  //PWM 调节参数1-20   1为最慢,20是最快  改这个值可以改变其速度
         push_val_right2 =5;         //PWM 调节参数1-20   1为最慢,20是最快         改这个值可以改变其速度
         Right_moto_back;
//         Right_moto_back2;
         Left_moto_go;
         Left_moto_go2;
}

/************************************************************************/
/*                    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>=20)
        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>=20)
        pwm_val_right=0;
   }
   else    Right_moto_pwm=0;
}

/************************************************************************/
/*    222222                2PWM调制电机转速2                                   */
/************************************************************************/
/*                    左电机调速                                        */
/*调节push_val_left的值改变电机转速,占空比            */
                void pwm_out_left_moto2(void)
{  
   if(Left_moto_stop2)
   {
    if(pwm_val_left2<=push_val_left2)
               Left_moto_pwm2=1;
        else
               Left_moto_pwm2=0;
        if(pwm_val_left2>=20)
        pwm_val_left2=0;
   }
   else  Left_moto_pwm2=0;
}
/******************************************************************/
/*                    右电机调速                                  */  
   void pwm_out_right_moto2(void)
{
  if(Right_moto_stop2)
   {
    if(pwm_val_right2<=push_val_right2)
               Right_moto_pwm2=1;
        else
               Right_moto_pwm2=0;
        if(pwm_val_right2>=20)
        pwm_val_right2=0;
   }
   else    Right_moto_pwm2=0;
}

/***************************************************/
///*TIMER0中断服务子函数产生PWM信号*/
        void timer0()interrupt 1   using 2
{
     TH0=0Xfe;          //0.1Ms定时
         TL0=0Xa3;
         time++;
         pwm_val_left++;
         pwm_val_right++;
         pwm_out_left_moto();
         pwm_out_right_moto();

         pwm_val_left2++;
         pwm_val_right2++;
         pwm_out_left_moto2();
         pwm_out_right_moto2();

}

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


/**********************循迹程序*****************************/
void SJX()
{
if(P20==0&&P21==0&&P22==0)                //全测到
        jc=0;
        if(P20==1&&P21==0&&P22==1)                //中间测到
        jc=1;
        if(P20==0&&P21==1&&P22==1)                 //左边测到
        jc=2;
    if(P20==1&&P21==1&&P22==0)                 //右边测到
        jc=3;
        if(P20==0&&P21==0&&P22==1)                 //左两测到
        jc=4;
        if(P20==1&&P21==0&&P22==0)                 //右两测到       
        jc=5;
        switch(jc)
         {
     case 0:stop();break;              //全测到     停
          
     case 1:run();break;              //直走
         
         case 2:zuozhuan();break;    //左拐
          
         case 3:youzhuan();break;           //右拐
          
         case 4:zuozhuan();break;           //左两测到   左拐

         case 5:youzhuan();break;           //右两测到   右拐
         }
}

        void main(void)
{

        TMOD=0X11;
        TH0= 0Xfe;                  //0.1ms定时
        TL0= 0Xa3;

        TH1=(65536-45872)/256;
        TL1=(65536-45872)%256;
        EA = 1;                        //中断总开关       
        TR0= 1;
        ET0= 1;
        TR1=1;
        ET1=1;
                  
        EX0 = 1;                 //允许外部中断0中断
        IT0 = 1;                 //1:下沿触发  0:低电平触发
        EX1 = 1;                 //外部中断
        IT1        = 1;
       
        led_1602_init();
        write_com(0x80+0x40);
                for(num6=0;num6<8;num6++)
        {
                 write_date(table[num6]);
                 delayms(1);       
        }
         write_com(0x80+0x00);
                for(num7=0;num7<4;num7++)
        {
                 write_date(table1[num7]);
                 delayms(1);       
        }
               
                write_com(0x80+0x00+4);
                 write_date(':');
                delayms(1);
               
                write_com(0x80+0x00+7);
                 write_date(':');
                delayms(1);       
               
                write_com(0x80+0x00+10);
                 write_date(':');
                delayms(1);
               
                write_com(0x80+0x40+8);
                 write_date(':');
                delayms(1);

                write_com(0x80+0x40+11);
                 write_date('.');
                delayms(1);
               
                write_com(0x80+0x40+14);
                 write_date('M');
                delayms(1);
        while(1)                                                        /*无限循环*/
        {
                  SJX();
            deal_juli();//距离处理函数
                  write_sfm(11,miao);
                write_sfm(8,fen);
                write_sfm(5,shi);
                 write_juli(9,S);
                write_juli(12,S1);
         }
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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