找回密码
 立即注册

QQ登录

只需一步,快速开始

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

昨天发的多功能小车程序

[复制链接]
跳转到指定楼层
楼主
ID:309758 发表于 2018-5-29 08:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<reg52.h>                                            
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define u8 unsigned char
  5. #define u16 unsigned int

  6. uchar num;
  7. unsigned char  irtime;        //红外用全局变量
  8. unsigned char IRcord[4];          //红外按键对应码值选对应功能的数组
  9. unsigned char irdata[33];          //存储电平持续的时间的数组
  10. u16 EchoCnt;

  11. bit irpro_ok,irok;                         //位定义,用于判断操作是否完成

  12. sbit in1=P1^0;                             //电机引脚定义
  13. sbit in2=P1^1;
  14. sbit in3=P1^2;
  15. sbit in4=P1^3;
  16. sbit IR=P3^2;               //将IR位定义为P3.2引脚红外模块引脚
  17. sbit XUNJI0 =P2^2;                //循迹模块
  18. sbit XUNJI1 =P2^3;
  19. sbit Trig = P3^6;                    //超声波模块
  20. sbit Echo = P3^7;
  21. sbit XUNGUANG0 = P2^0;            // 红外寻光接口定义
  22. sbit XUNGUANG1 = P2^1;

  23. typedef enum
  24. {
  25.         FORWARD=0,
  26.         BACKUP,
  27.         LEFT,
  28.         RIGHT,
  29.         STOP,
  30.     ZHUANHUAN,
  31.         XUNJI,
  32.         BIZHANG,
  33.         XUNGUANG,
  34. }MOTOR_DIR;

  35. void qianjin();
  36. void houtui();
  37. void zuozhuan();
  38. void youzhuan();
  39. void tingzhi();
  40. void DelayMs(u16 t);                                                   //延时函数
  41. void DelayUs(u16 i);
  42. void DcMotorContorl(MOTOR_DIR dir, u8 speed);        // 小车直流电机控制,dir为方向,speed为速度
  43. void TIM0init();                                //定时器0初始化
  44. void Ircordpro();
  45. void Ir_work();
  46. void HC04_Init();
  47. void HC04_Loop();
  48. void hongwaiyaokong();                                  //红外遥控函数
  49. void lanya();                                                  //蓝牙遥控函数
  50. void xunji();                                          //循迹函数
  51. void bizhang();                                                  //壁障函数
  52. void xunguang();                                          //寻光函数

  53. void init_t1()                                  //初始化函数
  54. {
  55. TMOD=0x20;            //设置定时器1为工作方式2
  56. TH1=0xfd;             //波特率初始值
  57. TL1=0xfd;
  58. TR1=1;                //定时器打开
  59. REN=1;                //允许串行接受
  60. SM0=0;                //串行口工作方式设置为1
  61. SM1=1;
  62. EA=1;                                  //打开总中断
  63. ES=1;
  64. }


  65. void main()                      //主函数
  66. {
  67.   init_t1();
  68.    while(1)
  69.     {
  70.           lanya();
  71.      }
  72. }

  73. void EX0init(void)                                   // 外部中断初始化
  74. {
  75. IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  76. EX0 = 1;   //允许外部中断0
  77. EA = 1;    //开总中断
  78. }


  79. void ex0_isr (void) interrupt 0 using 0   //外部中断0服务函数
  80. {
  81.   static unsigned char  i;                //接收红外信号处理
  82.   static bit startflag;                   //是否开始处理标志位

  83. if(startflag)                        
  84. {
  85.     if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms低电平+4.5ms高电平
  86.             i=0;
  87.                     irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
  88.                     irtime=0;
  89.                     i++;
  90.                             if(i==33)
  91.                               {
  92.                                    irok=1;
  93.                                  i=0;
  94.                                   }
  95.           }
  96.            else
  97.                 {irtime=0;
  98.                 startflag=1;
  99.                 }
  100. }

  101. void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数
  102. {
  103.   irtime++;                             //用于计数2个下降沿之间的时间
  104. }

  105. void TIM0init(void)//定时器0初始化
  106. {

  107.   TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  108.   TH0=0x00; //重载值
  109.   TL0=0x00; //初始化值
  110.   ET0=1;    //开中断允许位
  111.   TR0=1;    //开启定时器功能  
  112. }

  113. void t1() interrupt 4//中断服务函数
  114. {
  115. if(RI)
  116.   {
  117.    RI=0;
  118.    num=SBUF-48;                //将接收到的码值转换为十进制整数以选择对应功能
  119.    }
  120. }

  121. void HC04_Init(void)            //初始化超声波模块
  122. {
  123.         Trig = 0;
  124.         Echo = 0;
  125.         TMOD &=0X0f;
  126.         TMOD |=0X10;              //使用模式1,16位定时器1;
  127.         TH1=0;                    //装初值
  128.         TL1=0;
  129.         EA=1;                     //开总中断
  130.         ET1=1;                    //开定时器1中断
  131.         TR1=0;                    //定时器1
  132. }

  133. void HC04_Loop(void)             //数据处理函数计算前方物体和小车的距离
  134. {  
  135.         Trig = 1;
  136.         DelayUs(20);
  137.         Trig = 0;
  138.         while(Echo == 0);
  139.         TH1=0;
  140.         TL1=0;
  141.         TR1=1;
  142.         while(Echo == 1);
  143.         EchoCnt = (TH1*256 + TL1)*1.7/100;
  144. }

  145. void lanya()
  146. {
  147.    while(1)
  148.     {
  149.       switch(num)
  150.        {
  151.          case 1: qianjin();break;         //前进
  152.          case 2: zuozhuan();break;        //左转
  153.          case 3: tingzhi();break;         //停止
  154.          case 4: youzhuan();break;        //右转
  155.          case 5: houtui();break;          //后退
  156.          case 6: hongwaiyaokong();break;  //启动红外遥控
  157.          case 7: xunji();break;                          //启动循迹功能
  158.                  case 8: bizhang();break;         //启动壁障功能
  159.                  case 9: xunguang();break;              //启动寻光功能
  160.                  default:break;
  161.         }
  162.      }
  163. }


  164. /*蓝牙遥控电机程序*/
  165. void qianjin()
  166. {
  167.     in1=1;
  168.     in2=0;
  169.     in3=1;
  170.     in4=0;
  171. }

  172. void houtui()
  173. {
  174.     in1=0;
  175.     in2=1;
  176.     in3=0;
  177.     in4=1;
  178. }

  179. void zuozhuan()
  180. {
  181.     in1=1;
  182.     in2=0;
  183.     in3=0;
  184.     in4=0;
  185. }

  186. void youzhuan()
  187. {
  188.     in1=0;
  189.     in2=0;
  190.     in3=1;
  191.     in4=0;
  192. }

  193. void tingzhi()
  194. {
  195.     in1=0;
  196.     in2=0;
  197.     in3=0;
  198.     in4=0;
  199. }

  200. void hongwaiyaokong()                        // 红外遥控函数
  201. {
  202.         TIM0init();
  203.          EX0init();
  204.         while(1)        
  205.         {
  206.                 if(irok)                        //如果接收好了进行红外处理        红外解码
  207.                 {   
  208.                         Ircordpro();
  209.                         irok=0;
  210.                 }
  211.                 if(irpro_ok)                   //如果处理好后进行工作处理,执行对应功能
  212.                 {
  213.                         Ir_work();
  214.                 }        
  215.         }
  216. }

  217. void xunji()                        // 循迹函数
  218. {
  219.         DelayMs(1000);                // 默认延时,等待系统稳定
  220.         while(1)               
  221.         {
  222.                    DcMotorContorl(FORWARD, 10);
  223.                 if((XUNJI0 == 1) && (XUNJI1 == 0))                        // 寻迹右边红外检测到黑线
  224.                 {
  225.                         DcMotorContorl(RIGHT, 14);                                // 小车往右边走
  226.                 }
  227.                 else if((XUNJI0 == 0) && (XUNJI1 == 1))                // 小车左边红外检测到黑线
  228.                 {
  229.                         DcMotorContorl(LEFT, 14);                                // 小车往左边走
  230.                 }
  231.                 else if((XUNJI0 == 0) && (XUNJI1 == 0))                // 小车左右都没有检测到黑线
  232.                 {
  233.                         DcMotorContorl(FORWARD, 10);                        // 小车直走
  234.                 }
  235.         }
  236. }

  237. void bizhang(void)                        //壁障函数                                             
  238. {
  239.         HC04_Init();
  240.         while(1)               
  241.         {
  242.                 HC04_Loop();                          //调用数据处理函数
  243.                 if(EchoCnt < 25)                                // 距离小于25CM
  244.                 {
  245.                         DcMotorContorl(STOP, 20);        // 小车停止
  246.                         DcMotorContorl(RIGHT, 20);        //小车右转
  247.                         DelayUs(1500);
  248.                           if(EchoCnt < 25)
  249.                                   {
  250.                                   DcMotorContorl(STOP, 20);           // 小车停止
  251.                               DcMotorContorl(RIGHT, 25);   //小车右转
  252.                                   }
  253.                            else
  254.                                    {
  255.                                    DcMotorContorl(FORWARD, 20);        // 小车前进
  256.                                         }
  257.          }
  258.                 else
  259.                 {
  260.                         DcMotorContorl(FORWARD, 20);        // 小车前进
  261.                 }
  262.         }
  263. }

  264. void xunguang(void)                        //寻光函数
  265. {
  266.         DelayMs(1000);                // 延时,等待系统稳定
  267.         while(1)               
  268.         {
  269.                 if((XUNGUANG0 == 1) && (XUNGUANG1 == 0))                        // 寻光右边红外检测到光线
  270.                 {
  271.                         DcMotorContorl(RIGHT, 15);                                // 小车往右边走
  272.                 }
  273.                 else if((XUNGUANG0 == 0) && (XUNGUANG1 == 1))                // 小车左边红外检测到光线
  274.                 {
  275.                         DcMotorContorl(LEFT, 15);                                // 小车往左边走
  276.                 }
  277.                 else if((XUNGUANG0 == 0) && (XUNGUANG1 == 0))                // 小车左右都有检测到光线
  278.                 {
  279.                         DcMotorContorl(FORWARD, 20);                        // 小车直走
  280.                 }
  281.         }
  282. }


  283. /*红外遥控电机程序*/
  284. void DcMotorContorl(MOTOR_DIR dir,u8 speed)
  285. {
  286.         switch(dir)
  287.         {
  288.                 case FORWARD:                          // 前进
  289.                         in1 = 1;
  290.                         in2 = 0;
  291.                         in3 = 1;
  292.                         in4 = 0;
  293.                 break;
  294.                 case BACKUP:                   // 后退
  295.                         in1 = 0;
  296.                         in2 = 1;
  297.                         in3 = 0;
  298.                         in4 = 1;
  299.                 break;
  300.                 case LEFT:                           // 左转
  301.                         in1 = 0;
  302.                         in2 = 1;
  303.                         in3 = 1;
  304.                         in4 = 0;
  305.                 break;
  306.                 case RIGHT:                       // 右转
  307.                         in1 = 1;
  308.                         in2 = 0;
  309.                         in3 = 0;
  310.                         in4 = 1;
  311.                 break;        
  312.                 case STOP:                           // 停止
  313.                         in1 = 0;
  314.                         in2 = 0;
  315.                         in3 = 0;
  316.                         in4 = 0;
  317.                 break;
  318.         case ZHUANHUAN:                  //转换功能
  319.                     lanya();
  320.         break;        
  321.                 case XUNJI:                          //循迹功能
  322.                     xunji();
  323.             break;
  324.                 case BIZHANG:                  //壁障功能
  325.                     bizhang();
  326.             break;
  327.                 case XUNGUANG:              //寻光功能
  328.                     xunguang();
  329.                 break;
  330.                 default:                          // 其他
  331.                         in1 = 0;
  332.                         in2 = 0;
  333.                         in3 = 0;
  334.                         in4 = 0;
  335.                 break;
  336.         }
  337.         DelayMs(speed);                // speed的值越大,速度越快
  338.         in1 = 1;
  339.         in2 = 1;
  340.         in3 = 1;
  341.         in4 = 1;
  342.         DelayMs(25 - speed);        // speed的值越大,延时时间越短,速度越快
  343. }

  344. void DelayMs(u16 t)
  345. {
  346.         u16 i,j;
  347.         for(i=0; i<t; i++)
  348.                 for(j=0; j<120; j++);
  349. }

  350. void DelayUs(u16 i)
  351. {
  352.         while(--i);
  353. }

  354. void Ir_work(void)      //红外键值处理,红外键值转程序
  355. {
  356.         
  357.         switch(IRcord[2])   //判断第三个数码值
  358.         {
  359.                 case 0x0c:                        // 数字1                        //转换为蓝牙
  360.                         DcMotorContorl(ZHUANHUAN, 0);
  361.             break;
  362.                 case 0x18:                        // 数字2
  363.                         DcMotorContorl(FORWARD, 20);                // 小车直行
  364.                         break;
  365.                 case 0x5e:                        // 数字3
  366.                     DcMotorContorl(XUNJI, 0);                        //循迹功能
  367.                         break;
  368.                 case 0x08:                        // 数字4
  369.                         DcMotorContorl(LEFT, 20);                        // 小车左转
  370.                         break;
  371.                 case 0x1c:                        // 数字5
  372.                         DcMotorContorl(STOP, 20);                        // 小车停止
  373.                         break;
  374.                 case 0x5a:                        // 数字6
  375.                         DcMotorContorl(RIGHT, 20);                        // 小车右转
  376.                         break;
  377.                 case 0x42:                        // 数字7
  378.                         DcMotorContorl(BIZHANG, 0);                        //壁障功能
  379.                         break;
  380.                 case 0x52:                        // 数字8
  381.                         DcMotorContorl(BACKUP, 20);                        // 小车后退
  382.                         break;
  383.                 case 0x4a:                        // 数字9               
  384.                      DcMotorContorl(XUNGUANG, 0);                //寻光功能
  385.                         break;
  386.                 case 0x16:                        // 数字0
  387.                         break;
  388.                 case 0x46:                        // Mode
  389.                         DcMotorContorl(FORWARD, 20);                // 小车直行
  390.                         break;
  391.                 case 0x40:                        // <-
  392.                         DcMotorContorl(STOP, 20);                        // 小车停止
  393.                         break;
  394.                 case 0x44:                        // >||
  395.                         DcMotorContorl(LEFT, 20);                        // 小车左转
  396.                         break;
  397.                 case 0x43:                        //->
  398.                         DcMotorContorl(RIGHT, 20);                        // 小车右转
  399.                         break;
  400.                 case 0x15:                        // VOL-
  401.                         DcMotorContorl(BACKUP, 20);                        // 小车后退
  402.                         break;
  403.                 default:
  404.                         break;
  405.         }
  406.         //irpro_ok=0;//处理完成标志

  407. }

  408. void Ircordpro(void)        //红外解码码值处理函数
  409. {
  410.   unsigned char i, j, k;
  411.   unsigned char cord,value;
  412.   k=1;
  413.   for(i=0;i<4;i++)      //处理4个字节
  414.      {
  415.       for(j=1;j<=8;j++) //处理1个字节8位
  416.          {
  417.           cord=irdata[k];
  418.           if(cord>7)     //大于某值为1,这个和晶振有绝对关系,此值可以有一定误差
  419.                     {
  420.              value=value|0x80;
  421.                         }
  422.           else
  423.                     {
  424.              value=value;
  425.                         }
  426.           if(j<8)
  427.                     {
  428.                          value=value>>1;
  429.                         }
  430.            k++;
  431.          }
  432.      IRcord[i]=value;
  433.      value=0;     
  434.      }
  435.          irpro_ok=1;     //处理完毕标志位置1

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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