写点什么

基于 STM32 设计避障寻迹小车

作者:DS小龙哥
  • 2023-04-25
    重庆
  • 本文字数:8915 字

    阅读完需:约 29 分钟

一、前言

1.1 项目背景

根据美国玩具协会在一项研究中,过去几年全球玩具销售增长与 GDP 的世界平均水平大致相同。但全球玩具市场的内部结构已经占据了巨大的位置变化:传统玩具的市场份额正在下降,高科技电子玩具正在蓬勃发展。全球玩具市场的高科技电子游戏 2010 年的年销售额增长了 67%,但传统玩具的年销售额仅增长了 1%。


2001 年,十大最受欢迎的圣诞玩具之一有电子玩具。智能系统之前在很多领域,如智能工程、IT、集成引擎及行业整合正在讨论,就必须变得更聪明。可见传统的控制概念不能满足用户的需求,并与这些传统的控制相关的智能控制提高了一般的优势和较好满足人的需求。人工智能和计算机的不断发展,智能控制领域取得了很大的创新。因此,找到并使用远程控制和智能技术非常重要。而且市场价值超群。


智能汽车是一种识别的多功能智能设备决策的自主水平的机械设计,信息技术和人工智能领域的主动管理的环境中。它可分为三个部分:一个驱动部件,所述检测传感器和所述控制器的一部分。分别在物流运输方面发挥军事,安全检查和破坏程度进行评估的应用的作用。



1.2 小车的现状

【1】国内:在上世纪 80 年代末,中国开始研究智能车,几十年的研究后,取得了一些阶段性成果。7B.8 智能车辆系统。该系统是由南京理工大学、北京理工大学、浙江大学、国防科技大学、清华大学等多所院校联合硏制,属于军用室外智能车辆,于 1995 年底通过验收。


【2】国外:智能车辆的研发在国外的很多机构都得到了很大的创新,尤其是在科学和工业设计等领域,获得了更进一步的扩展,研发技术已经达到了很高的水平,其中具有代表性的智能车辆包括:


美国卡内基梅隆大学机器人研究所研制的 Navlab 系列智能车辆系统, 该系统的车体采用 Pontiac 运动跑车,其传感器系统包括视觉、差分 GPS 系统。


德国 Vamos—P 智能车辆系统该传感器系统包括两个有源双筒望远镜系统配置 PZSA 相机 4 种颜色,三个线性加速度计和角惯性传感器改变状态转速计和发动机的测量装置。驱动方向包括发动机转矩,液压制动器和电子节气门。

二、系统设计

2.1 主控系统设计

根据设计要求,控制器主要用在控制电机,并通过有关的传感器处理通道的轨道信息,将处理信号传送给控制器,然后通过控制器可以进行相应的处理,以此用来实现电机的前进和后退,确保在实验范围内能够进行躲避障碍和寻找痕迹还有加速减速等等动作。


供应链管理为核心的系统,在汽车的道路的控制,以达到他们的目标。 我们的系统进行完整的分析,关键要实现自动车辆控制,但此刻,微控制器已经显示出它的优势是简单,方便,快捷。


STM32 具有低功耗,高时钟速度和短中断延迟的特点。 CORTEX-M3 是一款 32 位 ARM7 系列处理器,包括处理器内核,内存单元,总线接口和跟踪调试单元。本设计中使用的 STM32 F103ZET6 微控制器直接用于最小的开发板,便于学习和使用。STM32F103 功能及特点。


功能包含内核(ARM 32 位的 Cortex™-M3 CPU)、储存器、时钟、复位和电源管理、 低功耗、 2 个 12 位模数转换器, 1μs 转换时间(多达 16 个输入通道)、 DMA、多达 80 个快速 I/O 端口、 调试模式、多达 7 个定时器、多达 9 个通信接口、CRC 计算单元, 96 位的芯片唯一代码。


