找回密码
 立即注册

QQ登录

只需一步,快速开始

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

带详细注释的单片机步进小车综合程序与资料

[复制链接]
跳转到指定楼层
楼主


单片机源程序如下:
  1.         /****************************************************************************
  2.          简单寻迹程序:接法
  3.          
  4.      EN1 EN2 PWM输入端,本程序不输入PWM,直接使插上跳线帽,使能输出,这样就能全速运行

  5.      插入蓝牙模块:
  6.          晶振:11。0592M晶振
  7.          请注意跳线帽切换

  8.      P1_0 P1_1 接IN1  IN2    当 P1_0=1,P1_1=0; 时左上电机正转        左上电机接驱动板子输出端(蓝色端子OUT1 OUT2)
  9.          P1_0 P1_1 接IN1  IN2    当 P1_0=0,P1_1=1; 时左上电机反转       

  10.          P1_0 P1_1 接IN1  IN2    当 P1_0=0,P1_1=0; 时左上电机停转       

  11.          P1_2 P1_3 接IN3  IN4    当 P1_2=1,P1_3=0; 时左下电机正转        左下电机接驱动板子输出端(蓝色端子OUT3 OUT4)
  12.          P1_2 P1_3 接IN3  IN4    当 P1_2=0,P1_3=1; 时左下电机反转   

  13.          P1_2 P1_3 接IN3  IN4    当 P1_2=0,P1_3=0; 时左下电机停转       

  14.          P1_4 P1_5 接IN5  IN6    当 P1_4=1,P1_5=0; 时右上电机正转        右上电机接驱动板子输出端(蓝色端子OUT5 OUT6)
  15.          P1_4 P1_5 接IN5  IN6    当 P1_4=0,P1_5=1; 时右上电机反转

  16.          P1_4 P1_5 接IN5  IN6    当 P1_4=0,P1_5=0; 时右上电机停转

  17.          P1_6 P1_7 接IN7  IN8    当 P1_6=1,P1_7=0; 时右下电机正转        右下电机接驱动板子输出端(蓝色端子OUT7 OUT8)
  18.          P1_6 P1_7 接IN7  IN8    当 P1_6=0,P1_7=1; 时右下电机反转

  19.          P1_6 P1_7 接IN7  IN8    当 P1_6=0,P1_7=0; 时右下电机停转
  20.    

  21.      P3_2接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1
  22.      P3_3接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2       
  23.      P3_4接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3
  24.          P3_5接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4
  25.          四路寻迹传感器有信号(白线)为0  没有信号(黑线)为1
  26.          四路寻迹传感器电源+5V GND 取自于单片机板靠近液晶调节对比度的电源输出接口

  27.                                                                                                                                                                                          
  28.          关于单片机电源:本店驱动模块内带LDO稳压芯片,当电池输入6V时时候可以输出稳定的5V
  29.          分别在针脚标+5 与GND 。这个输出电源可以作为单片机系统的供电电源。
  30.         ****************************************************************************/
  31.        
  32.        
  33.         #include<AT89x52.H>
  34.     #include <intrins.h>
  35. #define uchar unsigned char
  36. #define uint unsigned int               
  37. uchar step_g[8]={0x88, 0x99, 0x11, 0x33, 0x22, 0x66, 0x44, 0xcc}; //步进电机前进单步脉冲
  38.         uchar step_b[8]={0xcc, 0x44, 0x66, 0x22, 0x33, 0x11, 0x99, 0x88}; //步进电机后退单步脉冲
  39. uchar step_l[8]={0xc8, 0x49, 0x61, 0x23, 0x32, 0x16, 0x94, 0x8c};//步进电机左转单步脉冲
  40. uchar step_r[8]={0x8c, 0x94, 0x16, 0x32, 0x23, 0x61, 0x49, 0xc8};
  41. //步进电机右转单步脉冲
  42. uchar step_stop[8]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  43.         #define  ECHO  P2_4                                   //超声波接口定义
  44.     #define  TRIG  P2_5                                   //超声波接口定义
  45.         #define Sevro_moto_pwm    P2_7         //接舵机信号端输入PWM信号调节速度
  46. #define Left_1_led        P3_4         //P3_2接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1
  47.         #define Left_2_led        P3_5         //P3_3接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2       

  48.     #define Right_1_led       P3_6         //P3_4接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3
  49.         #define Right_2_led       P3_7       
  50.         #define left     'C'
  51.     #define right    'D'
  52.         #define up       'A'
  53.     #define down     'B'
  54.         #define stop     'F'
  55.         #define Car      '1'           //手机软件1号键
  56.         #define Car1     '2'           //手机软件1号键



  57.         char code str[] =  "收到指令,向前!\n";
  58.         char code str1[] = "收到指令,向后!\n";
  59.         char code str2[] = "收到指令,向左!\n";
  60.         char code str3[] = "收到指令,向右!\n";
  61.         char code str4[] = "收到指令,停止!\n";



  62.         unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
  63.         unsigned char const positon[3]={ 0xfe,0xfd,0xfb};
  64.         unsigned char disbuff[4]          ={ 0,0,0,0,};
  65.     unsigned char posit=0;

  66.            unsigned char pwm_val_left  = 0;//变量定义
  67.         unsigned char push_val_left =13;//舵机归中,产生约,1.5MS 信号
  68.         unsigned int  time=0;                    //时间变量
  69.         unsigned int  timer1=0;                    //时间变量
  70.     unsigned int  timer=0;                        //延时基准变量

  71.         unsigned long S=0;                                //计算出超声波距离值
  72.     unsigned long S1=0;
  73.         unsigned long S2=0;
  74.         unsigned long S3=0;
  75.         unsigned long S4=0;

  76.         bit  flag_REC=0;                                 //串行接收标去位
  77.         bit  flag    =0;  
  78.         bit  flag_xj =0;
  79.         bit  flag_bj =0;

  80.         unsigned char  i=0;
  81.         unsigned char  dat=0;
  82.     unsigned char  buff[5]=0;       //接收缓冲字节


  83.    
  84. /************************************************************************/       
  85. //延时函数       
  86.    void delay(unsigned int k)
  87. {   
  88.      unsigned int x,y;
  89.          for(x=0;x<k;x++)
  90.            for(y=0;y<2000;y++);
  91. }
  92. /************************************************************************/
  93. //前速前进
  94.      void  run(void)
  95. {
  96.          uchar step_g[8]={0x88, 0x99, 0x11, 0x33, 0x22, 0x66, 0x44, 0xcc};
  97. }

  98. //前速后退
  99.      void  backrun(void)
  100. {
  101.    
  102.          uchar step_b[8]={0xcc, 0x44, 0x66, 0x22, 0x33, 0x11, 0x99, 0x88};
  103. }

  104. //左转
  105.      void  leftrun(void)
  106. {
  107.    
  108.         uchar step_l[8]={0xc8, 0x49, 0x61, 0x23, 0x32, 0x16, 0x94, 0x8c};
  109. }

  110. //右转
  111.      void  rightrun(void)
  112. {
  113.   uchar step_r[8]={0x8c, 0x94, 0x16, 0x32, 0x23, 0x61, 0x49, 0xc8};  

  114. }
  115. //STOP
  116.      void  stoprun(void)
  117. {
  118. uchar step_stop[8]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  119. }
  120. /************************************************************************/
  121.      void  StartModule()                       //启动测距信号
  122.    {
  123.           TRIG=1;                                        
  124.           _nop_();
  125.           _nop_();
  126.           _nop_();
  127.           _nop_();
  128.           _nop_();
  129.           _nop_();
  130.           _nop_();
  131.           _nop_();
  132.           _nop_();
  133.           _nop_();
  134.           _nop_();
  135.           _nop_();
  136.           _nop_();
  137.           _nop_();
  138.           _nop_();
  139.           _nop_();
  140.           _nop_();
  141.           _nop_();
  142.           _nop_();
  143.           _nop_();
  144.           _nop_();
  145.           TRIG=0;
  146.    }
  147. /***************************************************/
  148.           void Conut(void)                   //计算距离
  149.         {
  150.           while(!ECHO);                       //当RX为零时等待
  151.           TR0=1;                               //开启计数
  152.           while(ECHO);                           //当RX为1计数并等待
  153.           TR0=0;                                   //关闭计数
  154.           time=TH0*256+TL0;                   //读取脉宽长度
  155.           TH0=0;
  156.           TL0=0;
  157.           S=(time*1.7)/100;        //算出来是CM
  158.           disbuff[0]=S%1000/100;   //更新显示
  159.           disbuff[1]=S%1000%100/10;
  160.           disbuff[2]=S%1000%10 %10;
  161.         }
  162. /************************************************************************/
  163. //字符串发送函数
  164.           void send_str( )
  165.                    // 传送字串
  166.     {
  167.             unsigned char i = 0;
  168.             while(str[i] != '\0')
  169.            {
  170.                 SBUF = str[i];
  171.                 while(!TI);                                // 等特数据传送
  172.                 TI = 0;                                        // 清除数据传送标志
  173.                 i++;                                        // 下一个字符
  174.            }       
  175.     }
  176.        
  177.                   void send_str1( )
  178.                    // 传送字串
  179.     {
  180.             unsigned char i = 0;
  181.             while(str1[i] != '\0')
  182.            {
  183.                 SBUF = str1[i];
  184.                 while(!TI);                                // 等特数据传送
  185.                 TI = 0;                                        // 清除数据传送标志
  186.                 i++;                                        // 下一个字符
  187.            }       
  188.     }       

  189.                           void send_str2( )
  190.                    // 传送字串
  191.     {
  192.             unsigned char i = 0;
  193.             while(str2[i] != '\0')
  194.            {
  195.                 SBUF = str2[i];
  196.                 while(!TI);                                // 等特数据传送
  197.                 TI = 0;                                        // 清除数据传送标志
  198.                 i++;                                        // 下一个字符
  199.            }       
  200.     }       
  201.                    
  202.                           void send_str3()
  203.                    // 传送字串
  204.     {
  205.             unsigned char i = 0;
  206.             while(str3[i] != '\0')
  207.            {
  208.                 SBUF = str3[i];
  209.                 while(!TI);                                // 等特数据传送
  210.                 TI = 0;                                        // 清除数据传送标志
  211.                 i++;                                        // 下一个字符
  212.            }       
  213.     }       

  214.               void send_str4()
  215.                    // 传送字串
  216.     {
  217.             unsigned char i = 0;
  218.             while(str4[i] != '\0')
  219.            {
  220.                 SBUF = str4[i];
  221.                 while(!TI);                                // 等特数据传送
  222.                 TI = 0;                                        // 清除数据传送标志
  223.                 i++;                                        // 下一个字符
  224.            }       
  225.     }       
  226.                    
  227. /************************************************************************/
  228.     void Display(void)                                  //扫描数码管
  229.         {
  230.          if(posit==0)
  231.          {P0=(discode[disbuff[posit]])&0x7f;}//产生点
  232.          else
  233.          {P0=discode[disbuff[posit]];}

  234.           if(posit==0)
  235.          { P2_1=0;P2_2=1;P2_3=1;}
  236.           if(posit==1)
  237.           {P2_1=1;P2_2=0;P2_3=1;}
  238.           if(posit==2)
  239.           {P2_1=1;P2_2=1;P2_3=0;}
  240.           if(++posit>=3)
  241.           posit=0;
  242.         }

  243. void  COMM( void )                      
  244.   {
  245.                   push_val_left=5;          //舵机向左转90度
  246.                   timer=0;
  247.                   while(timer<=4000); //延时400MS让舵机转到其位置
  248.                   StartModule();          //启动超声波测距
  249.           Conut();                           //计算距离
  250.                   S2=S;  
  251.   
  252.                   push_val_left=23;          //舵机向右转90度
  253.                   timer=0;
  254.                   while(timer<=4000); //延时400MS让舵机转到其位置
  255.                   StartModule();          //启动超声波测距
  256.           Conut();                          //计算距离
  257.                   S4=S;        
  258.        

  259.                   push_val_left=13;          //舵机归中
  260.                   timer=0;
  261.                   while(timer<=4000); //延时400MS让舵机转到其位置
  262.                   StartModule();          //启动超声波测距
  263.           Conut();                          //计算距离
  264.                   S1=S;        

  265.           if((S2<20)||(S4<20)) //只要左右各有距离小于,20CM小车后退
  266.                   {
  267.                   backrun();                   //后退
  268.                   timer=0;
  269.                   while(timer<=4000);
  270.                   }
  271.                   
  272.                   if(S2>S4)                 
  273.                      {
  274.                                 rightrun();          //车的左边比车的右边距离小        右转       
  275.                         timer=0;
  276.                         while(timer<=4000);
  277.                      }                                     
  278.                        else
  279.                      {
  280.                        leftrun();                //车的左边比车的右边距离大        左转
  281.                        timer=0;
  282.                        while(timer<=4000);
  283.                      }
  284.                                             
  285. }
  286. /************************************************************************/
  287. /*                    PWM调制舵机信号                                 */
  288. /************************************************************************/
  289. /*                    左电机调速                                        */
  290. /*调节push_val_left的值改变电机转速,占空比            */
  291.                 void pwm_Servomoto(void)
  292. {  

  293.     if(pwm_val_left<=push_val_left)
  294.                Sevro_moto_pwm=1;
  295.         else
  296.                Sevro_moto_pwm=0;
  297.         if(pwm_val_left>=200)
  298.         pwm_val_left=0;

  299. }
  300. /***************************************************/
  301. ///*TIMER1中断服务子函数产生PWM信号*/
  302.         void time1()interrupt 3   using 2
  303. {       
  304.      TH1=(65536-100)/256;          //100US定时
  305.          TL1=(65536-100)%256;
  306.          timer++;                                  //定时器100US为准。在这个基础上延时
  307.          pwm_val_left++;
  308.          pwm_Servomoto();

  309.          timer1++;                                 //2MS扫一次数码管
  310.          if(timer1>=20)
  311.          {
  312.          timer1=0;
  313.          Display();       
  314.          }
  315. }

  316. /************************************************************************/
  317. void sint() interrupt 4          //中断接收3个字节
  318. {

  319.     if(RI)                         //是否接收中断
  320.     {
  321.        RI=0;
  322.        dat=SBUF;
  323.        if(dat=='O'&&(i==0)) //接收数据第一帧
  324.          {
  325.             buff[i]=dat;
  326.             flag=1;        //开始接收数据
  327.          }
  328.        else
  329.       if(flag==1)
  330.      {
  331.       i++;
  332.       buff[i]=dat;
  333.       if(i>=2)
  334.       {i=0;flag=0;flag_REC=1 ;}  // 停止接收
  335.      }
  336.          }
  337. }
  338. /*********************************************************************/                 
  339. /*--主函数--*/
  340.         void main(void)
  341. {
  342.         TMOD=0x11;  
  343.     TH1=(65536-100)/256;          //100US定时
  344.         TL1=(65536-100)%256;
  345.         TH0=0;
  346.         TL0=0;

  347.     T2CON=0x34;
  348.         T2MOD=0x00;
  349.         RCAP2H=0xFF;
  350.         RCAP2L=0xDC;
  351.     SCON=0x50;  
  352.     PCON=0x00;

  353.     PS=1;



  354.     TR1=1;
  355.         ET1=1;
  356.         ES=1;
  357.     EA=1;  
  358.        
  359.         delay(100);
  360.     push_val_left=13;          //舵机归中
  361.          
  362.         while(1)                                                        /*无限循环*/
  363.         {
  364.        
  365.          
  366.                          
  367.                   while(flag_xj)                           //循线标志位
  368.                   {
  369.                                if(flag_REC==1)
  370.                                  {
  371.                                   stoprun();
  372.                                   break;
  373.                                  }
  374.                     
  375.                                  if(Left_2_led==0&&Right_1_led==0)
  376.                           run();

  377.                           else
  378.                          {                            
  379.                             if(Right_1_led==1&&Left_2_led==0)                //右边检测到黑线
  380.                                   {          
  381.                               uchar step_l[8]={0xc8, 0x49, 0x61, 0x23, 0x32, 0x16, 0x94, 0x8c};                                     //右边两个电机反转
  382.                                   }
  383.                                
  384.                                 if(Left_2_led==1&&Right_1_led==0)            //左边检测到黑线
  385.                                   {
  386.                                     uchar step_r[8]={0x8c, 0x94, 0x16, 0x32, 0x23, 0x61, 0x49, 0xc8};        ;               
  387.                              }
  388.                           }

  389.                   }


  390.                          while(flag_bj)                       /*无限循环*/
  391.            {
  392.        
  393.                if(timer>=1000)          //100MS检测启动检测一次
  394.              {
  395.                timer=0;
  396.                    StartModule(); //启动检测
  397.            Conut();                  //计算距离
  398.            if(S<20)                  //距离小于20CM
  399.                    {
  400.                    stoprun();          //小车停止
  401.                    COMM();                   //方向函数
  402.                    }
  403.                    else
  404.                    if(S>30)                  //距离大于,30CM往前走
  405.                    run();
  406.              }

  407.                          if(flag_REC==1)
  408.                         {
  409.                           push_val_left=13;          //舵机归中
  410.                           stoprun();
  411.                           break;
  412.                         }
  413.           }

  414.                



  415.           if(flag_REC==1)                                    //
  416.            {
  417.                 flag_REC=0;
  418.                 if(buff[0]=='O'&&buff[1]=='N')        //第一个字节为O,第二个字节为N,第三个字节为控制码
  419.                 switch(buff[2])
  420.              {
  421.                       case up :                                                    // 前进
  422.                           send_str( );
  423.                           flag_xj=0;
  424.                           flag_bj=0;
  425.                           run();
  426.                           break;

  427.                       case down:                                                // 后退
  428.                           send_str1( );
  429.                           flag_xj=0;
  430.                           flag_bj=0;
  431.                           backrun();
  432.                           break;

  433.                       case left:                                                // 左转
  434.                           send_str2( );
  435.                           flag_xj=0;
  436.                           flag_bj=0;
  437.                           leftrun();
  438.                           break;

  439.                       case right:                                                // 右转
  440.                           send_str3( );
  441.                           flag_xj=0;
  442.                           flag_bj=0;
  443.                           rightrun();
  444.                           break;

  445.                       case stop:                                                // 停止
  446.                           send_str4( );
  447.                           flag_xj=0;
  448.                           flag_bj=0;
  449.                           stoprun();
  450.                           break;

  451.                           case Car :                                                //                
  452.                           flag_xj=1;
  453.                           break;

  454.                           case Car1 :                                                //                
  455.                           flag_bj=1;
  456.                           break;
  457.              }
  458.       
  459.                                          
  460.          }
  461.         }
  462. }                                  
  463.        
复制代码

所有资料51hei提供下载:
APP整合综合程序,步进小车.zip (90.38 KB, 下载次数: 11)
单独功能的步进小车接线图.pdf (52.59 KB, 下载次数: 10)



评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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