嘉立创产业服务站群
发作品签到
专业版

梁山派智能小车设计

工程标签

1.1k
0
0
0

简介

基于梁山派开发板设计的智能小车

简介:基于梁山派开发板设计的智能小车

开源协议

Public Domain

创建时间:2023-08-18 09:47:14更新时间:2024-02-03 14:55:40

描述

1、项目介绍

根据官方教程,学习并复刻基于立创·梁山派的智能小车。

题目分析

1.1 .小车功能介绍

梁山派智能小车前方搭载了两个LED照明灯,左右各一个,可用于模拟行车过车中的车灯状态;
梁山派智能小车有2个独立按键,分别是KEYS与KEYM,可用于启动和运动模式切换;
梁山派智能小车搭载了一个蜂鸣器,可用于遇到障碍物时发出警报,也可使用定时器改变其输出频率让其播放音乐;
梁山派智能小车配置了四个电机驱动和四个N20电机,可实现PWM输出与调速功能;
梁山派智能小车搭载了五路红外循迹,可用于循黑线行驶,学习比较器电路的使用,实现循迹功能;
梁山派智能小车配备了HCSR04超声波模块接口电路,可通过学习模块原理以及底层驱动代码,实现超声波避障功能;
梁山派智能小车利用开发板上的ADC功能检测智能小车电量,方便我们及时充电;
梁山派智能小车提供了HC-05蓝牙模块接口电路,可配合手机蓝牙APP实现无线遥控小车的功能;
梁山派智能小车提供了一个摄像头模块接口电路,可用于学习摄像头识别相关知识;
梁山派智能小车提供了一个2.4G无线模块接口电路,可配合遥控器实现智能小车的控制;

1.2 .小车应用场景

该教程适用于电子爱好者以及新手小白入门基础项目的学习;
该教程适用于嵌入式课程教学,以智能小车结合立创·梁山派开发板贯穿嵌入式课程教学;
该教程适用于高校课程设计以及毕设参考案例,让学生结合立创·梁山派核心板根据课程设计要求完成特定功能的智能小车项目;
该教程适用于学生以及相关人员入门学习相关的智能车比赛;

2、总体设计方案

  梁山派智能小车总体设计方案系统框架图如图2-1所示,供电电路采用两节锂电池7.4V给本系统供电,通过降压芯片降到5V给单片机系统供电,立创·梁山派核心板与智能小车扩展板上的LED车灯、按键电路、避障电路、循迹电路、ADC电压采集电路、蓝牙遥控电路(无线遥控功能)、蜂鸣器、以及电机驱动电路进行连接。
                                                                           图2-1 总体设计系统框架图

3、电路设计

3.1 电源输入电路

3.1.1电源设计需求

    我们对智能小车系统的供电电路进行分析,通过查阅芯片手册以及立创·梁山派核心板的原理图我们得知,电机驱动芯片RZ7899的最大供电电压不超过25V,立创·梁山派核心板供电是3.3V(兼容5V),超声波模块是5V供电,其余外设模块均是3.3V。根据这个需求我们就可以开始对电源进行选型了,这里我选用了一款7.4V可充电锂电池,大家可以不必跟我一样,根据需求选用即可。

3.1.2智能小车电源原理图

                                                                                                  图3-1 电源电路原理图

3.1.3电源电路设计分析

    电源的输入接口P3是一个电池座,通过电池座接入2节3.7V的锂电池后给小车供电。电源进来后经过一个HE6250MPR降压芯片,该降压芯片的最大输入电压是15V,可固定输出5V电压给单片机和外围器件提供供电,电机驱动芯片则直接由7.4V电池供电。其中,D1是一个肖特基二极管,型号是SS43,作用是防止电源输入端正负极接反,起到一个保护作用。LED1是电源工作指示灯,当电源开关SW1打开时,系统开启供电,LED1会被点亮。C1和C2是10uF的电容,主要作用是上电瞬间可能电流会比较大,使用电容可以起到一个缓冲作用。

