STM32/STM8技术论坛
直播中

电子开发圈

6年用户 190经验值
擅长:DIY、Arduino、C51、STM32、FPGA
私信 关注
[经验]

循迹避障智能车系统设计(全套论文+程序)

本系统的功能为通过传感器对小车行驶的周边环境进行探测,遇到障碍物要进行有效的避障处理,并进行相应的危险状况播报,同时还可以根据预定的进行寻迹行驶等。
系统总体结构框图如下:

1.1.png


超声波模块采集小车前面障碍物的距离信息;红外传感器采集小车前部下方预设轨迹的变化信息。STM32主控芯片采集红外传感器及超声波传感器输出的信号,对它们的信息进行融合处理,经过数据分析之后发出相应控制指令传给L298N驱动模块及语音模块,对电机作出相应的驱动处理,对危险信息进行播报,实现对小车行驶的自动控制。

1.电机驱动模块电路设计

本次设计中的电机驱动芯片选用了L298N,它是一款接受高电压的电机驱动器,直流电机和步进电机都可以驱动。一片驱动芯片可同时控制两个直流减速电机做不同动作,在6V到46V的电压范围内,提供2安培的电流,并且具有过热自断和反馈检测功能。L298N可对电机进行直接控制,通过主控芯片的I/O输入对其控制电平进行设定,就可为电机进行正转反转驱动,操作简单、稳定性好,可以满足直流电机的大电流驱动条件。

1.2.PNG


1.3.PNG

1.4.PNG

1.5.PNG


2.超声波模块电路设计

根据智能小车控制器的避障需求,环境探测传感器应具有精确的探测功能,以获得周边环境的完整信息,同时还要为小车运动提供实时的信息。具有处理速度快,低功耗,容易使用等优点,且不受到外界环境的影响。但也有一些局限:检测角度较小,方向性较差,所以单个超声波模块的准确性并不理想,测量范围存在盲点。在实际开发应用中,会采取一些措施进行补偿处理,然后利用信息汇总技术对准确度进行提高。

1.6.PNG


超声波距离测量原理非常简单,一般采用回波时间法,即检测超声波往返所测距离的时间,当发射器发出一个短脉冲时,定时器启动;当接收器接收到返回脉冲时,定时器立即停止。此时记录的时间值为D = CT / 2,其中D为超声波传感器与测量对象之间的距离,C为介质中声波的传播速度(C = 331.4+t273 / 1m / s,t是摄氏温度),T是超声波发射回波的时间间隔。理论上,超声波在正常空气中传播速度随着介质温度的升高而有所加快,温度提高了一度,速度提高0.6 m/s左右。原理结构如图3.12所示。

1.7.PNG



超声波传感器主要由三部分组成:控制部分,总线部分,超声波发射接收部分。主控芯片通过I/O口发送信号,通过总线发送到两个发生电路中,控制着两个超声波的发射,然后再由两个信号接收电路对接收超声波信号进行放大,最后通过总线传送到主控芯片的输入端口,然后根据发射接收时间差T,计算出传感器与障碍物之间的距离,最后根据距离对小车的行驶安全性进行判断,并做出相应动作。

3.语音模块电路设计

本设计中采用的是ISD1820语音模块,它是美国ISD公司于2001年推出的一款单芯片8至20秒单段语音录放电路模块,基本结构与之前的ISD1110和ISD1420原理几乎相同,都是采用了CMOS技术,配置振荡器、滤波器、增益控制、话筒前置放大、扬声驱动及FLASH阵列。

1.8.PNG

4.红外模块电路设计

本次选用的红外对管模块适应环境光的能力很强,具有一对发射接收管,发射管发射一定频率的红外线,当检测到黑线时,不能反射回接收管,比较电路处理完后,绿色灯亮,信号输出接口不能输出数字信号。 可以通过电位器的旋钮调节灵敏度,有效检测距离范围为2到30厘米,正常工作电压为3.3到5V。具有抗干扰,易安装使用等特点,广泛应用于自动避障循迹。

1.9.PNG


红外模块电路原理如图所示,图中10K限流电阻,不同性能的限流电阻决定了红外发射功率,限流电阻越小,发射功率越大。当光反射回来三极管导通,LM393两个输入端,同相输入端用“+”表示,反相输入端用“-”表示。用于比较两个电压,任一个输入端加一个固定电压做参考电压,即阈值电平。另一端加上比较电压。当反相输入电压低于同相输入电压时,输出截止。否则输出端饱和,输出接地。只要LM393的两个输入电压差大于10mv,就可以确保输出从现状态可靠转换到另一状态。使用比较器就可以不用AD转换电路,经过LM393后在主控芯片控制端口产生高电平,从而完成检测的目的。模块的灵敏度可以通过变阻器VR1进行调整。

1.10.PNG



5.显示模块电路设计

LCD1602模块的命令操作端有RS、RW和EN,单片机的P2^5、P2^6、P2^7脚分别与之相连。数据端口DB0~DB7分别接在单片机的P0^0~P0^7。为了保持LCD1602液晶具有较高的亮度,一般电路设计中都会将VL端串联一个2K的电阻接地。

1.11.PNG



1.12.PNG


6.主程序设计

开始先是对单片机的初始化,其中包括对外部中断初始化和液晶的初始化。然后调用超声波测距子程序,判断前方300mm处是否存在障碍物,如果存在进行避障处理,如果不存在则进行红外对管检测,并做出相应动作。

1.13.PNG


7.电机驱动程序设计

开始通过超声波模块和红外模块的检测,判断中断请求,如果没有中断请求则保持原状态,如果有中断请求则调控PWM进行避障或者循迹运动。通过P1^3电平检测,把它赋给temp,根据P1低四位电平,给出相应的驱动电平送到L298N,从而控制小车的直走停止,左右转等动作。