特点是集成了强大的硬件系统,使其在工作中消耗更少的电力。它是一个 16/32 位混合编码指令,可以与拇指指令兼容。NVIC 是 CORTEX-M3 的紧密耦合部分,可配置 240 个中断并分为 256 个优先级,CORTEX-M3 还使用尾链技术,使得背对背中断响应仅 6 个时钟周期,因此中断响应更迅速。


MPU 是处理器中的存储模块,通过定义和检查存储区域的属性来实现存储功能。调试访问接口可以用作串口或串行 JTAG 调试端口。串口调试端口只能通过时钟和数据两个引脚进行调试,以保证低成本。


STM32 处理器分为标准化、增强型和最新产品。STM32 F101 为标准型,频率为 36 兆赫 ;STM32 F103 是增强型,频率为 72 兆赫,STM32 F105 和 STM32 F107 是最新的系列产品,增加了 USB 和以太网接口。


依据如上的分析,选择 P89C51 RAM 单片机为这个设计的主要控制装备,使用 STM32 芯片作为设计的开发芯片。由于其存储性能强,功耗小,能满足复杂编程功能的要求,且成本较低,对于这种设计来说是绰绰有余。

2.2 电机驱动模块

2.2.1 供电方式

方案一:采用单电源同时提供单片机和直流电机。该方案的优点是减小了机身的重量,操作简单。这会让单片机的波动变得很大,影响到单片机的性能,稳定性变得不高。


方案二:采用双电源供电,通过两个外界移动电源进行供电,该方案的优点是减小了波动,稳定性更好,可以更好地操作汽车。


方案三:多电池串联供电。由于单片机的工作电压在 5V 左右,直流电压也小,可以通过电池供电,使电池串联连接,保证了系统的正常运行。


综合考虑,使用第二方案。

2.2.2 驱动电机方式

功率晶体管用作功率放大器的输出信号以驱动 DC 电动机。 线性控制电路的结构比较简单,原理简单,加速度强。 方案 H 桥达林顿配置。 达林顿微处理器控制,可调孔隙率操作状态切换时,电机速度的更精确的控制。


从电路的管道饱和效率关模式是非常高的。H 型桥式电路确保了速度和方向的简单控制。电子管的开关速度非常快,稳定性很强。它是一种广泛应用的 PWM 调速技术。现在市场上有很多芯片。我选择了 L298N。该实施例具有优异的特性的头速度,平滑控制,一个宽的速度范围,大的过载可承受频繁的冲击载荷也可以实现无级地频繁很快开始,制动和扭转等。 因此,我们决定使用的功率晶体管作为发动机功率放大器 DC 的输出控制。



图 2.1.1 H 桥式电路



图 2.2.2 L298N

2.2.3 电机驱动选择

方案一:DC 电机的使用具有硬件电路设计简单的优点。当使用额定的直流电压时,速度变化不大,调速性能很好,性价比很高。对于小车,它可以很好地控制。


方案二:步进电机,步进电机可实现精确的转角输出,只要应用合适的脉冲序列,电机就可以按照人们预定的速度或方向连续旋转,控制速度很慢,但软件程序的编程是一个比直流电机更复杂。


所以我选择方案一,好控制且性价比高。

2.3 循迹模块

方案一:这个模块使用了两个红外对管(如图 2.3),分别放在小车车前左右两边,由光电开关的检测情况可知,来控制小车的行驶和转向,通过测试表明,只要合理的安排两个光电开关的位置,就可以达到循迹的功能。


方案二:使用三对红外管,其中的两个红对外管可以检测到黑线。 在黑线轨道之后,汽车将立即调整到中心灯开关的方向,再次检测黑线,即返回轨道。那么它就会再次沿着黑线行驶。但是,现场的观察表明,小车在寻机的过程中会左右摇摆,虽然可以正确的寻迹,但是成本和稳定性都无法和第二方案相比较。


通过比较,我选取第二种方案来实现循迹



图 2.3 红外对管