3.2 单片机最小系统电路

    毋庸置疑,我们使用的是立创·梁山派核心板作为我们的最小系统板,立创·梁山派核心板采用的主控芯片是GD32F470,具备了超高的计算性能,处理器最高主频可达200MHz,并提供了完整的DSP指令集、并行计算能力和专用浮点运算单元(FPU) 来满足高级计算需求。具体关于立创·梁山派核心板的相关资料和内容这里不作过多的介绍,大家可以去立创开发板官方网站进行了解。

3.3 电机驱动电路

3.3.1电机驱动电路原理图

                                                                                                                图3-2 电机驱动电路原理图

3.3.2电机驱动电路设计分析

    首先我们都知道单片机本身的IO口电流是非常有限的,如果直接将电机接在单片机IO口,会导致无法正常驱动电机转动,所以我们必须使用电机驱动芯片来驱动我们的电机组,这里我选用RZ7899电机驱动芯片。RZ7899是一款DC双向马达驱动电路,适用于自动阀门电机驱动、电磁门锁驱动等,该电路具有良好的抗干扰性,微小的待机电流、低的输出内阻,同 时它还具有内置二极管能释放感性负载的反向冲击电流。
    它通过两个逻辑输入端子BI和FI来控制电机的前进、后退及制动。我们将BI和FI与单片机IO进行连接,通过改变单片机I/O口电平从而改变芯片控制端输出引脚的电平,就可以对电机进行正反转,停止以及制动控制,控制原理非常简单,运用起来非常方便,亦能满足直流电机的大电流要求。
    在进行代码调试时我们可以参照以下的引脚功能表和输入输出真值表进行调试。我们只要将BI和FI引脚连接到单片机的定时器通道引脚,就可以结合单片机的定时器PWM输出功能控制电机转速,从而改变我们智能小车行驶的速度。
芯片特点
  • 微小的待机电流,小于 2uA;工作电压范围宽 3.0V~25V。
  • 有紧急停止功能 ; 有过热保护功能 。
  •                                                                            图3-4 超声波模块接口图

    3.5.2避障电路设计分析

        超声波测距原理是在超声波发射装置发出超声波,在发射超声波的同时开始计时,超声波在空气中传播,在传播的时刻碰到障碍物,就会返回一个信号给超声波接收器,超声波接收器接收到信号后立即停止计时,这时候会有一个时间t,而超声波在空气中传播的速度为340m/s,通过公式s=340 x t / 200,即可计算出待测距离是多少。
    HC-SR04超声波测距模块工作原理
    • 工作电压:DC 5V;
    • 采用I/O口触发方式测距,通过单片机发出至少10us的高电平信号到超声波模块的Trig引脚,用于触发超声波模块工作;
    • 模块的发射探头会自动发送8个40KHz的方波信号,自动检测是否有信号返回;
    • 如果有信号返回,通过Echo引脚连接单片机的I/O口输出高电平,高电平持续时间就是超声波从发射到返回的时间;
    • 根据声音在空气中的传播速度为340米/秒,即可计算出所测的距离;

     

    • 有过流嵌流及短路保护功能 ; 封装外形为: SOP8。

      3.4 循迹电路

      3.4.1循迹电路原理图

                                                                                                                   图3-3 循迹电路原理图

      3.4.2循迹电路设计分析

          循迹电路的设计是利用了红外光遇到不同颜色地面反射程度不同的原理。循迹电路采用LM393电压比较器与ITR9909红外对管进行设计,其中ITR9909的内部集成了红外发射管和接红外收管。循迹的工作原理是将电压比较器的1引脚连接到单片机引脚上,IO配置为输入模式,当电压比较器的1引脚输出高电平时,表示红外光被吸收,检测到黑线,LED6指示灯亮起,单片机IO读取到高电平。
      红外循迹的原理:利用红外光在不同颜色的反射情况进行识别
      • 检测黑线的原理是红外发射管发射光线到地面,当红外光遇到白色地面则被反射,红外接收管接收到反射光,经过电压比较器后输出低电平。
      • 检测黑线的原理是红外发射管发射光线到地面,当红外光遇到黑色地面则被吸收,红外接收管未接收到反射光,经过电压比较器后输出高电平。

      3.5 避障电路

      3.5.1避障电路原理图

          避障电路使用的是超声波HC-SR04模块,该模块的类型可自行选取购买,以下是实物图。
            
      下面是智能小车扩展板上的超声波模块接口。

      图3-4 超声波模块接口图