1.14.PNG


8.超声波避障程序设计

超声波避障程序的设计思想主要是依据超声波测距原理。首先,单片机给超声波模块Trig端发送一个高电平且持续20us,再给Trig端发送一个低电平,启动超声波模块,随即超声波模块会发送8个40KHZ的方波,等待信号返回,如果有信号返回则超声波模块的Echo端输出一个高电平,接收高电平的时间就是超声波从发射到接收的时间,测试距离就等于(接收高电平时间*340)/ 2,单位为m。计算出障碍物和智能小车的距离,取前方多个方向的值,然后进行多次采样,以此减小数据误差,最后进行数据处理,通过软件算法判断最优路线,智能小车向目标方向行驶。

1.15.PNG

1.16.PNG


9.语音模块程序设计

它的工作状态和检测障碍存在信号是同步的,当检测到前方存在障碍物,语音模块就会进行障碍信息播报。

1.17.PNG


10.红外循迹程序设计

首先对小车状态进行检测,如在轨迹上,则调用直走子程序,即两电机都正转;如偏向轨迹左边,则调用右转子程序,即左电机正转右电机反转;如偏向轨迹右边,调用左转子程序,左电机反转右电机正转;如到轨迹终点,则调用停止子程序,即两电机都不转。

1.18.PNG


11.显示模块程序设计

LCD1602液晶显示程序的设计流程为先调用定义字符库,然后将DDRAM地址设置在第一行显示位置上,再根据系统数据对显示数据首地址及程序循环量进行设置,在循环显示程序中,要不断地提取相关字符代码直至第一行数据显示任务完成,同理,第二行数据显示任务与第一行完成过程是一样的,当两行数据全部显示完毕即可结束显示子程序。

1.19.PNG



主程序核心部分如下:

int main()
{
  Sys_Delay_Init(72);               
  Car_GPIO_Config();
  Xunji_GPIO_Config();
  Chaoshengbo_Init();
  timer_Init();
    TIM3_PWM_Init(2000);
  while(1)
  {
        TIM3_PWMoutPA6_Config(1500);
        TIM3_PWMoutPA7_Config(1500);
        Chaoshengbo_ReadJuli();
      if( juli>300)
         { Ctrl();}
        else
         { Stop();}
    }
   }

电机PWM占空比设置核心程序如下:

//TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
//TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
//TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
//TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
void TIM3_PWMoutPA6_Config(u16 CCR1_Val)
{
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;        
//配置为PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;      
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
   TIM_OC1Init(TIM3, &TIM_OCInitStructure);     
  //使能通道1
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);   
  // 使能TIM3重载寄存器ARR
}
void TIM3_PWMoutPA7_Config(u16 CCR2_Val)
{
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    /* PWM1 Mode configuration: Channel2 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;        
   //配置为PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;      
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  
       //当定时器计数值小于CCR1_Val时为高电平
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);      
  //使能通道2
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);            
       // 使能TIM3重载寄存器ARR
}
void TIM3_PWMoutPB0_Config(    u16 CCR3_Val)
{
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    /* PWM1 Mode configuration: Channel2 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;        
//配置为PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;      
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  
//当定时器计数值小于CCR1_Val时为高电平
  TIM_OC3Init(TIM3, &TIM_OCInitStructure);     
//使能通道3
  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);            
// 使能TIM3重载寄存器ARR
}
void TIM3_PWMoutPB1_Config(u16 CCR4_Val)
{
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    /* PWM1 Mode configuration: Channel2 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//配置为PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;      
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  
//当定时器计数值小于CCR1_Val时为高电平
  TIM_OC4Init(TIM3, &TIM_OCInitStructure);      
//使能通道4
  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM3, ENABLE);   
// 使能TIM3重载寄存器ARR
}

超声波读距核心程序如下:

void Chaoshengbo_ReadJuli()
{
  GPIO_SetBits(TRIG_PORT,TRIG_PIN);
//送>10US的高电平RIG_PORT,TRIG_PIN这两个在define中有
  Delay_1us(20);               
  //延时20US
  GPIO_ResetBits(TRIG_PORT,TRIG_PIN);
     while(!GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN));                         //等待高电平
  TIM_Cmd(TIM2,ENABLE);                                                     //开启时钟
  while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN));                             //等待低电平
  TIM_Cmd(TIM2, DISABLE);                                                     //定时器2失能
  juli=(TIM_GetCounter(TIM2)*5*34/200);                                 
       //计算距离 juli=TIME/(计数频率)*(344/2)m
    TIM_SetCounter(TIM2,0);
}

循迹功能核心程序如下:

void Ctrl()
{
u8 Temp=(u8)(GPIO_ReadInputData(GPIOB)&0xf0);
switch (Temp)
{
    case 0x00:Go();
        break;
    case 0x10:Right();
        break;
    case 0x20:Right();
        break;
    case 0x30:Right();
        break;
    case 0xE0:Right();
        break;
    case 0xD0:Right();
        break;
    case 0x40:Left();
        break;
    case 0x80:Left();
        break;
    case 0xC0:Left();
        break;
        case 0x70:Left();
        break;
        case 0xB0:Left();
        break;
    case 0xF0:Stop();
        break;
    default:Back();
        break;
}
Delay_1ms(100);
}








回帖(3)

张伟

2018-12-5 18:34:40
参考学习一下
举报

李英

2018-12-5 18:35:50
有没有图片什么的
举报

刘琦

2019-4-9 21:41:20
学习一下   我用51在做

举报

更多回帖

发帖
×
20
完善资料,
赚取积分