找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的手机控制小车和机械臂程序

[复制链接]
跳转到指定楼层
楼主
ID:621334 发表于 2019-10-10 22:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
第一写帖子,不好的地方请大家指出
最近做了一辆小车,
具体功能如下:1、4个电机和两个驱动模块实现小车的运动
                      2、用蓝牙模块实现小车的通信问题,实现小车与手机的通信
                      3、机械臂的应用,用舵机实现机械臂的左右前后移动和夹东西(后来因为舵机的扭矩太小,失败了)
                      4 、用时钟配置pwm来控制小车速度
遇到的问题:1、蓝牙模块与手机的通信问题,解决:先要设置波特率,发送的信号是以16进制来发送的,安卓手机下载个串口助手
                    2、舵机的控制问题 :安装时,没有把舵机的方向调好  心得:在机械臂组装时,应把舵机转向正确的角度

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>   
  3. #define uchar unsignrd char
  4. #define uint unsigned int
  5. unsigned char a,aa,b,c,d ;
  6. uint t , count ,num;
  7. sbit   BIN1=P0^4;    //后右端电机输入口       奇数等于1,为往前走
  8. sbit   BIN2=P0^5;
  9. sbit   BIN3=P0^6;    //后左端电机输入口
  10. sbit   BIN4=P0^7;

  11. sbit   FIN1=P0^0;    //前右端电机输入口
  12. sbit   FIN2=P0^1;
  13. sbit   FIN3=P0^2;    //前左端电机输入口
  14. sbit   FIN4=P0^3;

  15. sbit   bi = P1^0;     //蜂鸣器

  16. sbit   p11 = P1^1;     //抓手舵机
  17. sbit   p12 = P1^2;     //前后伸长舵机
  18. sbit   p13 = P1^3;     //上下移动舵机
  19. sbit   p14 = P1^4;     //底层旋转舵机

  20. sbit P14=P1^3;//寻迹左
  21. sbit P15=P1^2;//寻迹中
  22. sbit P16=P1^1;//寻迹右   

  23. void delay_us(uint z)
  24. {
  25.     uint j,k;
  26.   for(j=z;j>0;j--)
  27.     for(k=110;k>0;k--);
  28. }

  29. void delay_ms(uint q)
  30. {
  31.     uint j,k;
  32.   for(j=q;j>0;j--)
  33.     for(k=10;k>0;k--);
  34. }

  35. /*****************小车前进*****************/
  36. void forward()
  37. {   
  38.   if(num<=t)
  39.   {
  40.   BIN3=1;
  41.   BIN1=1;
  42.   FIN3=1;
  43.    FIN1=1;
  44.   }
  45.    
  46.    else
  47.   {BIN3=0;
  48.   BIN1=0;
  49.   FIN3=0;
  50.    FIN1=0;}
  51.    
  52. }

  53. /*****************小车后退*****************/
  54. void back()
  55. {   
  56.   if (num<=t)
  57.   {FIN2=1;
  58.    FIN4=1;  
  59.    BIN2=1;   
  60.    BIN4=1;
  61.   }
  62.   else
  63.    {
  64.    BIN2=0;  
  65.   FIN2=0;
  66.   BIN4=0;
  67.   FIN4=0;}
  68.   }     
  69. /*****************小车右转*****************/
  70. void right()
  71. {   

  72.   if (num<=t)
  73.   {
  74.   FIN3 = 1;
  75.   BIN3 = 1;
  76.   }   
  77.   else
  78.   {    FIN3 = 0;
  79.    BIN3 = 0;
  80.   }

  81.   if (num<=t/6)
  82.   {
  83.    FIN1 = 1;
  84.    BIN1 = 1;
  85.    }
  86.    else
  87.    {
  88.    FIN1 = 0;
  89.    BIN1 = 0;
  90.    }
  91.   }

  92. /*****************小车左转*****************/
  93. void left()
  94. {
  95.     if (num<=t)
  96.   {
  97.   FIN1 = 1;
  98.   BIN1 = 1;
  99.   }   
  100.   else
  101.   {
  102.    FIN1 = 0;
  103.    BIN1 = 0;
  104.   }

  105.   if (num<=t/6)
  106.   {
  107.    FIN3 = 1;
  108.    BIN3 = 1;
  109.    }
  110.    else
  111.    {
  112.    FIN3 = 0;
  113.    BIN3 = 0;
  114.    }
  115.   }


  116. /*****************小车停止*****************/ void stop()
  117. {   
  118.    FIN1=0;
  119.    FIN2=0;

  120.    FIN3=0;
  121.   FIN4=0;

  122.    BIN1=0;
  123.    BIN2=0;

  124.    BIN3=0;
  125.    BIN4=0;
  126. }

  127. /*****************小车加速*****************/

  128. void speed_add()
  129. {   
  130.     if (1<=t<20)
  131.     {t = t+2;}
  132.   if (t==20)
  133.   { t = 20;}
  134.   delay_us(200);   
  135. }

  136. /*****************小车减速*****************/

  137. void speed_down()
  138. {  if (1< t <=20)
  139.     { t = t-2;}
  140.   if (t==1)
  141.   { t = 1;}
  142.   delay_us(200);
  143. }

  144. /*****************小车循迹*****************/
  145. void xunji()
  146. {     
  147.     if((P14==0&&P15==1&&P16==0)||(P14==1&&P15==1&&P16==1))   // 为零时,证明红外
  148. 探测到黑线
  149.   { t = 15; forward();    }
  150.     if(P14==1&&P15==0&&P16==0)
  151.    { t = 10;  left(); }    if(P14==0&&P15==0&&P16==1)
  152.    { t =10; right();}
  153.   if(P14==0&&P15==0&&P16==0)
  154.    {stop();  }
  155.   }



  156. void not_catch ()          //抓手控制
  157. {
  158.   if(count <=4)           
  159.     p11=1;         
  160.   else
  161.     p11=0;
  162. }

  163. void catch()
  164. {
  165.     if(count <=2)           
  166.     p11=1;         
  167.   else
  168.     p11=0;
  169. }

  170. void arm_forward()
  171. {
  172.   if (a == 0x46)
  173.   {
  174.     delay_ms(2);
  175.     if(a == 0x45 && b<4)
  176.     {  
  177.       b=b+1;
  178.     }   
  179.   }
  180.   if (a==0x47)
  181.   {
  182.     delay_ms(2);
  183.     if(a == 0x45 && b>0)
  184.     {  
  185.       b=b-1;
  186.     }   
  187.   }  
  188.   if(count <=b)        
  189.     p12=1;   else
  190.     p12=0;  
  191. }

  192. void arm_turn()
  193. {
  194.   
  195.   if (a == 0x46)
  196.    {
  197.     delay_ms(2);
  198.     if (c<4&&a==0x45)
  199.       {c++;}
  200.                }
  201.   if (a== 0x47)
  202.     {
  203.     delay_ms(2);
  204.     if (c>0&&a==0x45)
  205.       {c--; }
  206.           }
  207.    if(count <=c)           
  208.     p14=1;         
  209.   else
  210.     p14=0;

  211. }




  212. void arm_up()
  213. {   
  214.   if (a == 0x46)
  215.   {
  216.     delay_ms(2);
  217.     if(a == 0x45 && d<4)
  218.     {  
  219.       d=d+1;
  220.     }   
  221.   }
  222.   if (a==0x47)
  223.   {
  224.     delay_ms(2);
  225.     if(a == 0x45 && d>0)
  226.     {        d=d-1;
  227.     }   
  228.   }  
  229.   if(count <=d)        
  230.     p13=1;
  231.   else
  232.     p13=0;  
  233. }

  234. void keep()
  235. {   
  236.   not_catch();   
  237.   if(count <=d)        
  238.     p13=1;
  239.   else  
  240.     p13 = 1;     
  241.   if(count <=c)           
  242.     p14=1;
  243.   else  
  244.     p14 = 1;         
  245.   if(count <=b)        
  246.     p12=1;   
  247.   else
  248.     p12=0;
  249. }

  250. void choose_second()
  251. {   
  252.   while(a != 0x61)       //退出
  253.   {   
  254.   if (a != 0x60)
  255.   {
  256.   keep();
  257.   }
  258.      
  259.    switch(a)
  260.    {
  261.        case 0x41:                 //机械臂前进与后退        
  262. //待修改
  263.                {
  264.             while (a!=0x50)            
  265.              {arm_forward();
  266.               // not_catch();  
  267.             keep();        }
  268.             break;
  269.             }
  270.                                     
  271.            case 0x43 :                //底盘左转与右转  
  272.                 {
  273.             while (a!=0x50)              
  274.             {arm_turn();
  275.             //not_catch();
  276.             keep();
  277.             }  
  278.             break;}
  279.                   
  280.            case 0x62:                  //关抓手
  281.                {not_catch();   
  282.             break;}

  283.        case 0x60:                //开抓手
  284.             {
  285.            catch();
  286.            keep();
  287.            break;
  288.           }

  289.        case 0x44:                        //向上与向下
  290.              {   
  291.            while (a!=0x50)  
  292.             {arm_up();
  293.             //not_catch();
  294.             keep();
  295.                 }  
  296.                   break; }                           
  297.    }
  298.    
  299.    
  300.   }


  301. }
  302. /*****************蓝牙初始化*****************/
  303. void UART_INIT()
  304. {     
  305.     TMOD |= 0x20;   //8位自动重装模式
  306.     PCON = 0x00;         TH1 = 0xfd;
  307.         TL1 = 0xfd;   //9600波特率

  308.         SM0 = 0;
  309.         SM1 = 1;     //串口工作方式1
  310.         REN = 1;     //允许串口接收
  311.     RI = 0;  
  312.         EA = 1;      //开总中断
  313.         ES = 1;      //开串口中断
  314.         TR1 = 1;    //启动定时器1   
  315. }
  316. void init()
  317. {   
  318.     num=0;
  319.     count =0;          //给 num 赋初值
  320.     TMOD |= 0X01;
  321.     TH0=(65536-458)/256;   //调整 t的值改变频率 50HZ
  322.     TL0=(65536-458)%256;

  323.     EA=1;     
  324.     ET0=1;                     
  325.     TR0=1;

  326. }

  327. void chooce()
  328. {    t = 4;
  329.     P0 = 0x00;
  330.      aa = 1;
  331.     b =0;
  332.     c = 0;
  333.     d = 0;
  334.        while(1)
  335.     {
  336.       keep();              
  337.          switch(a)
  338.          {
  339.            case 0x41:                 //前进        //待修改
  340.                {forward();
  341.             break;}      
  342.            case 0x42:                //后退              
  343.            {back();  
  344.             break;}      
  345.            case 0x43 :                //左转                  {left();        
  346.              break;}      
  347.            case 0x44:                 //右转
  348.                {right();  
  349.             break;}      
  350.            case 0x45:                  //停止
  351.                {stop();   
  352.             break;}
  353.        case 0x46:                        //加速
  354.              {speed_add();
  355.                   break; }                 
  356.        case 0x47:                 //减速
  357.               {speed_down();         
  358.                break;}
  359. //       case 0x48:  {break;}            //空情况
  360.                
  361.        case 0x49 :                 //蜂鸣器振动
  362.                   { bi  =0;  
  363.               break;}
  364.      
  365.        case 0x50:                 //小车循迹
  366.                   { xunji();   
  367.               break;}  
  368.        case 0x51:   
  369.               {bi = 1;
  370.              break;}
  371.        case 0x52:
  372.             {  choose_second();
  373.             break;
  374.             }
  375.                              
  376.                                     
  377. }

  378. }
  379. }

  380. /*****************主程序*****************/
  381. void main()
  382. {     
  383.     init();
  384.         UART_INIT();     //串口初始化
  385.       chooce();     //手机控制选择运动
  386. }  

  387. /*****************串口中断*****************/
  388. void UART_SER() interrupt 4
  389. {
  390.     a = SBUF;
  391.     RI = 0;     //清除接收标志
  392. //    SBUF = a;    //将内容返回到手机端,可在手机查看发送内容
  393. //    while(!TI);
  394.     TI = 0;       //写标志清零
  395. }


  396. void time0() interrupt 1 //中断函数
  397. {
  398.   TH0=(65536-458)/256;
  399.   TL0=(65536-458)%256;

  400.   count ++;
  401.   if (count%2 == 0)
  402.   {num ++;}

  403.   if(num>21)
  404.   {   count = 0;
  405.     num=0;  
  406.   }   
  407. }  
复制代码
程序打包:
控制小车和机械臂程序.pdf (202.28 KB, 下载次数: 57)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:328014 发表于 2019-10-10 22:59 | 只看该作者
好东东啊 有原理图吗?
回复

使用道具 举报

板凳
ID:621334 发表于 2019-10-10 23:04 | 只看该作者
51hei团团 发表于 2019-10-10 22:59
好东东啊 有原理图吗?

过几天加上,还没完善这一部分
回复

使用道具 举报

地板
ID:735007 发表于 2020-4-22 10:56 | 只看该作者
晨晨晨晨晨晨 发表于 2019-10-10 23:04
过几天加上,还没完善这一部分

楼主,请问有原理图吗?
回复

使用道具 举报

5#
ID:721592 发表于 2020-5-25 03:15 | 只看该作者
感谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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