3.5.2避障电路设计分析

    超声波测距原理是在超声波发射装置发出超声波,在发射超声波的同时开始计时,超声波在空气中传播,在传播的时刻碰到障碍物,就会返回一个信号给超声波接收器,超声波接收器接收到信号后立即停止计时,这时候会有一个时间t,而超声波在空气中传播的速度为340m/s,通过公式s=340 x t / 200,即可计算出待测距离是多少。
HC-SR04超声波测距模块工作原理
  • 工作电压:DC 5V;
  • 采用I/O口触发方式测距,通过单片机发出至少10us的高电平信号到超声波模块的Trig引脚,用于触发超声波模块工作;
  • 模块的发射探头会自动发送8个40KHz的方波信号,自动检测是否有信号返回;
  • 如果有信号返回,通过Echo引脚连接单片机的I/O口输出高电平,高电平持续时间就是超声波从发射到返回的时间;
  • 根据声音在空气中的传播速度为340米/秒,即可计算出所测的距离;
图3-5 超声波HC-SR04模块工作时序图

3.6 其他电路

3.6.1LED车灯与按键电路

(1)LED灯的一端连接到单片机IO口,通过单片机IO的高低电平控制LED灯,这里设计了2种驱动的方式,LED车灯的电路是低电平点亮,按键指示灯的电路是高电平点亮,其中电阻的大小可以自己结合灯所需的亮度以及欧姆定律计算。比如这里按键指示灯不需要太亮则电阻为1KΩ大一点,LED车灯需要亮一些则电阻为100Ω小一点。
(2)这里独立按键的电路设计原理是将按键一端连接到单片机IO口,另一端接地,当按键按下时,读取到低电平;按键松开时,读取到高电平。注意这里IO口配置时需要将其配置为上拉输入。当然你也可以加一个上拉电阻将IO口的电平拉高,这样就不需要配置为上拉输入了。
                                                                                        图3-6 LED灯电路原理图

3.6.2蜂鸣器与ADC电压采集电路

(1)蜂鸣器电路:这里采用的蜂鸣器是有源蜂鸣器,有源蜂鸣器内部自带震荡源,只要一通电就会发出鸣叫。这里设计的电路原理是采用了一个PNP型的三极管充当开关的作用,通过调整单片机IO口的高低电平从而达到控制蜂鸣器的效果。之所以采用三极管是因为我们都知道单片机的电流驱动能力是比较小的,直接驱动器件无法正常工作,所以采用三极管的发射极引导电流进入集电极,而不是将单片机IO口直接加到蜂鸣器上。
  • 当IO口输出高电平时,发射极电压没有远大于基极电压,三极管没有导通,处于截止状态,蜂鸣器没有发出声音;
  • 当IO口输出低电平时,发射极电压远大于基极电压,三极管导通,电流从发射极流入集电极,蜂鸣器发出鸣叫声。
                                             
                                                           图3-7 蜂鸣器电路原理图
(2)ADC电压采集电路:首先我们在使用ADC之前,需要知道它的位数即精度。通过数据手册可以查询到我们的ADC是12位的,通过计算我们知道精度为2^12-1等于4095。代表ADC可以表示的精度范围为0~4095。
                      图3-8 ADC电压采集电路原理图