2.4 避障模块

2.4.1 红外线避障

方案一:在小车的中央使用红外线管。安装容易,可以检测障碍物的存在,但很难确定汽车是否会在水平方向上与障碍物碰撞,不容易使汽车做出准确的转向反应。最终没有采纳这个方案。


方案二:车辆的前部的两侧布置了两个红外线管,平行于机器方向。 它可以精确地确定车辆和障碍,和及时响应的相对距离和方向。缺点是对硬件要求较高,且成本比较大。


方案三:在小车的右侧使用红外线管。通过对该方案的测试,可以避免障碍物,充分利用资源而不浪费。但是在右侧会有部分死角,不利于小车完美避障。最终没有采纳这个方案。


方案四:把一个包括有舵机的红外线管装置在小车的头部。借助旋转的功能可以全方位的了解四周的情况并及时作出反应,缺点就是我们需要安装舵机,并编写多个程序使它运行,这就加大了工作负担。并且需要制作不宜过重的舵机,还要是其旋转角度为最佳,工作过程过于麻烦,故未选择该方案。


所以采用第二种。

2.4.2 超声波避障

方案一:串联电阻转速控制系统。


方案二:静态可控整流器。V-M 系统简称。


方案三:脉宽调制系统。


旋转式交流转换系统由交流发电机驱动,交流发电机改变直流电动机,并由需要速度控制的直流电动机发电机供电。发电机的输出电压可以通过调整发电机励磁电流和通过调节电机的速度被改变。


如果激励变化的侧电流 输出电压的极性是从电机的极性不同。因此,G-M 系的可逆操作可以是相对简单的。 该系统需要一个可变旋转速度旋转单元,其包括具有相同容量的电动机速度控制的至少两个旋转机械。它还需要一个激励发生器。但他的装备很笨重。成本高,效率低,维护不实用。而且由于技术落后,因此不需要搁置。


V-M 系统是直流调速系统的主要形式。 有许多类型,例如:单相,三相或更多,相位,半波,交替,半控制,总控制等,它们可以实现平稳的速度控制。 V-M 系统的缺点是晶闸管的单向导电性。它不允许反向电流引起系统的可逆操作。另一个缺点是高操作和维护条件。最后,如果系统以低速运行,其功率将非常低,此时产生的高谐波电流将损坏附近的电气设备。


晶闸管与相位无关。当晶闸管跳闸时,电源电压会施加到电机上。当晶闸管断开时,直流电源与电动机断开。电动机继续在二极管中流动,并且通过它的电压接近零。脉冲宽度调制(PWM)。脉冲具有恒定的周期,并且仅改变为晶闸管指定的时间,即通过改变脉冲的宽度来调节连续速度。


与 V-M 系统相比,PWM 调速系统具有以下优点:


(1)由于 PWM 速度控制系统的高频开关,只能通过发动机电感滤波器获得小的 DC 纹波电流。由于上述现有的信号系统,V-M 的系统,具有相同的平均电流相对小的热机。


(2)由于开关频率高,如果快速响应匹配到发动机,该系统能够是宽带,响应速度快,因此,良好的性能,动感较强的抗干扰能力。


根据上述的综合比较,和发动机控制能力,并在这种设计中的 DC 马达的速度调节的发展方向,该设计依赖于调节 PWM 输出的速度,以一个小的计算机芯片的单 MEGA16,从而可以实现更好的控制 EF。FECT 与 LM29 芯片相结合。在避开障碍物的过程中,电机也可以通过直接控制 LM29 8 芯片来控制。操作方便,易于翻转和倒退功能。


所以我选择了方案三。

2.5 遥控变速系统

本课题要求智能小车可以遥控可变速,所以加上遥控系统。


在本课题中利用按键和 LCD1602 结合进而改变小车的速度问题。这样可以减轻负担且更加直接的改变小车的速度。

2.6 LCD1602 液晶显示模块

