查看: 2588|回复: 1

[经验] 基于AVR单片机自动循迹小车的设计

[复制链接]
  • TA的每日心情

    2022-8-2 14:54
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2020-1-20 19:03:50 | 显示全部楼层 |阅读模式
    分享到:
                                 AVR自动循迹小车的设计

    一、设计要求    
    (1)自动寻迹小车从安全区域启动。 
    (2)小车按指定路线运行,自动区分直线轨道和弯路轨道,在指定弯路处拐弯,实现灵活前进、转弯、倒退等功能,在轨道上划 出设定的地图。 
    (3)小车完成指定运行任务后,自动返回出发起点,自动倒车,入库
      一般寻迹是指小车在黑色地板上循白线行走,通常采取的方法是红外探测法,即利用红外线在不同颜色的物体表面具有不同反射性质的特点,在小车行驶中不断向地面发射红外光,当红外光遇到白色轨迹时发生漫反射,反射光被装在小车上的接收管接收;如果遇到黑色地板则红外光被吸收,接收管接收不到红外光。单片机以是否收到反射回来的红外光为依据来确定白线的位置和小车的行走路线。红外探测器探测距离有限,一般最大不应超过3cm。下面是小车底盘示意图:

    根据要求,设计的系统主要由控制器模块、电源模块、寻迹传感器模块、直流电机及其驱动模块、电压比较模块等构成。

    二、方案设计 

      经过反复考虑论证,制定了左右两轮分别驱动,后万向轮转向的方案。即左右轮分别用两个转速和力矩基本完全相同的直流电机进行驱动,车体尾部装一个万向轮。这样,当两个直流电机转向相反、转速相同时就可以实现电动车的原地旋转,由此可以轻松实现小车坐标不变的90度和180度转弯。安装时保证两个驱动电机同轴。当小车前进时,左右两驱动轮与后万向轮形成了三点结构。这种结构使得小车在前进时比较平稳,可以避免出现后轮过低而使左右两驱动轮驱动力不够的情况。为了防止小车重心的偏移,后万向轮起支撑作用。  车架材料选择有机玻璃,它比塑料车架更加牢固,比铁制小车更轻便,美观。

    程序设计            


    #include<mega128.h>
    #include "delay.h"
    #define left1   PORTC.0  
    #define left2   PORTC.1
    #define min     PORTC.2
    #define right1  PORTC.3
    #define right2  PORTC.4  
    #define Turn_Left       PORTC.5
    #define Turn_Right      PORTC.6
    #define u8      unsigned char
    #define u16     unsigned int  

    void  Init_IO(void)
    {
        DDRC = DDRC&0xe0; //将C端口低5位定义为输入,浮空
        PORTC = 0xe0;//
        DDRB = 0xff; //将B端口设为输出模式
        PORTB = 0xff;
        PORTA = 0xff;
        DDRA = 0xff;
    }   

    void Adjust_Speed(u8 Left_Speed,u8 Right_Speed)
    {
          OCR1A = (u16)Right_Speed*10 ;//Left_Speed:1--100,为右电机占空比
          OCR1B = (u16)Left_Speed*10;//Right_Speed:1--100,为左电机的占空比   
    }

    void    Init_Timer1(void)
    {       u16     i,j;
            i = 300; //实际测试发现1600时电机速度还是很快的。
            j = 300;
            TCCR1A = 0xa0;//相位与频率修正PWM,TOP值为ICR1,向上计数匹配清零,向下计数匹配时置1
            TCCR1B = 0x12;//系统时钟8分频,A,B同时输出PWM   
            OCR1A = i; //右电机
            OCR1B = j;  //在电机
            ICR1 = 1000;
    }

    void main(void)
    {   
            Init_IO();
            Init_Timer1();
            while(1)
            {
               if(PINC==0xfb)//只有中间循迹管检测到黑线11011
               {
                   Adjust_Speed(30,30);//前进  
                   PORTA = 0xfe;
               }

             if(PINC==0xf9)//中间和左边第二个循迹管检测到黑线10011
             {
                   Adjust_Speed(20,60);//左转
                  //  delay_ms(5);
                   PORTA = 0xfd;
              }

               if(PINC==0xfd)//左边第二个循迹管检测到黑线10111
               {
                    Adjust_Speed(15,65);//左转
                   //delay_ms(5);
                     PORTA = 0xfb;
               }

               if(PINC==0xfc)//左边两个同时检测到黑线00111
               {

                    Adjust_Speed(15,70);//左转
                     PORTA = 0xf7;
               }

              if(PINC==0xfe)//左边第一个循迹管检测到黑线01111
              {

                   Adjust_Speed(15,85);//左转
                 //   delay_ms(5);
                    PORTA = 0xef;
              }

                if(PINC==0xf3)//中间和右边第二个循迹管检测到黑线11001
              {

                   Adjust_Speed(35,15);//右转
                    PORTA = 0xdf;
               }
              if(PINC==0xf7)//右边第二个循迹管检测到黑线11101
              {
                   Adjust_Speed(70,13);//右转  
                    PORTA = 0xbf;
               }  
               if(PINC==0xe7)//右边两个检测到黑线11100
               {
                   Adjust_Speed(75,13);//右转  
                   PORTA = 0x7f;
               }  
               if(PINC==0xef)//右边第一个检测到黑线11110
               {
                   Adjust_Speed(96,12);//右转   
                   PORTA = 0xfc;
               }   
               if(PINC==0xe3)//右侧三个循迹管同时检测到黑线(直角)11000
               {
                   Adjust_Speed(40,0);//右转
                   PORTA = 0xf8;   
               }
               if(PINC==0xe7)//左侧三个循迹管同时检测到黑线(直角)00011左转
              {
                   Adjust_Speed(0,40);//左转
                    PORTA = 0xf0;
               }
               if(PINC==0xe0)//5个循迹管同时检测到交叉00000直走
               {
                 Adjust_Speed(25,25);//直走
                  PORTA = 0xe0;
               }
           //    if(PINC==0xff)
             //  {
               //    Adjust_Speed(0,100);//直走
                 // PORTA = 0xc0;   
               //}

            }

    }




















    H7ZPD9DJLCT`WRC[Q~)E3[S.png
    PWM模式配置表.jpg
    回复

    使用道具 举报

    该用户从未签到

    发表于 2020-2-7 12:03:33 | 显示全部楼层
    内容不错,可以

    评分

    参与人数 1与非币 +27 收起 理由
    a1153635534 + 27 很给力!

    查看全部评分

    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 19:27 , Processed in 0.125681 second(s), 19 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.