4、原理图以及PCB设计

4.1.1 整体原理图设计

                                                                              图4-1 整体原理图

4.1.2原理图设计注意事项

(1)在选择器件时优先选择基础库以及库存较多的器件;
(2)不同器件的发货仓库尽量保持一致;
(3)不同封装的器件其大小不同,建议新手或者焊接技术较为薄弱的选择直插式封装或者0805封装,当然你也可以直接采用SMT贴片的形式;
(4)器件的类型尽可能减少,比如800Ω的电阻和1000Ω的电阻在可以相互替代不影响电路的情况下,合并选择其中一种即可;
(5)原理图设计完要对原理图进行整理,每一个模块都使用一个方格框起来,这样会使原理图的整体结构比较清晰,方便阅读;

4.2 PCB设计

4.2.1 PCB设计

 
图4-2-1 PCB图

4.2.2小车PCB外形设计

图4-2-2 小车3D图

4.2.3 PCB设计注意事项

(1)电源及信号走线按照信号电流流向,严格按照原理图设计图进行布局设计,即使它们都连接上去了,没有报错,但也要考虑先后顺序,先经过A再到B,最后到C,不能直接从A到C到B,这点在初学的时候尤其重要。
(2)布线时要避免走直角,一般取 45 度走向或圆弧形。在高频电路中,拐弯时不能取直角或锐角,以防止高频信号在导线拐弯时发生信号反射现象。
(3)电源线的线宽要比信号线宽,GND一般采用铺铜的方式。
(4)通常情况下,导线的宽度一般不低于 10mil单位,一般电源线设置为25mil以上宽度。

5、软件设计