在日常生活中,我们对液晶显示器并不陌生。我使用的液晶的显示部,许多电子产品,如计算器,万用表,数字时钟,和许多消费电子产品,数码屏幕基材以及特殊字符和图形的通道。 人与机器在单芯片微型计算机之间的通信接口, 一般输出模式如下:管发光管,LED 数字显示,屏幕流体。


液晶显示器的好处如下:显示质量高,由于每个点都保持液晶彩色 LCD,在接收到信号亮度后,产生耐用性,不像阴极射线管供电(CRT),需要不断更新新的亮点。因此,液晶显示器画质高且不会闪烁。而且其数字式接口体积小、重量轻功耗低 。


另一方面,LCD 的功耗主要在其内部电极和驱动器的 IC 器件上消耗,因此比其他监视器消耗更少的能量。

2.6.1 液晶显示简介

  1. 液晶显示原理


液晶显示器的原理依赖于液晶的物理特性。通过控制其显示区域中的电压,存在电子显示器,即可以显示图像。其中,适用于 LSI 直接控制且易于操作的低厚度液晶显示器广泛用于移动通信设备的许多领域,例如笔记本电脑,数码相机和个人数字助理。


  1. 液晶显示器的分类


LCD 的分类方法有很多种,根据显示的不同,可以分为段类型,字符类型,点阵类型等。除了黑白显示外,LCD 还具有多级彩色显示屏。如果按行为方式划分,则可分为静态(静态),简单矩阵(简单矩阵)和有源矩阵(有源矩阵)。


字符的显示用 LCD 显示一个字符时比较复杂,因为一个字符由 6×8 或 8×8 点阵组成,既要找到和显示屏幕上某几个位置对应的显示 RAM 区的 8 字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。这样一来就组成某个字符。但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在 LCD 上开始显示的行列号及每行的列数找出显示 RAM 对应的地址,设立光标,在此送上该字符对应的代码即可。


1602 字符型 LCD 简介


液晶显示单元是专门用于显示字母,数字,符号等的点阵 LCD 显示器。目前常用 161,162,202 和 402 行等的模块。一般 1602 字符型液晶显示器实物如图 2.6.1 和 2.6.2:



图 2.6.1



图 2.6.2 1602 字符型液晶显示器实物图

2.6.2 1602LCD 的基本参数及引脚功能

1602LCD 主要技术参数:


显示容量:16×2 个字符


芯片工作电压:4.5—5.5V


工作电流:2.0mA(5.0V)


模块最佳工作电压:5.0V


字符尺寸:2.95×4.35(W×H)mm


引脚功能说明:


各引脚接口说明如表 1 所示:



表 2.6.1 引脚接口说明表

2.6.3 1602LCD 的指令说明

1602 液晶模块内部的控制器共有 11 条控制指令,如表 2 所示:



表 2.6.2 控制命令表


1602 液晶模块通过指令编程来实现读写操作、屏幕和光标的操作。(说明:1 为高电平、0 为低电平)

2.6.4 1602LCD 的 RAM 地址映射及标准字库表

LCD 模块运行缓慢,因此在执行每条命令前检查模块的忙标志,将其设置为低电平表示它不忙,否则命令无效。要显示其指示器模块,字符显示的第一个字符输入字符显示地址,图 2.6.3 是 1602 的内部显示地址。



图 2.6.3 1602LCD 内部显示地址


当初始化设置在液晶模块,其中所述第一显示模式时,光标自动地移动到右侧,如果液晶显示单元的符号,无需人工干预。 前每个命令输入被定义为液晶模块处于繁忙状态。


1602 LCD 模块在字符生成存储器(CGROM)中存储了 160 个不同的点阵字符,如图 2.6.4 所示。这些字符是:日语假名等,每一个字符具有固定的代码,如英文大写字母“代码”是 01000001b(41H)时,模块显示在 41H 的图矩阵字符。我们就能看到字母“A”。



