找回密码
 立即注册

QQ登录

只需一步,快速开始

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

蓝牙循迹小车源程序

[复制链接]
跳转到指定楼层
楼主
ID:267314 发表于 2017-12-26 19:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  1. #include <reg52.h>
  2. #define uchar unsigned char         
  3. #define uint unsigned int
  4. sbit in1=P1^0;      
  5. sbit in2=P1^1;
  6. sbit in3=P1^2;
  7. sbit in4=P1^3;
  8. sbit ENA=P1^4;      
  9. sbit ENB=P1^5;
  10. sbit led=P2^3;
  11. uchar count_flag=0;                        //当第1个字符接收完成后,置count_flag=1
  12. uchar recv_flag=0;                        //当3个字符全部接收完成后,置recv_flag=1,否则recv_flag=0
  13. uchar count_data=0;                        //接收到的3个字符在数组中的下标,0、1、2
  14. uchar buffer_data[3]=0;                //存放接收到的3个字符,buffer_data[count_data]为数组中的一个字符
  15. uint  pwm_data=0;                        //PWM方波的计数变量
  16. uint  left_pwm=0;                        //表征左边电机的占空比
  17. uint  right_pwm=0;                        //表征右边电机的占空比
  18. uint  PWM_CYCLE=210;                //PWM方波的周期
  19. uint  temp=0;                                //保存P3口输入的循线信息
  20. uint  flag=0;
  21. uint  flagxun=0;                        //flagxun=0,蓝牙状态;flagxun=1,循线状态
  22. /************************毫秒延时函数**********************************************/
  23. void delay(uint x)
  24. {
  25.         uint m,n;
  26.         for(m=0;m<x;m++)
  27.                 for(n=0;n<15;n++);
  28. }
  29. /**************************端口初始化函数******************************************/
  30. void com_init()                              
  31. {
  32.         P0=0xff;
  33.         P1=0xff;
  34.         P2=0xff;
  35.         P3=0xff;
  36. }
  37. /**************************电机初始化函数******************************************/
  38. void dian_init()                       
  39. {
  40.         in1=1;
  41.         in2=0;
  42.         in3=1;
  43.         in4=0;
  44.         ENA=0;
  45.         ENB=0;
  46. }
  47. /**************************定时器初始化函数******************************************/
  48. void timer_init(void)                        
  49. {
  50.         TMOD=0x22;                          //T1为方式2,T0为方式2
  51.     TL1=0xfd;                                     //11.0592M晶振,波特率为9600
  52.     TH1=0xfd;
  53.         TL0=0;
  54.         TH0=156;                                //计数100次溢出,即每隔100us进入T0中断
  55.     SCON=0x50;  
  56.     PCON=0x00;
  57.    
  58.         TR1=1;
  59.         ES=1;   
  60.     EA=1;
  61.         ET0=1;
  62.         TR0=1;      
  63. }
  64. /**************************驱动轮方向与速度控制函数******************************************/
  65. void forward1(uint x)        //左轮前进
  66. {
  67.         in1=1;
  68.         in2=0;
  69.         left_pwm=x;
  70. }
  71. void forward2(uint x)        //右轮前进
  72. {
  73.         in3=1;
  74.         in4=0;
  75.         right_pwm=x;
  76. }
  77. void back1(uint x)        //左轮后退
  78. {
  79.         in1=0;
  80.         in2=1;
  81.         left_pwm=x;
  82. }
  83. void back2(uint x)        //右轮后退
  84. {
  85.         in3=0;
  86.         in4=1;
  87.         right_pwm=x;
  88. }
  89. /**************************高速向前******************************************/
  90. void bforw()                                                //高速向前
  91. {
  92.         in1=1;
  93.         in2=0;
  94.         in3=1;
  95.         in4=0;
  96.         left_pwm=140;
  97.         right_pwm=140;      
  98. }
  99. void mforw()                                           //中速向前
  100. {
  101.         in1=1;
  102.         in2=0;
  103.         in3=1;
  104.         in4=0;
  105.         flag=0;
  106.         while((temp==0)&&(8000-flag))
  107.         {
  108.                 left_pwm=105;
  109.                 right_pwm=105;
  110.                 flag++;
  111.                 delay(10);
  112.         }
  113.         bforw();
  114.         flag=0;      
  115. }
  116. void sforw()                //保持原来方向,低速向前测黑线
  117. {
  118.         left_pwm=35;
  119.         right_pwm=35;      
  120. }
  121. void sright()                                //微调路径,尽量减小小车左右摆动
  122. {
  123.         in1=1;
  124.         in2=0;
  125.         in3=1;
  126.         in4=0;
  127.         flag=0;
  128.         while(temp==64)
  129.         {
  130.                 left_pwm=80-2*flag;//可调试
  131.                 right_pwm=28-7*flag;//可调试
  132.                 delay(30);
  133.                 flag++;
  134.                 if(flag>=4)flag=4;
  135.         }
  136.         flag=0;      
  137. }
  138. void sleft()
  139. {
  140.         in1=1;
  141.         in2=0;
  142.         in3=1;
  143.         in4=0;
  144.         flag=0;
  145.         while(temp==32)
  146.         {
  147.                 right_pwm=80-2*flag;//可调试
  148.                 left_pwm=28-7*flag;//可调试
  149.                 delay(30);
  150.                 flag++;
  151.                 if(flag>=4)flag=4;
  152.         }
  153.         flag=0;      
  154. }
  155. void mright()                                           //二次调节,减小左右摆动
  156. {
  157.         in1=1;
  158.         in2=0;
  159.         in3=1;
  160.         in4=0;
  161.         flag=0;
  162.         while(temp==192)
  163.         {
  164.                 left_pwm=100-4*flag;//可调试
  165.                 right_pwm=50-3*flag;//可调试
  166.                 delay(2);
  167.                 flag++;
  168.                 if(flag>=10)flag=10;
  169.         }
  170.         flag=0;      
  171. }
  172. void mleft()
  173. {
  174.         in1=1;
  175.         in2=0;
  176.         in3=1;
  177.         in4=0;
  178.         flag=0;
  179.         while(temp==48)
  180.         {
  181.                 right_pwm=100-4*flag;//可调试
  182.                 left_pwm=50-3*flag;//可调试
  183.                 delay(2);
  184.                 flag++;
  185.                 if(flag>=10)flag=10;
  186.         }
  187.         flag=0;      
  188. }
  189. void bright()                                                         //后退,防止小车脱离赛道
  190. {
  191.         flag=0;
  192.         in3=0;
  193.         in4=1;
  194.         while(temp==128)
  195.         {
  196.                 flag++;
  197.                 if(flag<16)
  198.                 {
  199.                         left_pwm=60+1*flag;//可调试
  200.                         right_pwm=0;//可调试
  201.                         delay(6);
  202.                 }
  203.                 if(flag>=16)
  204.                 {
  205.                         left_pwm=35+(flag-17)^2;//可调试
  206.                         right_pwm=3*(flag-15);//可调试
  207.                         delay(10);
  208.                 }
  209.                 if(flag>=25)flag=25;
  210.         }
  211.         flag=0;      
  212. }
  213. void bleft()
  214. {
  215.         flag=0;
  216.         in1=0;
  217.         in2=1;
  218.         while(temp==16)
  219.         {
  220.                 flag++;
  221.                 if(flag<16)
  222.                 {
  223.                         right_pwm=60+1*flag;//可调试
  224.                         left_pwm=0;//可调试
  225.                         delay(6);
  226.                 }
  227.                 if(flag>=16)
  228.                 {
  229.                         right_pwm=35+(flag-17)^2;//可调试
  230.                         left_pwm=3*(flag-15);//可调试
  231.                         delay(10);
  232.                 }
  233.                 if(flag>=25)flag=25;
  234.         }
  235.         flag=0;      
  236. }
  237. void expe()                 //接收到未知数据,保持原来方向
  238. {
  239.         left_pwm=110;
  240.         right_pwm=110;      
  241. }
  242. void stop()                  //停止
  243. {
  244.         left_pwm=0;
  245.         right_pwm=0;
  246. }
  247. /**************************手机APP遥控函数*****************************************/
  248. void bluetooth(void)
  249. {
  250.         switch(buffer_data[2])
  251.         {
  252.                 case 'A': forward1(80);forward2(80);break;                //按下APP前进键
  253.                 case 'B': back1(80);back2(80);break;                          //按下APP后退键
  254.                 case 'C': back1(50);forward2(50);break;              //按下APP左转键
  255.                 case 'D': forward1(50);back2(50);break;                  //按下APP右转键
  256.                 case 'F': forward1(0);forward2(0);break;                //松手
  257.                 case '1': flagxun=~flagxun;break;                                //按下1,进入循线状态
  258.                 default : ;
  259.         }         
  260. }
  261. /**************************循线函数*****************************************/
  262. void xunji(void)
  263. {
  264.                 P3=0xff;
  265.                 temp=P3;
  266.                 temp=temp&0xf0;
  267.                 P0=temp;
  268.                 switch(temp)                                        //左1 左2 右3 右4
  269.                 {
  270.                         case 0:mforw();break;                //全都没检测到黑线,中速前进
  271.                         case 16:bleft();break;                //左1检测到黑线,高速左转
  272.                         case 32:sleft();break;                //左2检测到黑线,低速左转
  273.                         case 64:sright();break;                //右3检测到黑线,低速右转
  274.                         case 128:bright();break;        //右4检测到黑线,高速右转
  275.                         case 96:sforw();break;                //左2、右3检测到黑线,低速前进
  276.                         case 48:mleft();break;                //左1、左2检测到黑线,中速左转
  277.                         case 192:mright();break;        //右3、右4检测到黑线,中速右转
  278.                         case 240:stop();break;                //全都检测到黑线,停止
  279.                         default :expe();break;                //接收到未知数据,保持原来方向前进
  280.                 }
  281. }
  282. /*************************主函数***************************************************/
  283. void main(void)
  284. {
  285.         com_init();                        //四组IO口初始化
  286.         dian_init();                //电机初始化
  287.         timer_init();                //定时器初始化
  288.         led=0;
  289.         flagxun=0;
  290.         while(!flagxun)                                               
  291.         {
  292.                 if(recv_flag==1)        //recv_flag==1表明3个字符全部接收完毕                           
  293.                 {
  294.                         recv_flag=0;    //清空3个字符全部接收完毕标记位
  295.                            bluetooth();    //手机APP遥控函数
  296.                 }
  297.                 while(flagxun)
  298.                         xunji();
  299.         }
  300. }
  301. /**************************串口中断服务函数****************************************/
  302. void Serial(void) interrupt 4                                  //中断接收3个字符
  303. {
  304.            uchar temp_data;                                                  //temp_data用来存放接收到的字符
  305.         RI=0;
  306.         temp_data=SBUF;
  307.         if(temp_data=='O'&&(count_data==0))         //接收第一个字符串
  308.         {
  309.                 buffer_data[count_data]=temp_data;
  310.                 count_flag=1;                            //count_flag=1表示已经接收到第1个字符
  311.         }
  312.         else
  313.         {
  314.                 if(count_flag==1)                            //开始接收第2、3个字符
  315.                 {
  316.                         count_data++;
  317.                         buffer_data[count_data]=temp_data;
  318.                         if(count_data>=2)                                   //count_data=2,表明已经接收3个字符
  319.                         {                                                                   //此时表明3个字符已接收完毕,开始执行遥控程序
  320.                                 count_data=0;
  321.                                 count_flag=0;                                   //清空标记位
  322.                                 recv_flag=1 ;                                   //数据接收完毕标记位
  323.                         }  
  324.                 }
  325.         }         
  326. }
  327. /*************************定时器中断函数*******************************************/
  328. void Timer0(void) interrupt 1
  329. {
  330.         pwm_data++;
  331.         if(pwm_data>PWM_CYCLE)
  332.                 pwm_data=0;
  333.         if(pwm_data<=left_pwm)                       
  334.                 ENA=1;
  335.         else
  336.                 ENA=0;
  337.         if(pwm_data<=right_pwm)
  338.                 ENB=1;
  339.         else
  340.                 ENB=0;
  341.         P3=0xff;
  342.         temp=P3;
  343.         temp=temp&0xf0;
  344.         P0=temp;
  345. }
复制代码





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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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