5.0 代码规范

    你是否遇到自己写的代码间隔很久之后再来阅读时感觉有点读不太懂甚至是忘记当时的编程逻辑?当你的代码发给其他人阅读时经常被吐槽?变量命名直接a,b,c,再来看时直接蒙圈?
    相信大家多多少少都会犯以上的一些错误,由此可见,代码规范是软件设计的一个重要环节。当你养成一个良好的代码编程习惯时你就可以避免以上的错误,写出像诗句一般的代码,让人阅读起来非常舒服移易懂。下面我将讲述一些代码规范的事项,大家可参照学习养成良好的代码规范。
  • 模块化编程:将各个模块分开成一个个独立的.c和.h文件,这样可以快速移植代码。
  • 适当添加注释:在一些头文件以及函数,变量,控制逻辑处的代码进行必要的一些注释说明。
  • 变量以及函数命名规范:变量和函数的命名尽量做到见名知意。
  • 代码排版格式尽量规范:在需要缩进的地方要缩进,在需要括号的地方尽量添加括号。

    5.1 部分代码

    5.1.1循迹代码

    • track.h
    • 1)track.h头文件主要存放一些需要引用的头文件,以及宏定义,函数声明。
    • 2)为了避免头文件重复定义,使用了条件编译的方式:#ifndef xx:如果没有定义xx;#define xx:则定义xx;#endif:结束

    #ifndef _TRACK_H #define _TRACK_H #include "gd32f4xx.h" #include "systick.h" #define XJ01_RCU RCU_GPIOA // GPIOA的时钟 #define PORT_XJ01 GPIOA // GPIOA的端口 #define XJ01_PIN GPIO_PIN_15 // GPIOA的引脚 #define XJ02_RCU RCU_GPIOC // GPIOC的时钟 #define PORT_XJ02 GPIOC // GPIOC的端口 #define XJ02_PIN GPIO_PIN_10 // GPIOC的引脚 #define XJ03_RCU RCU_GPIOC // GPIOC的时钟 #define PORT_XJ03 GPIOC // GPIOC的端口 #define XJ03_PIN GPIO_PIN_12 // GPIOC的引脚 #define XJ04_RCU RCU_GPIOB // GPIOB的时钟 #define PORT_XJ04 GPIOB // GPIOB的端口 #define XJ04_PIN GPIO_PIN_13 // GPIOB的引脚 #define XJ05_RCU RCU_GPIOB // GPIOB的时钟 #define PORT_XJ05 GPIOB // GPIOB的端口 #define XJ05_PIN GPIO_PIN_15 // GPIOB的引脚 #define No_Black_Line_Found 0 //没有检查到黑线 #define Black_Line_Found 1 //检查到黑线 void track_gpio_config(void); // 循迹gpio引脚配置 void Black_Line_Detection(void); // 黑线检测函数 #endif /* TRACK_H */
     
    • track.c
      #include "track.h" FlagStatus XJ01 = RESET; FlagStatus XJ02 = RESET; FlagStatus XJ03 = RESET; FlagStatus XJ04 = RESET; FlagStatus XJ05 = RESET; /******* 函数名称 : track_gpio_config 功 能 : 循迹gpio引脚配置 参 数 : 无 返 回 值 : 无 *******/ void track_gpio_config(void) { /* 使能时钟 / rcu_periph_clock_enable(XJ01_RCU); / 配置为输入模式 上拉模式 / gpio_mode_set(PORT_XJ01,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,XJ01_PIN); / 使能时钟 / rcu_periph_clock_enable(XJ02_RCU); / 配置为输入模式 上拉模式 / gpio_mode_set(PORT_XJ02,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,XJ02_PIN); / 使能时钟 / rcu_periph_clock_enable(XJ03_RCU); / 配置为输入模式 上拉模式 / gpio_mode_set(PORT_XJ03,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,XJ03_PIN); / 使能时钟 / rcu_periph_clock_enable(XJ04_RCU); / 配置为输入模式 上拉模式 / gpio_mode_set(PORT_XJ04,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,XJ04_PIN); / 使能时钟 / rcu_periph_clock_enable(XJ05_RCU); / 配置为输入模式 上拉模式 */ gpio_mode_set(PORT_XJ05,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,XJ05_PIN); } /******* 函数名称 : Black_Line_Detection 功 能 : 黑线检测函数 参 数 : 无 返 回 值 : 无 *******/ void Black_Line_Detection(void) { XJ01 = gpio_input_bit_get(PORT_XJ01,XJ01_PIN); XJ02 = gpio_input_bit_get(PORT_XJ02,XJ02_PIN); XJ03 = gpio_input_bit_get(PORT_XJ03,XJ03_PIN); XJ04 = gpio_input_bit_get(PORT_XJ04,XJ04_PIN); XJ05 = gpio_input_bit_get(PORT_XJ05,XJ05_PIN); }
    • main.c
      #include "main.h" #include "stdlib.h" #include "string.h" #include "bsp_pwm.h" #include "motor.h" #include "track.h" #include "bsp_led.h" #include "bsp_key.h" #include "bsp_beep.h" uint16_t No_Black_Line_TimeCount = 0 ; // 没有发现黑线时间 uint8_t LongTime_No_Black_Line_Flag = 0 ; // 长时间没发现黑线标志位 extern FlagStatus XJ01; extern FlagStatus XJ02; extern FlagStatus XJ03; extern FlagStatus XJ04; extern FlagStatus XJ05; /******* 函数名称 : main 功 能 : 主函数 参 数 : 无 返 回 值 : 无 ********/ int main(void) { nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组 systick_config(); // 滴答定时器初始化 pwm1_config(200,100); // 定时器1 PWM配置 PWM输出频率10KHZ pwm2_config(200,100); // 定时器2 PWM配置 PWM输出频率10KHZ 速度调节0-100 motor_gpio_config(); // 电机驱动引脚初始化 track_gpio_config(); // 循迹gpio引脚配置 beep_gpio_config(); led_gpio_config(); key_gpio_config(); //熄火停止 car_stop(Flameout_Stop); //关闭车灯和蜂鸣器 beep_off(); led_l_off(); led_r_off(); LEDS=0; LEDM=0; while(1){ Black_Line_Detection();//黑线检测函数 if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//3中间检测到黑线00100 { car_front(87); //前进 } if(XJ01==No_Black_Line_Found && XJ02==Black_Line_Found && XJ03==Black_Line_Found && XJ04==Black_Line_Found && XJ05==No_Black_Line_Found)//2 3 4中间检测到黑线00100 { car_front(87); //前进 } if(XJ01==No_Black_Line_Found && XJ02==Black_Line_Found && XJ03==Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//2 3检测到黑线(右偏小)01100 { motor_LQ_front(40); motor_LH_front(40); motor_RQ_front(87); motor_RH_front(87); } if(XJ01==No_Black_Line_Found && XJ02==Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//2检测到黑线(右偏大)01000 { motor_LQ_front(30); motor_LH_front(30); motor_RQ_front(87); motor_RH_front(87); } if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==Black_Line_Found && XJ04==Black_Line_Found && XJ05==No_Black_Line_Found)//4 3检测到黑线(左偏小)00110 { motor_LQ_front(87); motor_LH_front(87); motor_RQ_front(40); motor_RH_front(40); } if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==Black_Line_Found && XJ05==No_Black_Line_Found)//4检测到黑线(左偏大) { motor_LQ_front(87); motor_LH_front(87); motor_RQ_front(30); motor_RH_front(30); } if(XJ01==Black_Line_Found && XJ02==Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//1 2检测到黑线(左转) { motor_LQ_back(55); motor_LH_back(55); motor_RQ_front(87); motor_RH_front(87); } if(XJ01==Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//1 检测到黑线(左转) { motor_LQ_back(45); motor_LH_back(45); motor_RQ_front(87); motor_RH_front(87); } if(XJ01==Black_Line_Found && XJ02==Black_Line_Found && XJ03==Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//1 2 3检测到黑线(左转) { motor_LQ_back(35); motor_LH_back(35); motor_RQ_front(87); motor_RH_front(87); } if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==Black_Line_Found && XJ05==Black_Line_Found)//4 5检测到黑线(右转) { motor_LQ_front(87); motor_LH_front(87); motor_RQ_back(55); motor_RH_back(55); } if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==Black_Line_Found)//5 检测到黑线(右转) { motor_LQ_front(87); motor_LH_front(87); motor_RQ_back(45); motor_RH_back(45); } if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==Black_Line_Found && XJ04==Black_Line_Found && XJ05==Black_Line_Found)//3 4 5检测到黑线(右转) { motor_LQ_front(87); motor_LH_front(87); motor_RQ_back(35); motor_RH_back(35); } if(XJ01==Black_Line_Found && XJ02==Black_Line_Found && XJ03==Black_Line_Found && XJ04==Black_Line_Found && XJ05==Black_Line_Found) { car_stop(Brake_Stop);//刹车停止 delay_1ms(4000); car_front(87); //前进 delay_1ms(200); } if(XJ01==Black_Line_Found || XJ02==Black_Line_Found || XJ03==Black_Line_Found || XJ04==Black_Line_Found || XJ05==Black_Line_Found) { No_Black_Line_TimeCount=0; LongTime_No_Black_Line_Flag=0; } if(XJ01==No_Black_Line_Found && XJ02==No_Black_Line_Found && XJ03==No_Black_Line_Found && XJ04==No_Black_Line_Found && XJ05==No_Black_Line_Found)//未检测到黑线(停止) { if(LongTime_No_Black_Line_Flag == 1)//长时间 car_stop(Brake_Stop);//刹车停止 else car_front(87); //前进 } } }

     

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
fdf191e64780baf707aee550ba1fb427.mp4
7
2
BOM_Board1_PCB1_2024-02-02.xlsx
6
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1)
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航