图 2.6.4 字符代码与图形对应图

2.6.5 1602LCD 的一般复位过程

延时 15mS


写指令 38H(不检测忙信号)


延时 5mS


写指令 38H(不检测忙信号)


延时 5mS


写指令 38H(不检测忙信号)


以后每次写指令、读/写数据操作均需要检测忙信号


写指令 38H:显示模式设置


写指令 08H:显示关闭


写指令 01H:显示清屏


写指令 06H:显示光标移动设置


写指令 0CH:显示开及光标设置

2.7 机械系统

本设计要求汽车的机械系统稳定、灵活、简单,三轮运动系统具有上述特点。


驱动部分:由于玩具车的直流电机功率小,车内装有电池、电机和电子设备,使电机负荷较重。为了使汽车平稳地起动和平稳地行驶,在直流电动机和轮轴之间安装了三个减速齿轮。


电源部分:利用两个外接电源。


电机驱动部分主要由单芯片 L29 8N 和 ATMEGA16 芯片连接,ATMGA16 芯片直接与驱动电路相连。M 轴承电压,7 和 805,电机电压,选择 12V 电源)电源电压输入端子。L29 8N 可同时驱动两台电机,最大输出电流为 2A,以其性能和价格好,选用 L29 8N 作为电机驱动芯片,L29 8N 芯片如图 2-3 所示,为了达到控制停止电机的目的。ATMEGA16 的两个 PB4 和 PB5 端口直接连接到 L29 8N 的两个启用的 ENA 和 ENB 端子。L29 8N 的四个输出端子直接连接到两个电机以驱动电机。

三、硬件设计

3.1 总体设计

智能车由后轮驱动,后轮由两侧的电机驱动。前两个轮子的速度被制作和停止以控制转向。前轮是万象车轮,起支撑作用。跟踪光电管分别安装在车身的左右两侧。如果左传感器从黑线,主命令中心接收信息左侧晶圆控制轮上的电机停止工作,同时右侧电机继续运行这样使小车左向左行使。当右侧右侧的传感器感受到黑线时,主控制芯片控制和左侧相同原理,这使小车向右行驶就和向左相同。


避障原理与直线相同。小车按寻迹路线行走,3 个超声波传感器检测,检测前方是否有障碍物,当有障碍物,停止,没有障碍物,前进;前方有障碍,左右两边检测,哪边检测距离大,往那边走,按键设置前方障碍的最小距离;在避障模式下,按键设置最小转弯半径,小于转弯半径视为不能转弯,小车原地后退,然后停车由此来避免障碍物做到避障功能。

3.2 驱动电路

H 桥发动机电路集成在 L298 上面 ,因此我们可以借助该集成电路来 驱使发动机,该发动机引擎通常使用 H 桥发动机电路,因此 L298N 能够用于驱动发动机。



图 3.2.1 L298N 引脚图



图 3.2.2 原理图

3.3 主控制电路

这个模块主要针对采集到的信号进行了分析,并给出 PWM 波形来控制电机启动、旋转速度和停下。并重新检测障碍物报警等功能。



图 3.5.1 原理图

四、软件设计

4.1 电机驱动程序

