智能小车 订阅
智能小车作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能小车能够实时显示时间、速度、里程,具有自动寻迹、寻光、避障功能,可程控行驶速度、准确定位停车,远程传输图像等功能。智能小车可以分为三部分——传感器部分、控制器部分、执行器部分。控制器部分:接收传感器部分传递过来的信号,并根据事前写入的决策系统(软件程序),来决定机器人对外部信号的反应,将控制信号发给执行器部分。好比人的大脑。执行器部分:驱动机器人做出各种行为,包括发出各种信号(点亮发光二极管、发出声音)的部分,并且可以根据控制器部分的信号调整自己的状态。对机器人小车来说,最基本的就是轮子。这部分就好比人的四肢一样。 传感器部分:机器人用来读取各种外部信号的传感器,以及控制机器人行动的各种开关。好比人的眼睛、耳朵等感觉器官。 展开全文
智能小车作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能小车能够实时显示时间、速度、里程,具有自动寻迹、寻光、避障功能,可程控行驶速度、准确定位停车,远程传输图像等功能。智能小车可以分为三部分——传感器部分、控制器部分、执行器部分。控制器部分:接收传感器部分传递过来的信号,并根据事前写入的决策系统(软件程序),来决定机器人对外部信号的反应,将控制信号发给执行器部分。好比人的大脑。执行器部分:驱动机器人做出各种行为,包括发出各种信号(点亮发光二极管、发出声音)的部分,并且可以根据控制器部分的信号调整自己的状态。对机器人小车来说,最基本的就是轮子。这部分就好比人的四肢一样。 传感器部分:机器人用来读取各种外部信号的传感器,以及控制机器人行动的各种开关。好比人的眼睛、耳朵等感觉器官。
信息
发展背景
汽车工业的迅速发展
外文名
intelligent car
组成部分
传感器部分、控制器部分等
中文名
智能小车
特    色
显示时间、速度、里程等
智能小车发展背景简介
51智能小车 智能小车 随着汽车工业的迅速发展,关于汽车的研究也就越来越受人关注。全国电子大赛和省内电子大赛几乎每次都有智能小车这方面的题目,全国各高校也都很重视该题目的研究。可见其研究意义很大。在智能小车现今发展最好的当是 飞思卡尔 举行的比赛,采用先进的摄像头采集黑线线路,此时要求芯片的运算速度是非常高的。
收起全文
精华内容
下载资源
问答
  • Arduino智能小车——蓝牙小车

    万次阅读 多人点赞 2019-05-20 10:25:11
    Arduino智能小车——蓝牙小车  上一章我们完成了小车的运动控制,虽然小车已经可以运动,但是不能远程遥控,不够高大上。在这一篇,我们将尝试用手机蓝牙遥控小车。蓝牙模块  蓝牙( Bluetooth® ):是一种无线...

    Arduino智能小车——蓝牙小车

    Arduino智能小车系列教程时空门:

    1. Arduino智能小车——拼装篇 点击跳转
    2. Arduino智能小车——测试篇 点击跳转
    3. Arduino智能小车——调速篇 点击跳转
    4. Arduino智能小车——超声波避障 点击跳转
    5. Arduino智能小车——蓝牙小车 点击跳转
    6. Arduino智能小车——循迹篇 点击跳转
    7. Arduino智能小车——小车测速 点击跳转

      上一章我们完成了小车的运动控制,虽然小车已经可以运动,但是不能远程遥控,不够高大上。在这一篇,我们将尝试用手机蓝牙遥控小车。

    蓝牙模块

      蓝牙( Bluetooth® ):是一种无线技术标准,可实现固定设备、移动设备和楼宇个人域网之间的短距离数据交换(使用2.4—2.485GHz的ISM波段的UHF无线电波)。

      我们在此使用的蓝牙模块(HC-05)已经在内部实现了蓝牙协议,不用我们再去自己开发调试协议。这类模块一般都是借助于串口协议通信,因此我们只需借助串口将我们需要发送的数据发送给蓝牙模块,蓝牙模块会自动将数据通过蓝牙协议发送给配对好的蓝牙设备。

    串口通信

      由于要借助串口实现蓝牙通信功能,所以我们在此要先了解下Arduino的串口通信。

      Arduino UNO开发板上的串口为0->RX,1->TX,在开发板内部也已经配置好了串口的功能,我们只需调用函数借口即可。以下列出串口通信里面常用的函数,并加以简单解释,详细用法可在用到时自行查询。

    开启串行通信接口并设置通信波特率

    Serial.begin(speed); 
    

    关闭串口通信

    Serial.end();    
    

    判断串口缓冲器是否有数据写入

    Serial.available();
    

    读取串口数据

    Serial.read();    
    

    返回下一字节(字符)输入数据,但不删除它

    Serial.peek();   
    

    清空串口缓存

    Serial.flush();    
    

    写入字符串数据到串口

    Serial.print();    
    

    写入字符串数据+换行到串口

    Serial.println(); 
    

    写入二进制数据到串口

    Serial.write();     
    

    read时触发的事件函数

    Serial.SerialEvent();
    

    读取固定长度的二进制流

    Serial.readBytes(buffer,length);
    

    打印接到数据十进制表示的ascii码

    Serial.println(incomingByte, DEC);
    

    蓝牙模块连接

    TX: 接Arduino UNO开发板"RX"引脚
    RX: 接Arduino UNO开发板"TX"引脚
    GND: 接Arduino UNO开发板"GND"引脚
    VCC: 接Arduino UNO开发板"5V"或"3.3V"引脚

    手机蓝牙助手

      想实现手机蓝牙遥控小车,手机APP是必不可少的,目前网上有很多蓝牙串口助手,省去了我们自己写APP的时间,当然如果朋友你有能力或者想自己DIY的话也可以尝试自己写APP,在这里我推荐大家用这款手机蓝牙助手(百度上搜手机蓝牙串口助手就可以搜到,挺好用的)

      如果不想自己去找的话可以到我的百度网盘下载 [点击这里下载](http://pan.baidu.com/s/1pKClRTL)

      下载并安装后打开APP,在这里可能会提示你有新版本请求更新,建议点击以后再说(暂时不更新),以我的经验,一般点击立即更新都会更新失败。

      进入主界面,左上角会提示"蓝牙未连接",这个时候我们可以先对蓝牙助手的界面进行自定义设置。点击右下角的三个点(在我这里是这样的,其他手机可能不同,如果没有这三个点可以试着点击手机的功能键),选择“更多”。
      然后选择“地面站设置”进入自定义界面,往下拖动,找到“自定义按键[x]”,在此我们对按键[1][2][3][4][6]进行自定义设置。
    **  点击自定义按键[1],将其“显示名称”属性改为“停止”,“点击发送”属性改为“00”,并点击“确定”保存**
    同理更改其他按键:

    点击自定义按键[2],将其“显示名称”属性改为“前进”,“点击发送”属性改为“01”,并点击“确定”保存
    点击自定义按键[4],将其“显示名称”属性改为“左转”,“点击发送”属性改为“03”,并点击“确定”保存
    点击自定义按键[5],将其“显示名称”属性改为“后退”,“点击发送”属性改为“02”,并点击“确定”保存
    点击自定义按键[6],将其“显示名称”属性改为“右转”,“点击发送”属性改为“04”,并点击“确定”保存

      以上修改的属性值即为我们点击对应按键之后,蓝牙串口助手自动通过蓝牙发送的数据,与上一篇所定义的小车的几个状态一致,这样方便在Arduino在接收到蓝牙模块的数据后对小车的状态进行控制。

    #define STOP      0
    #define FORWARD   1
    #define BACKWARD  2
    #define TURNLEFT  3
    #define TURNRIGHT 4
    

    修改后属性如下图

    下面就来看看我们修改的效果吧,点击“模式切换”

    这时候你就可以看到我们自定义的按键咯,看看修改前后的对比吧。
      接下来我们将连接蓝牙,仍然点击右下角的三个点,然后点击“连接”
      一般没有连接过蓝牙模块的时候“已配对的设备”下面没有可选择的设备名称,因此我们要点击“扫描新设备”来检测我们的蓝牙模块,扫描成功后蓝牙模块的名称将显示在“已配对的设备”一栏中
      点击我们的蓝牙模块的名称,输入密码进行配对。配对成功后在蓝牙串口助手的左上角会显示“蓝牙已连接”字样,恭喜你,这时候你已经连接成功。

    小科普:
      蓝牙模块上电(只简单连接"VCC"和"GND"引脚)之后,其他蓝牙设备即可与其连接,一般蓝牙模块默认初始连接密码为"0000"或"1234",如果连接不上蓝牙,请尽快与厂商或者店家联系。蓝牙模块上电后LED指示灯不断闪亮,当有设备连接预期连接之后会隔一段闪两下,蓝牙串口助手也会有相应已连接的提示。

    Arduino代码编写

    新建一个工程,将下面代码复制到工程内

    #define STOP      0
    #define FORWARD   1
    #define BACKWARD  2
    #define TURNLEFT  3
    #define TURNRIGHT 4
    
    int leftMotor1 = 4;
    int leftMotor2 = 5;
    int rightMotor1 = 6;
    int rightMotor2 = 7;
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(leftMotor1, OUTPUT);
      pinMode(leftMotor2, OUTPUT);
      pinMode(rightMotor1, OUTPUT);
      pinMode(rightMotor2, OUTPUT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      //usart read
      if(Serial.available()>0)
      {
        char cmd = Serial.read();//读取蓝牙模块发送到串口的数据
      
        Serial.print(cmd);
        motorRun(cmd);
          
      }  
    }
    void motorRun(int cmd)
    {
      switch(cmd){
        case FORWARD:
          Serial.println("FORWARD"); //输出状态
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         case BACKWARD:
          Serial.println("BACKWARD"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNLEFT:
          Serial.println("TURN  LEFT"); //输出状态
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNRIGHT:
          Serial.println("TURN  RIGHT"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         default:
          Serial.println("STOP"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, LOW);
      }
    }
    

      朋友们大概也发现了,这个代码和上一篇的代码基本上相同,只不过增加了串口的内容。

    ##代码详解
      串口初始化函数,想要通过串口的库函数对串口进行操作,必须在void set_up()函数中对其进行初始化。

    Serial.begin(9600);
    

      在void loop()函数内,加入了检测串口接收内容的函数,并将接收到的命令输入到 void motorRun(int cmd)函数中控制小车运动。

    if(Serial.available()>0)
      {
        char cmd = Serial.read();
      
        Serial.print(cmd);
        motorRun(cmd);
      }  
    

    蓝牙小车测试

      下载程序之后,重新连接蓝牙模块,切换到我们自定义的按键界面,快试试蓝牙遥控小车吧。

    可能遇到的问题

      由于大家用的手机蓝牙串口助手可能不同,或者软件版本的不同,很容易出现如下的情况:

      好像看起来并没有什么毛病,但是小车就是不会运转。这种情况是因为手机蓝牙串口助手向手机发送的是[ASCII码](https://baike.baidu.com/item/ASCII/309296?fr=aladdin),虽然打印出来也是0、1、2、3、4,但是在C语言里面这种应该表示为char类型,例如
    char cmd = '1';	// ASCII码、字符1
    int cmd = 1;	//整型1
    
    
    #define STOP      0		// 程序中的宏定义
    #define FORWARD   1
    #define BACKWARD  2
    #define TURNLEFT  3
    #define TURNRIGHT 4
    

    而在程序里面的宏定义中使用的是整型的1,因此才会出现虽然接收到了信号,但是小车不会动的情况,在这种情况下,需要对其进行特殊处理,将loop函数修改成下面这样,其他程序保持不变:

    void loop() {
      // put your main code here, to run repeatedly:
      //usart read
      if(Serial.available()>0)
      {
        int cmd = Serial.read();//读取蓝牙模块发送到串口的数据
      	if (cmd != 10)	// 10代表是判断接收到的数据是否是换行符,如果是换行符的话就不控制小车运动
      	{
    	    Serial.print(cmd-48);	// 48是ASCII吗中字符‘0‘对应的10进制数,'0','1'等每个字符型的数字减去'0'后即可得到整型的0,1等
    	    motorRun(cmd-48);
        }
          
      }  
    }
    

    附件

    安卓手机蓝牙串口点击下载,也可以复制链接 https://download.csdn.net/download/qq_16775293/11165678 到浏览器下载。

    欢迎各位有兴趣的朋友加入Q群1:789127261点评、交流

    展开全文
  • Arduino智能小车——循迹篇

    万次阅读 多人点赞 2017-09-04 11:57:11
    Arduino智能小车——循迹篇   相信大家都在网上看到过类似下图这样的餐厅服务机器人,或者仓库搬运机器人,但是你们有没有注意到图片中地上的那条黑线?没错,他们都是沿着这条黑线来行进的,在这一篇将教大家...

    Arduino智能小车——循迹篇

    Arduino智能小车系列教程时空门:

    1. Arduino智能小车——拼装篇 点击跳转
    2. Arduino智能小车——测试篇 点击跳转
    3. Arduino智能小车——调速篇 点击跳转
    4. Arduino智能小车——超声波避障 点击跳转
    5. Arduino智能小车——蓝牙小车 点击跳转
    6. Arduino智能小车——循迹篇 点击跳转
    7. Arduino智能小车——小车测速 点击跳转

      相信大家都在网上看到过类似下图这样的餐厅服务机器人,或者仓库搬运机器人,但是你们有没有注意到图片中地上的那条黑线?没错,他们都是沿着这条黑线来行进的,在这一篇将教大家怎么用小车实现类似的循迹功能。

    准备材料

    黑色电工胶布

      黑色胶布用于搭建小车运行的“轨道”,选用黑色宽度18mm左右的即可。

    循迹模块

      在此我们使用循迹模块TCRT5000,该模块体积小,灵敏度较高,还可以通过转动上面的电位器来调节检测范围。

    模块特色

    1、采用TCRT5000红外反射传感器
    2、检测距离:1mm~8mm适用,焦点距离为2.5mm
    3、比较器输出,信号干净,波形好,驱动能力强,超过15mA。
    4、配多圈可调精密电位器调节灵敏度
    5、工作电压3.3V-5V
    6、输出形式 :数字开关量输出(0和1)
    7、设有固定螺栓孔,方便安装
    8、小板PCB尺寸:3.2cm x 1.4cm
    9、使用宽电压LM393比较器

    工作原理

      TCRT5000传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来但强度不够大时,光敏三极管一直处于关断状态,此时模块的输出端为低电平,指示二极管一直处于熄灭状态;被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,光敏三极管饱和,此时模块的输出端为高电平,指示二极管被点亮。

      由于黑色具有较强的吸收能力,当循迹模块发射的红外线照射到黑线时,红外线将会被黑线吸收,导致循迹模块上光敏三极管处于关闭状态,此时模块上一个LED熄灭。在没有检测到黑线时,模块上两个LED常量。
    ##循迹模块安装
      循迹模块的工作一般要求距离待检测的黑线距离1-2cm,因此我建议大家可以将循迹模块向下延伸。我自己是在硬纸板上面打了几个孔,固定循迹模块,每个模块之间可以留1cm左右的距离。传感器在接收到反射不同的距离的时候“AO”引脚电压会不同,是模拟信号,“DO”是数字信号输出。因为在这里我们只用判断是否检测到黑线,因此使用“DO”数字信号即可。按照车头为正方向,从右到左循迹模块的“DO”依次接到开发板“10”、“11”、“12”、“13”引脚。

    ## 跑道的搭建   找一块干净的地面,贴上准备好的黑色电工胶布。由于小车自身结构的原因,转弯的时候尽可能增大转弯半径,在跑道尽头如图中那样拉一条黑色横线,用于小车识别终点。

    测试代码

    #include <Servo.h>
    
    #define STOP      0
    #define FORWARD   1
    #define BACKWARD  2
    #define TURNLEFT  3
    #define TURNRIGHT 4
    
    int leftMotor1 = 16;
    int leftMotor2 = 17;
    int rightMotor1 = 18;
    int rightMotor2 = 19;
    
    int trac1 = 10; //从车头方向的最右边开始排序
    int trac2 = 11; 
    int trac3 = 12; 
    int trac4 = 13; 
    
    int leftPWM = 5;
    int rightPWM = 6;
    
    Servo myServo;  //舵机
    
    int inputPin=7;   // 定义超声波信号接收接口
    int outputPin=8;  // 定义超声波信号发出接口
    
    void setup() {
      // put your setup code here, to run once:
      //串口初始化
      Serial.begin(9600); 
      //舵机引脚初始化
      myServo.attach(9);
      //测速引脚初始化
      pinMode(leftMotor1, OUTPUT);
      pinMode(leftMotor2, OUTPUT);
      pinMode(rightMotor1, OUTPUT);
      pinMode(rightMotor2, OUTPUT);
      pinMode(leftPWM, OUTPUT);
      pinMode(rightPWM, OUTPUT);
      //寻迹模块D0引脚初始化
      pinMode(trac1, INPUT);
      pinMode(trac2, INPUT);
      pinMode(trac3, INPUT);
      pinMode(trac4, INPUT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
     
      tracing();
          
      
    }
    void motorRun(int cmd,int value)
    {
      analogWrite(leftPWM, value);  //设置PWM输出,即设置速度
      analogWrite(rightPWM, value);
      switch(cmd){
        case FORWARD:
          Serial.println("FORWARD"); //输出状态
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         case BACKWARD:
          Serial.println("BACKWARD"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNLEFT:
          Serial.println("TURN  LEFT"); //输出状态
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNRIGHT:
          Serial.println("TURN  RIGHT"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         default:
          Serial.println("STOP"); //输出状态
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, LOW);
      }
    }
    void tracing()
    {
      int data[4];
      data[0] = digitalRead(10);
      data[1] = digitalRead(11);
      data[2] = digitalRead(12);
      data[3] = digitalRead(13);
    
      if(!data[0] && !data[1] && !data[2] && !data[3])  //左右都没有检测到黑线
      {
        motorRun(FORWARD, 200);
      }
    
      if(data[0] || data[1])  //右边检测到黑线
      {
        motorRun(TURNRIGHT, 150);
      }
    
      if(data[2] || data[3])  //左边检测到黑线
      {
        motorRun(TURNLEFT, 150);
      }
    
      if(data[0] && data[3])  //左右都检测到黑线是停止
      {
        motorRun(STOP, 0);
        while(1);
      }
      
      Serial.print(data[0]);
      Serial.print("---");
      Serial.print(data[1]);
      Serial.print("---");
      Serial.print(data[2]);
      Serial.print("---");
      Serial.println(data[3]);
    }
    

    代码详解

    小车装有4个TCRT5000,从最右边模块开始读入数据,放入data[]数组中

    data[0] = digitalRead(10);
    data[1] = digitalRead(11);
    data[2] = digitalRead(12);
    data[3] = digitalRead(13);
    

    4个模块可能存在的检测状态如下,其中“1”表示检测到黑线,“0”代表没有检测到黑线:

    data[0]data[1]data[2]data[3]小车运动状态
    1111停止
    0011左转
    0001左转
    0010左转
    1100右转
    1000右转
    0100右转
    0000直行

    第一种情况,四个模块都没有检测到黑线时,直行:

    if(!data[0] && !data[1] && !data[2] && !data[3])  //左右都没有检测到黑线
    {
    	motorRun(FORWARD, 200);
    }
    

    右边任意一个模块检测到黑线时,右转:

    if(data[0] || data[1])  //右边检测到黑线
    {
      motorRun(TURNRIGHT, 150);
    }
    

    左边任意一个模块检测到黑线时,左转:

    if(data[2] || data[3])  //左边检测到黑线
    {
      motorRun(TURNLEFT, 150);
    }
    

    当四个模块都检测到黑线时,说明已经运动到轨道终点,此时停止运动:

    if(data[0] && data[3])  //左右都检测到黑线是停止
    {
      motorRun(STOP, 0);
      while(1);
    }
    

    循迹效果展示

    在起点出准备出发

    弯道中

    识别到终点后停止

    欢迎各位有兴趣的朋友加入Q群1:789127261点评、交流

    展开全文
  • 智能小车

    2013-09-25 23:14:34
    智能小车代码
  • 智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车智能小车
  • Arduino智能小车——测试篇

    万次阅读 多人点赞 2017-08-21 00:53:45
    Arduino智能小车——测试篇 上一章讲解了智能小车的拼装,但是还没有让小车动起来,这章我们将继续拼装,使得小车可以动起来。 驱动模块安装 可能有些朋友会问到,驱动是干嘛的,为什么要驱动,小时候玩四...

    Arduino智能小车——测试篇

    Arduino智能小车系列教程时空门:

    1. Arduino智能小车——拼装篇 点击跳转
    2. Arduino智能小车——测试篇 点击跳转
    3. Arduino智能小车——调速篇 点击跳转
    4. Arduino智能小车——超声波避障 点击跳转
    5. Arduino智能小车——蓝牙小车 点击跳转
    6. Arduino智能小车——循迹篇 点击跳转
    7. Arduino智能小车——小车测速 点击跳转

        上一章讲解了智能小车的拼装,但是还没有让小车动起来,这章我们将继续拼装,使得小车可以动起来。

    驱动模块安装

        可能有些朋友会问到,驱动是干嘛的,为什么要驱动,小时候玩四驱车的时候直接装上电池小车就跑了,干嘛还要驱动模块。答案很简单,四驱车他只能朝着一个方向运动,而且永远都是以最大速度运行,我们所做的智能小车通常要控制小车电机的转速和运行方向,因此驱动是必不可少的模块。驱动模块的具体工作原理不在这里做详细的介绍,想了解的朋友可以自行查阅资料。

    驱动模块用法简介

        一般拿到一个模块之后都要去对应的官网找到它的资料包,查看其详细用法,在某宝上买的模块一般店家都有整理好的资料包,所以某宝也是一个很好的资料库,大家一定要合理运用哦~

    在此我们选用的是L298N模块,该模块引脚分配如下:

    **+12V:**该引脚接的电压是驱动模块所能输出给电机的最大电压,一般 直接接电池。12V是由L298N芯片所能接受最大电压而定,一般介入5~12V电压。在此我们接入的电压为两节18650串联的电压,即3.7+3.7=7.4V;

    GND: 在该项目中GND即为电源的负极,同时要保证Arduino开发板,驱动模块等所有模块的GND连在一起才可以正常工作。在某些复杂的项目中还需要区分数字地和模拟地,在此不做详细介绍。

    +5V: L298N模块(注意不是L298N芯片)内含稳压电路(将高电压转换为低电压的电路),在模块内部将"+12V"引脚输入的电压转化为可供开发板使用的+5V电压,一般将次输出接入到开发板为开发板供电。

    L298N有两路输出,所以可以控制小车前进、后退、转弯,其中:
    ENA: 代表第一路输出的电压大小。驱动模块输出电压越高,电机转速越快。
    1.当其输入为0V的时候,驱动模块输出对第一路电机输出电压为0V;
    2.当其输入为3.3V的时候,驱动模块对第一路电机输出电压为"+12V"引脚的输入电压。
    3.由于ENA输入电压的高低控制驱动对电机的输出电压,因此当我们需要对小车运动速度进行控制的时候,一般通过PWM对"ENA"引脚进行控制。

    **IN1/IN2:**这两个引脚控制电机正反转方向。例:假如IN1输入高电平3.3V,IN2输入低电平0V,ENA为3.3V,电机正转,此时将IN1输入改为0V,IN2输入改为3.3V,其他条件不变,则电机将会反转。

    **OUT1/OUT2:**这两个引脚分别接电机的两极。

    **ENB,IN3/IN4,OUT3/OUT4引脚控制第二路输出,与上述ENB,IN3/IN4,OUT3/OUT4**功能相似。

    驱动安装

        将准备好的驱动模块固定在小车,将从地盘电机延长出来的导线分左右两边分开,左边两个电机中每一个电机的其中一根线OUT1,另外一个接OUT2。同理,右边两个电机中每一个电机的其中一根线OUT3,另外一个接OUT4,并用螺丝刀将拧蓝色接线柱上方的螺丝拧紧。

    电池座固定

        将电池固定在小车尾部,将电源的两根线链接到+12V和GND引脚,红色代表正极,接到+12V,黑色代表负极,接到GND(一般电路中默认红色为正,黑色为负),并拧紧螺丝固定。

    Ardunio开发板安装

        将Arduno板子用螺丝固定在小车中部,由于小车运动中也需要对开发板供电,此时我们用两根公对公的杜邦线为其供电,红色(也可以为其他颜色)杜邦线一边插入Arduino板的"5V"引脚,一边插到L298N驱动的"+5V"引脚,黑色(也可以为其他颜色)杜邦线一边插入Arduino板的"GND"引脚,一边插到L298N驱动的"GND"引脚。
        为控制电机的正反转,此时我们需要拿四根公对母杜邦线,将L298N驱动的IN1/IN2/IN3/IN3引脚与Arduino板的4/5/6/7号引脚对应相连,最终拼装图如下:

    抱歉,接线有点乱,大家可以用扎带或者皮筋将其捆好固定

        至此,我们的小车基本拼装完成,接下来就要开始写程序来控制小车运动咯,有没有很激动~

    Ardunio程序编写

    Arduino的程序编写一般使用Arduino IDE,该软件安装比较简单,大家可以自行安装,安装成功后打开IDE,在程序里写入下述代码:

    //定义五中运动状态
    #define STOP      0
    #define FORWARD   1
    #define BACKWARD  2
    #define TURNLEFT  3
    #define TURNRIGHT 4
    //定义需要用到的引脚
    int leftMotor1 = 4;
    int leftMotor2 = 5;
    int rightMotor1 = 6;
    int rightMotor2 = 7;
    
    void setup() {
      // put your setup code here, to run once:
      //设置控制电机的引脚为输出状态
      pinMode(leftMotor1, OUTPUT);
      pinMode(leftMotor2, OUTPUT);
      pinMode(rightMotor1, OUTPUT);
      pinMode(rightMotor2, OUTPUT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      int cmd;
      for(cmd=0;cmd<5;cmd++)//依次执行向前、向后、向左、想有、停止四个运动状态
      {
        motorRun(cmd);  
        delay(2000);//每个命令执行2s 
      } 
    }
    //运动控制函数
    void motorRun(int cmd)
    {
      switch(cmd){
        case FORWARD:
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case BACKWARD:
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         case TURNLEFT:
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNRIGHT:
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         default:
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, LOW);
      }
    }
    

    代码详解

    为方便代码的编写,提高代码的可读性,在此我们先定义出小车可能的运动状态

    #define STOP      0	//停止
    #define FORWARD   1	//前进
    #define BACKWARD  2	//后退
    #define TURNLEFT  3	//左转弯
    #define TURNRIGHT 4	//右转弯
    

    电机运动需要经过驱动模块驱动,而驱动模块的输出状态又取决去IN1/IN2/EN,IN3/IN4/ENB这两组引脚的控制。本实验只是简单控制电机的运动,不用控制电机的转速,因此ENA,ENB默认接入高电平(买过来模块的时候,你会发现这两个引脚都通过跳线帽和"+5V"的引脚相连,即输出最大电压),此时我们只需控制IN1/IN2,IN3/IN4两组引脚即可对小车的运动状态进行控制。因此我们在此定义以下四个引脚

    //定义需要用到的引脚
    int leftMotor1 = 4;
    int leftMotor2 = 5;
    int rightMotor1 = 6;
    int rightMotor2 = 7;
    

    当电机的两个输入端加入的电压有电压差,且电压差满足一定条件时电机才会转动,为控制L298N驱动OUT1/OUT2,OUT3/OUT4两路输出,我们需要了解该模块的使用方法。

    下面两个表格为L298N的输入输出对应关系,其中H:高电平,L:低电平,ENA、ENB均为高电平

    输入输出
    IN1IN2OUT1OUT1
    HLHL
    LHLH

    输入输出
    IN3IN4OUT3OUT4
    HLHL
    LHLH

    由上述表格可以清晰看出控制小车运动时,只需要将同一边的两个引脚设置成不同的输出电压即可,例如让小车向前运动时左右两边的IN1和IN2可以设置为

    digitalWrite(leftMotor1, LOW);
    digitalWrite(leftMotor2, HIGH);
    digitalWrite(rightMotor1, LOW);
    digitalWrite(rightMotor2, HIGH);
    

    为了提高代码的执行效率,我们在此将小车的四种运动状态封装在函数里,方便调用。

    void motorRun(int cmd)
    {
      switch(cmd){
        case FORWARD:
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case BACKWARD:
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         case TURNLEFT:
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
         case TURNRIGHT:
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
         default:
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, LOW);
      }
    }
    

    至此,小车应该便可以成功运动起来咯,快为自己庆祝下吧。接下来我们将在此基础上进项进一步的开发,大家再接再厉哦
    ##调试中可能出现的问题

    问题1.

    下载完程序,小车向前运动时,有些轮子向前,有些轮子运动方向相反:
    将运动方向错误的电机的两根电源线在驱动上的接线位置对换。例如将本来接OUT1的电源线换到OUT2,将接OUT2的电源线换到OUT1。

    问题2.

    代码没变,但是电机一会儿动一会不动:
    这样的情况一般是由于接触不良造成的,检查你的驱动输出到电机的电源线是否有松动或者接触不良的情况。

    问题3.

    向前运动时他向后,向后运动时他向前,向左运动时他向右:
    解决方案1:按照 问题1 中那样的解决方案,一个一个换线
    解决方案2:将void motorRun(int cmd)函数中,引脚输出状态反过来,例如解决向前运动时他向后这种错误状态

    case FORWARD:	//原来的代码
          digitalWrite(leftMotor1, LOW);
          digitalWrite(leftMotor2, HIGH);
          digitalWrite(rightMotor1, LOW);
          digitalWrite(rightMotor2, HIGH);
          break;
    
    case FORWARD:	//修改后的代码
          digitalWrite(leftMotor1, HIGH);
          digitalWrite(leftMotor2, LOW);
          digitalWrite(rightMotor1, HIGH);
          digitalWrite(rightMotor2, LOW);
          break;
    

    欢迎各位有兴趣的朋友加入Q群1:789127261点评、交流

    展开全文
  •    从本文开始,在之后的一段时间里,我会通过本系列文章,详细介绍如何从零开始用51单片机去实现智能小车的控制,本文作为本系列的第一篇文章,主要介绍如何让小车动起来。 一、硬件的选择    1、底盘和电机  ...

       从本文开始,在之后的一段时间里,我会通过本系列文章,详细介绍如何从零开始用51单片机去实现智能小车的控制,本文作为本系列的第一篇文章,主要介绍如何让小车动起来。

    本系列文章链接:

    -----------------------------------------------------------------------------

       详细介绍如何从零开始制作51单片机控制的智能小车(一)———让小车动起来
       详细介绍如何从零开始制作51单片机控制的智能小车(二)———超声波模块、漫反射光电管、4路红外传感器的介绍和使用
       详细介绍如何从零开始制作51单片机控制的智能小车(三)———用超声波模块和漫反射光电传感器实现小车的自动避障
       详细介绍如何从零开始制作51单片机控制的智能小车(四)———通过蓝牙模块实现数据传输以及通过手机蓝牙实现对小车运动状态的控制
       详细介绍如何从零开始制作51单片机控制的智能小车(五)———对本系列第四篇文章介绍的手机蓝牙遥控加减速异常的错误的介绍及纠正

    -----------------------------------------------------------------------------

    一、硬件的选择

       1、底盘和电机

       底盘的形状呢,大家可以按照自己的需要自主选取,至于电机关注一下工作电压,转速,电机类型就差不多,对于新手,可以尝试以下样式(4WD智能小车底盘,附带4个直流减速电机,电机接线需要自己焊接),也就是本文例子采用的底盘和电机,组装简单,使用方便,特别适合新手。

    在这里插入图片描述

       2、电机驱动模块

        L298N电机驱动模块,绝对是新手的首选,但是此系列也包含了很多类型,本文采用的是L298N双H桥驱动 红色版 ,除了性能外,我选择它是因为它具备了5v的输出接口,可以用来给单片机供电。大家可以用两个这种驱动,也可以用一个,另一个用个便宜点的。
        由于家中有一个如下式样的L298N驱动,所以为了不让资源浪费,另一个,我就用如下型号的L298N驱动。

       3、单片机最小系统

        关于最小系统,大家只要选用自己熟悉的就行了,没什么特别的讲究,我采用的样式如下(芯片采用的是STC89C52)

       4、电源

        这一部分大家根据需要自己选择即可,选的时候注意一下电压和容量就行,我选用的是常见的 9v 650mAh(容量不是很大,但是这种电池比较常见,充一次电跑2~3小时应该不是问题),我选的是USB充电款,充电很方便,电池盒我选用的是如下的这种拆卸方便的款式,缺点就是不附带电源开关。

       5、杜邦线

        这是必备的辅件,就不多说了,公对公,母对母,公对母(这一种一般用的多一些)都要买一些,家里常备物品。

    二、硬件的连接

        本文涉及到的硬件连接为单片机、电源、 电机、 两个电机驱动L298N之间的连接,在这里我介绍一种参考的连接方式,大家可以自己设计连接方案
        如上图所示,四个电机的正负极分别接两个L298N的绿色电机接口,至于到底哪个接正极,哪个接负极,根据你电机安装的方式而定,建议先把电机的两根线焊上,然后把底盘安装起来,这样电机的安装方式就确定了,先随便把两个L298N的4个绿色电机接口跟电机相接,等到把其他信号线接好后,再判断对错并调节,调节方法如下:在程序中让小车往前跑,观察车轮的转向,往前转的车轮的线不用变,把往后转的电机对应的L298N绿色接口的两根线换一下就行了。
       如上图所示,L298N的左边数第一个蓝色端口 是5V输出,把其中一个L298N的该接口接到单片机的5v接口上,另一L298N该接口可以空着,左边数第二个蓝色端口是GND需要同时与单片机的GND与电源的负极相接,左边数第三个蓝色端口是L298N的电源输入端口,与电源的正极相接,我采用的是9v的电源。
       剩下的就是L298N的信号线与单片机的连接了,介绍如上图所示,在这里我采用的是双驱的接法,也就是左边两个点击用同一个信号控制,右边两个电机用同一个信号控制,单片机的I/O口自行选择,与程序配合起来就行,我选用的是 ENA接P16 ENB 接P17 IN1接P34 IN2接P35 IN3接P36 IN4接P37 若改为4驱所需的I/O将扩大一倍。

       收到部分读者说这部分连线还是不太明白,于是我简单画了以下的草图,帮助大家理解上面的内容(字不好看,请见谅)

       实物图片如下:

    三、程序的编写

       1、工程的建立

       编译环境根据自己习惯和需要选择,本文以KEIL C51为例,由于本次设计的小车控制并不复杂,所以我把工程中用到的所有头文件、函数的定义、sbit定义的位变量都放到了一个头文件中,取名为car.h(名字大家随意取即可),C文件呢我建议大家把各个部分别写在不同的文件中,比如我把与电机驱动有关的函数放到了motor_control.c(名字任意取)文件中,控制方案和延时函数,中断函数放到了主函数main.c(名字任意取)文件中,后续随着功能增加还会增设其他的C文件,只要所有的C文件均包含以上共同的头文件car.h,也就互相建立了联系。

       2、根据L298N与单片机的接线,编写电机控制函数

       虽然说本文选用的车型四个电机可以独立控制,但是为了简单化,方便化,我们让左边的两个电机采用共同的信号控制,右边的两个电机采用共同的信号控制,大家若需要可以自主改为4路独立的信号控制,根据本文第二部分——硬件的连接部分的介绍,我们选用了单片机的P34 P35 I/O口作为左电机的方向控制信号,单片机的P36 P37 I/O口作为右电机的方向控制信号,单片机的P16 I/O口作为左电机的PWM输出控制信号,单片机的P17 I/O口作为右电机的PWM输出控制信号。
       以上6个I/O口的位定义如下(为方便各文件调用,我们把它放到统一的h文件car.h中)
    sbit Left_moto_pwm=P1^6 ;
    sbit Right_moto_pwm=P1^7;
    sbit p34=P3^4;
    sbit p35=P3^5; 
    sbit p36=P3^6;
    sbit p37=P3^7;
    
        左右电机的状态控制函数如下:
    void Left_moto_go()  //左电机正转
    {p34=0;p35=1;} 
    void Left_moto_back() //左电机反转
    {p34=1;p35=0;} 
    void Left_moto_stp()  //左电机停转
     {p34=1;p35=1;} 
    void Right_moto_go()  //右电机正转
    {p36=0;p37=1;} 
    void Right_moto_back() //右电机反转
    {p36=1;p37=0;}  
    void Right_moto_stp()  //右电机停转
    {p36=1;p37=1;} 
    
    

      4、PWM调速输出函数的编写:

        对于新手来说,如果理解不了以下两个函数,那只需要知道如何使用就行了,即通过修改push_val_left的值就可以调节左电机的转速,通过修改push_val _right的值就可以调节右电机的转速,push_val_left和push_val_right的值均位于1到10之间,值越大电机转速越快
    bit Left_moto_stop =1;
    bit Right_moto_stop =1;
    unsigned char pwm_val_left =0;
    unsigned char push_val_left =0; 
    unsigned char pwm_val_right =0;
    unsigned char push_val_right=0;
    
    
    void pwm_out_left_moto(void)     //左电机调速
    { 
    if(Left_moto_stop) 
    { 
    if(pwm_val_left<=push_val_left) 
    Left_moto_pwm=1; 
    else 
    Left_moto_pwm=0; 
    if(pwm_val_left>=10) 
    pwm_val_left=0; 
    } 
    else 
    Left_moto_pwm=0; 
    } 
    
    void pwm_out_right_moto(void)   //右电机调速
    { 
    if(Right_moto_stop) 
    { 
    if(pwm_val_right<=push_val_right) 
    Right_moto_pwm=1; 
    else 
    Right_moto_pwm=0; 
    if(pwm_val_right>=10) 
    pwm_val_right=0; 
    } 
    else 
    Right_moto_pwm=0; 
    } 
    

      5、小车姿态控制函数的编写:

       理解了 左右电机的状态控制函数,编写小车姿态控制函数就很简单了,大家稍微想一下小车左右轮的状态,小车会怎么运行,就理解了,比如 左右电机都正转,那小车运行状态肯定是前行。每个函数的前两行是左右电机转速的设置。
    
    unsigned char Left_Speed_Ratio;  //左电机转速的设定值
    unsigned char Right_Speed_Ratio; //右电机转速的设定值
    
    
    
    void run(void)     //小车前行
    { 
    push_val_left =Left_Speed_Ratio;    
    push_val_right =Right_Speed_Ratio; 
    Left_moto_go(); 
    Right_moto_go(); 
     } 
    
     
    
    void back(void)   //小车后退
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_back();
    Right_moto_back();
     } 
    
    
    
    void left(void)   //小车左转
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio;
    Right_moto_go(); 
    Left_moto_stp();
    } 
    
     void right(void) //小车右转
    { 
    push_val_left =Left_Speed_Ratio;
    push_val_right =Right_Speed_Ratio;
    Right_moto_stp();
    Left_moto_go();
    } 
    
    void stop(void)  //小车停止
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_stp();
    Right_moto_stp();
     } 
    
    void rotate(void) //小车原地转圈
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_back();
    Right_moto_go();
     } 
    

      6、与定时器中断有关函数的编写

    void Timer0Init()    //定时器初始化函数
    {
    	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
    
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;	
    	ET0=1;//打开定时器0中断允许
    	EA=1;//打开总中断
    	TR0=1;//打开定时器			
    }
    
    
    
    void timer0()interrupt 1 using 2  //定时器中断函数,此处配置为1ms产生一次中断,对PWM的输出进行控制
    { 
    TH0=0XFC;	//给定时器赋初值,定时1ms
    TL0=0X18;
    time++; 
    pwm_val_left++; 
    pwm_val_right++; 
    pwm_out_left_moto(); 
    pwm_out_right_moto(); 
    } 
     
    

      7、延时函数的编写

       关于延时函数,大家只要会用就行,可以用单片机小精灵等辅助软件生成,以下为延时1秒的函数
    void delay1s(void)   
    {
        unsigned char a,b,c;
        for(c=167;c>0;c--)
            for(b=171;b>0;b--)
                for(a=16;a>0;a--);
        _nop_();  
    }
    

      8、主函数内容的编写

       关于主函数的内容,首先要调用定时器中断初始化函数,其次要设置左右电机的速度参数,本文的主要内容是让车动起来,所以主函数内要调用本部分第5步中编写的小车姿态控制函数,对其进行检验,为了便于观察两个状态之间加了5秒的延时,代码如下:
    void main()
    	{
    	Timer0Init();  
    	Left_Speed_Ratio=5;   //设置左电机车速为最大车速的50%
    	Right_Speed_Ratio=5;	设置右电机车速为最大车速的50%
    	while(1)
    		{
    	run();
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
    	back();
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
        left();
        delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
        right();
        delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
    	stop();		
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
        rotate();
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();		
    					
    		}
    }
    

    四、本文例子完整的C文件和H文件代码

       1、motor_control.c文件完整代码如下:

    #include <car.h>
    
    
    unsigned char pwm_val_left =0;
    unsigned char push_val_left =0; 
    unsigned char pwm_val_right =0;
    unsigned char push_val_right=0;
    unsigned char Left_Speed_Ratio;
    unsigned char Right_Speed_Ratio;
    
    bit Left_moto_stop =1;
    bit Right_moto_stop =1;
    
    
    void Left_moto_go()  //左电机正转
    {p34=0;p35=1;} 
    void Left_moto_back() //左电机反转
    {p34=1;p35=0;} 
    void Left_moto_stp()  //左电机停转
     {p34=1;p35=1;} 
    void Right_moto_go()  //右电机正转
    {p36=0;p37=1;} 
    void Right_moto_back() //右电机反转
    {p36=1;p37=0;}  
    void Right_moto_stp()  //右电机停转
    {p36=1;p37=1;} 
    
    
    void pwm_out_left_moto(void)    //左电机PWM
    { 
    if(Left_moto_stop) 
    { 
    if(pwm_val_left<=push_val_left) 
    Left_moto_pwm=1; 
    else 
    Left_moto_pwm=0; 
    if(pwm_val_left>=10) 
    pwm_val_left=0; 
    } 
    else 
    Left_moto_pwm=0; 
    } 
    
    void pwm_out_right_moto(void)    //右电机PWM
    { 
    if(Right_moto_stop) 
    { 
    if(pwm_val_right<=push_val_right) 
    Right_moto_pwm=1; 
    else 
    Right_moto_pwm=0; 
    if(pwm_val_right>=10) 
    pwm_val_right=0; 
    } 
    else 
    Right_moto_pwm=0; 
    } 
    
    
    void run(void)     //小车前行
    { 
    push_val_left =Left_Speed_Ratio;    
    push_val_right =Right_Speed_Ratio; 
    Left_moto_go(); 
    Right_moto_go(); 
     } 
    
     
    
    void back(void)   //小车后退
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_back();
    Right_moto_back();
     } 
    
    
    
    void left(void)   //小车左转
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio;
    Right_moto_go(); 
    Left_moto_stp();
    } 
    
     void right(void) //小车右转
    { 
    push_val_left =Left_Speed_Ratio;
    push_val_right =Right_Speed_Ratio;
    Right_moto_stp();
    Left_moto_go();
    } 
    
    void stop(void)  //小车停止
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_stp();
    Right_moto_stp();
     } 
    
    void rotate(void) //小车原地转圈
    { 
    push_val_left =Left_Speed_Ratio; 
    push_val_right =Right_Speed_Ratio; 
    Left_moto_back();
    Right_moto_go();
     } 
    
    

       2、main.c文件完整代码如下:

    #include <car.h>
    
    extern unsigned char Left_Speed_Ratio;
    extern unsigned char Right_Speed_Ratio;
    unsigned int time=0; 
    extern unsigned char pwm_val_left;
    extern unsigned char pwm_val_right;
    
    void delay1s(void)   
    {
        unsigned char a,b,c;
        for(c=167;c>0;c--)
            for(b=171;b>0;b--)
                for(a=16;a>0;a--);
        _nop_();  
    }
    
    void Timer0Init()
    {
    	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
    
    	TH0=0XFC;	//给定时器赋初值,定时1ms
    	TL0=0X18;	
    	ET0=1;//打开定时器0中断允许
    	EA=1;//打开总中断
    	TR0=1;//打开定时器			
    }
    
    
    
    void timer0()interrupt 1 using 2 
    { 
    TH0=0XFC;	//给定时器赋初值,定时1ms
    TL0=0X18;
    time++; 
    pwm_val_left++; 
    pwm_val_right++; 
    pwm_out_left_moto(); 
    pwm_out_right_moto(); 
    } 
    
    void main()
    	{
    	Timer0Init();  
    	Left_Speed_Ratio=5;   //设置左电机车速为最大车速的50%
    	Right_Speed_Ratio=5;	设置右电机车速为最大车速的50%
    	while(1)
    		{
    	run();
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
    	back();
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
        left();
        delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
        right();
        delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
    	stop();		
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();
        rotate();
    	delay1s(); delay1s();  delay1s();  delay1s();  delay1s();		
    					
    		}
    }
    
    
    

       3、car.h文件完整代码如下:

    #ifndef __car_H
    #define __car_H
    
    #include <reg52.h>
    #include <intrins.h>
    
    sbit Left_moto_pwm=P1^6 ;
    sbit Right_moto_pwm=P1^7;
    sbit p34=P3^4;
    sbit p35=P3^5; 
    sbit p36=P3^6;
    sbit p37=P3^7;
    
    
    void Left_moto_go() ;
    void Left_moto_back() ;
    void Left_moto_stp() ;
    void Right_moto_go();
    void Right_moto_back(); 
    void Right_moto_stp(); 
    void delay(unsigned int k) ;
    void delay1s(void) ;
    void pwm_out_left_moto(void) ;
    void pwm_out_right_moto(void);
    void run(void);
    void back(void);
    void left(void);
    void right(void);
    void stop(void);
    void rotate(void);
    
    

    五、本文例子实物视频演示

           实物视频演示视频链接

        点击上面的链接即可查看本文介绍内容的视频演示,内容依次为(即主函数中程序的内容):前进5秒 、后退5秒、左转5秒、右转5秒、停转5秒、转圈5秒。附视频网址:

        https://www.bilibili.com/video/bv1N5411x7zL

       本文到这里就结束了,本文完整的工程文件我会放在附件里,需要者自取,我放的时候都是免费的,但是过段时间它会自己涨…,欢迎大家继续阅读本系列的后续文章“详细介绍如何从零开始制作51单片机控制的智能小车(二)———超声波模块、漫反射光电管、4路红外传感器的介绍和使用”

       本系列文章的附件已经支持自主下载,附件获取方式如下(推荐通过Gitee免费下载):
    https://blog.csdn.net/qq_44339029/article/details/114887405

       欢迎大家积极交流,本文未经允许谢绝转载

    展开全文
  • 根据红外原理,可以远程遥控智能小车,实现小车的行进
  • Arduino智能小车——超声波避障

    万次阅读 多人点赞 2017-09-01 21:17:36
    Arduino智能小车——超声波避障  经过这几篇的测试大家应该对小车有一定的认识了,在实际的操作过程中经常会由于操作不当各种碰壁吧?那这次我们将给小车装上一只“眼睛”,让小车看到障碍,躲避障碍。准备材料...
  • Arduino智能小车——拼装篇

    万次阅读 多人点赞 2019-05-20 10:24:35
    Arduino智能小车——拼装篇简介Arduino是一款便捷灵活、方便上手的开源电子原型平台,比较适合刚接触硬件的入门级开发者学习。在我身边有很多初学者都陷入了这么一种困境,已经将Arduino官网的教程全部跑完,然而...
  • 智能小车-51单片机-智能小车超声波避障 智能小车-51单片机-智能小车超声波避障
  • 避障智能小车代码基于STM32,函数库开发相关配置
  • 基于stm32的智能小车控制程序,可实现遥控自动追踪等功能
  • 智能小车原理图智能小车原理图智能小车原理图智能小车原理图
  • Arduino智能小车——小车测速

    万次阅读 多人点赞 2019-05-20 10:25:04
    Arduino智能小车——小车测速  可以用于测速的模块很多,比如加速度计、激光、超声波、编码器等等,由于我们对小车速度的测量精度要求不高,因此我们可以借助小车套件里面的码盘配上测速模块对其速度进行测量。...
  • 基于51单片机的循迹避障遥控智能小车原创技术报告。包括原创代码,增强型最小系统pcb等内容。实现循迹、避障、无线遥控等三个功能。
  • 智能小车代码

    2019-03-08 19:38:45
    智能小车学习网站链接

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,284
精华内容 5,313
关键字:

智能小车