#include "stm32f10x.h"#include "SZ_STM32F103C8_LIB.h"#include "LCD1602.h"#include "sys.h"#include "delay.h"#include "adc.h"#include "ultrasonic.h"u16 count = 0; //定时器计数
u32 juli_up = 200; //最小距离u16 juli_Q = 0;u16 juli_Z = 0;u16 juli_Y = 0;u16 juli = 0; //距离设定u32 temp;
u8 start = 0; //0手动 1自动
//停止void stop(){ GPIO_SetBits(GPIOA,GPIO_Pin_4); GPIO_SetBits(GPIOA,GPIO_Pin_5); GPIO_SetBits(GPIOA,GPIO_Pin_6); GPIO_SetBits(GPIOA,GPIO_Pin_7);}
//前进void qianjin(){ GPIO_SetBits(GPIOA,GPIO_Pin_4); GPIO_ResetBits(GPIOA,GPIO_Pin_5); GPIO_SetBits(GPIOA,GPIO_Pin_6); GPIO_ResetBits(GPIOA,GPIO_Pin_7);}
//后退void houtui(){ GPIO_ResetBits(GPIOA,GPIO_Pin_4); GPIO_SetBits(GPIOA,GPIO_Pin_5); GPIO_ResetBits(GPIOA,GPIO_Pin_6); GPIO_SetBits(GPIOA,GPIO_Pin_7);}
//左转void zuozhuan(){ GPIO_ResetBits(GPIOA,GPIO_Pin_4); GPIO_SetBits(GPIOA,GPIO_Pin_5); GPIO_SetBits(GPIOA,GPIO_Pin_6); GPIO_ResetBits(GPIOA,GPIO_Pin_7);}
//右转void youzhuan(){ GPIO_SetBits(GPIOA,GPIO_Pin_4); GPIO_ResetBits(GPIOA,GPIO_Pin_5); GPIO_ResetBits(GPIOA,GPIO_Pin_6); GPIO_SetBits(GPIOA,GPIO_Pin_7);}
复制代码

4.2 寻迹程序

void TIM3_IRQHandler(void)   //TIM3{  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)   {      TIM_ClearITPendingBit(TIM3, TIM_IT_Update);        if(start==1)      {        count++;        //超声波距离判断 低于最小距离        if(juli<juli_up)        {            stop(); //停止        }        else         {            if((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15)==0)&&(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)==0))            {                if(count%2==0)                  qianjin();//前进                else                  stop(); //停止            }            else if((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15)==1)&&(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)==0))            {                            if(count%2==0)                  zuozhuan();  //左转                else                  stop(); //停止            }            else if((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15)==0)&&(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)==1))            {                          if(count%2==0)                  youzhuan(); //右转                else                  stop(); //停止            }            else            {                  stop(); //停止            }                      }      }  }}

int main(void){ delay_init(); //初始化定时器
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LCD_1602Init(); //初始化lcd1602
GPIO_Configuration(); //GPIO初始化 Ultran_Init(); //超声波初始化 delay_ms(500); TIM3_Int_Init(20,35999); //10ms while (1) { if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0) { while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)==0);//等待按键抬起 set_juli(); //设置距离 } if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0) { while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_2)==0);//等待按键抬起 start = 1; //循迹模式 } if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0) { while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0);//等待按键抬起 start = 2; //行走 } if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0) { while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0);//等待按键抬起 start = 0; } Ultra_Ranging1(&temp); //获取距离 juli_Q = temp; if(start==2) { Ultra_Ranging2(&temp); //获取距离 juli_Z = temp;
Ultra_Ranging3(&temp); //获取距离 juli_Y = temp; } display(); //显示界面
delay_ms(100); }}
复制代码

4.3 避障程序

void TIM3_IRQHandler(void)   //TIM3{  if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)   {      TIM_ClearITPendingBit(TIM3, TIM_IT_Update);        if(start==1)      {        count++;        //超声波距离判断 低于最小距离        if(juli<juli_up)        {            stop(); //停止        }        else         {            if((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15)==0)&&(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)==0))            {                if(count%2==0)                  qianjin();//前进                else                  stop(); //停止            }            else if((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15)==1)&&(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)==0))            {                            if(count%2==0)                  zuozhuan();  //左转                else                  stop(); //停止            }            else if((GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_15)==0)&&(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9)==1))            {                          if(count%2==0)                  youzhuan(); //右转                else                  stop(); //停止            }            else            {                  stop(); //停止            }                      }      }  }}
复制代码


发布于: 刚刚阅读数: 4
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022-01-06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
基于STM32设计避障寻迹小车_三周年连更_DS小龙哥_InfoQ写作社区