找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9335|回复: 0
打印 上一主题 下一主题
收起左侧

智能车双车追逐与超车系统设计报告与STM32程序源码

[复制链接]
跳转到指定楼层
楼主
2018年大学第九届TI
大学生电子设计竞赛设计报告

参赛序号

B-02

参赛题目

双车追逐与超车系统(B题)

参赛队员

*

指导教师

刘*

报告日期



      本系统以设计题目的要求为目的,采用 STM32F103开发板机作为步进电机的控制核心, 用脉冲精确的控制步进电机, 使之能在要求范围内转动相应的角度。 同时控制光电传感器进行赛道数据的采集,进而对步进电机进行相应的控制。




双车追逐与超车系统(B题)
1系统设计
1.1  设计要求
1.1.1 总体要求
1.1.2 基本部分
1.1.3 发挥部分
2系统方案
2.1 驱动电机的论证与选择
2.2 人机交互与输入模块的论证与选择
3系统总体设计
3.1系统硬件的设计
3.1.1系统总体框图
3.1.2 输入模块与电路原理图
3.1.3 输出模块与电路原理图
3.1.4 人机交互模块与电路原理图
3.2系统软件的设计
3.2.1程序功能描述与设计思路
3.2.2程序流程图
附录1:源程序
附录2:参考文献


双车追逐与超车系统B
本科组
1系统设计
1.1  设计要求
1.1.1 总体要求
设计两辆智能小车。甲车车头紧靠起点标志线,乙车车尾紧靠边界,甲、乙两辆小车同时启动,先后通过起点标志线,在行车道内同向而行,实现双车追逐与超车功能,跑道如图1所示。
图1.1  跑道图

1.1.2 基本部分

(1)甲车、乙车分别从起点标志线开始,在行车道各正常行驶一圈(15分)。

(2)甲、乙两辆小车在图1所示位置同时启动,开始双车追逐,在甲车通过超车标志区时视为双车追逐结束。此过程中,两车间距始终小于30cm(20分)。

(3)甲、乙两车在完成基础要求(2)时的行驶时间小于10秒(10分)。

(4)完成基础要求(2)后,乙车通过超车标志线后在超车区内实现超车功能,并先于甲车到达终点标志线,即实现乙车超过甲车,若超车时间小于5秒,得25分。(25分)。


1.1.3 发挥部分

(1)在完成基础要求(4)后,甲,乙两车继续行驶第二圈,要求甲车通过超车标志线后实现超车功能(20分)。

(2)甲,乙两车行驶第二圈总时间不超过10秒(10分)。

2系统方案
本系统主要由输入模块、输出模块、人机交互模块组成,下面分别论证这几个模块的选择。
2.1 驱动电机的论证与选择
方案一:采用直流电机作为系统的主要动力机构,直流电机是日常生活中比较常用 的电机类型,可以采用L298N 芯片对直流电机的控制,但直流电机无法精确控制;本次设计要用到两个电机相互配合来控制小车转弯的角度以及双车追逐之间的距离,要求很高的精度,直流电机较难实现。
方案二:舵机。 舵机体积小, 安装方便,其转动的角度用脉冲来进行控制,能做到精确转动,且转动力矩比同质量的直流电机或步进电机都大,转动的范围有限, 不适合本系统。
方案三:采用步进电机作为系统的主要动力机构,步进电机通过脉冲控制,每次可以走一个很小的角度,这就可以满足本题精确控制小车转弯的角度以及双车追逐之间的距离的要求。

综合以上三种方案,选择方案三。

2.2 人机交互与输入模块的论证与选择
              应题目要求,按键作为人机交互模块,光电传感器对赛道数据进行采集。这两个模块固定。
3系统总体设计3.1系统硬件的设计3.1.1系统总体框图
系统总体框图如图所示
图3.1  系统总体框图
3.1.2 输入模块与电路原理图
              光电传感器作为数据采集端。
图3.2  红外光电传感器实物图
图3.3  红外光电传感器原理图
3.1.3 输出模块与电路原理图
              步进电机空系统的执行端。
图3.4 步进电机实物图
图3.5 步进电机驱动电路图

3.1.4 人机交互模块与电路原理图
              按键KEY用于人机交互。
图3.6 按键电路图
3.2系统软件的设计3.2.1程序功能描述与设计思路

1、程序功能描述

根据题目要求软件部分主要实现按键控制小车按指定距离走完一圈和超车功能。

2、程序设计思路

我们从系统设计出发,根据硬件系统设计,将软件设计分为硬件层、驱动层、应用层。这样设计符合模块化思想,有助于代码调试、阅读、学习。

3.2.2程序流程图

1、主程序流程图

2、转圈与追逐功能流程图

3、超车功能流程图

4、直走子程序流程图

5、转弯子程序流程图
6、超车子程序流程图

附录1源程序
  1. #include "main.h"

  2. /*
  3. * 函数名:main
  4. * 函数功能:功能选择
  5. * 入口参数:void
  6. * 返回参数:0
  7. *
  8. */

  9. int main(void)
  10. {        
  11.         System_Init();
  12.         while(1){
  13.                 delay_ms(10);
  14.                 switch(KEY_UP()){                //判断按键是否松开
  15.                         case KEY0_PRES:                        //KEY0松开
  16.                                 start(20, 50);                //小车起步
  17.                                 start(20, 20);
  18.                                 functionOne();                //功能一
  19.                                 break;
  20.                         case KEY1_PRES:                //KEY1松开
  21.                                 break;
  22.                         case WKUP_PRES:                //WKUP_PRES松开
  23.                                 start(20, 50);        //小车起步
  24.                                 start(20, 20);
  25.                                 functionThree();        //功能三
  26.                                 count = 0;                //重新计数
  27.                                 val = 0;
  28.                                 num = 1;
  29.                                 functionTwo();        //功能二
  30.                                 break;
  31.                 }
  32.         }
  33.   
  34.         return 0;
  35. }

  36. void start(int s, int t){                //小车起步程序
  37.         while(s>0){                //小车走s步
  38.                 delay_ms(t);                        //延时t毫秒
  39.                 motor_start10(3-con1%4);                //左轮反转
  40.                 motor_start11(con2%4);                //右轮正转
  41.                 if(con1 == 600){        //左轮清零
  42.                         con1 = 0;
  43.                 }
  44.                 con1++;
  45.                 if(con2 == 600){        //右轮清零
  46.                         con2 = 0;
  47.                 }
  48.                 con2++;
  49.                 s--;
  50.         }
  51.         delay_ms(2);        //延时
  52. }

  53. void overCar(void){                //超车程序
  54.         int i = 0;
  55.         while(1){                //直走245步
  56.                 delay_ms(5);
  57.                 motor_start10(3-con1%4);  //左轮反转
  58.                 motor_start11(con2%4);                //右轮正转
  59.                 if(con1 == 600){
  60.                         con1 = 0;
  61.                 }
  62.                 con1++;
  63.                 if(con2 == 600){
  64.                         con2 = 0;
  65.                 }
  66.                 con2++;
  67.                 i++;
  68.                 if(i > 245){        
  69.                         i = 0;
  70.                         break;
  71.                 }
  72.         }
  73.         
  74.         trunLeft(20); //左转
  75.         trunRight();        //右转
  76.         
  77.         while(1){                //直走340步
  78.                 delay_ms(3);
  79.                 motor_start10(3-con1%4);
  80.                 motor_start11(con2%4);
  81.                 if(con1 == 600){
  82.                         con1 = 0;
  83.                 }
  84.                 con1++;
  85.                 if(con2 == 600){
  86.                         con2 = 0;
  87.                 }
  88.                 con2++;
  89.                 i++;
  90.                 if(i > 340){
  91.                         i = 0;
  92.                         break;
  93.                 }
  94.         }
  95.         
  96.         trunRight();                //右转
  97.         
  98.         while(1){                //直走30步
  99.                 delay_ms(5);
  100.                 motor_start10(3-con1%4);
  101.                 motor_start11(con2%4);
  102.                 if(con1 == 600){
  103.                         con1 = 0;
  104.                 }
  105.                 con1++;
  106.                 if(con2 == 600){
  107.                         con2 = 0;
  108.                 }
  109.                 con2++;
  110.                 i++;
  111.                 if(i > 30){
  112.                         i = 0;
  113.                         break;
  114.                 }
  115.         }
  116.         
  117.         trunLeft(0);                //左转
  118.         count = 8;                //给标志线计数器重新赋值为8
  119.         val = 8;
  120.         num = 8;
  121. }

  122. void functionThree(void){                //功能三
  123.         int i = 0;
  124.         while(1){               
  125.                 lineRun();                //直线走
  126.                 if(num == 10){                //判断是否到达终点
  127.                         break;
  128.                 }
  129.                 trunLeft(0);        //左转
  130.                 if(num == 8){                //判断是否到达超车区域
  131.                         while(1){                //直线行驶800步
  132.                                 delay_ms(5);               
  133.                                 motor_start10(3-con1%4);
  134.                                 motor_start11(con2%4);
  135.                                 if(con1 == 600){
  136.                                         con1 = 0;
  137.                                 }
  138.                                 con1++;
  139.                                 if(con2 == 600){
  140.                                         con2 = 0;
  141.                                 }
  142.                                 con2++;
  143.                                 i++;
  144.                                 if(i == 800){
  145.                                         i = 0;
  146.                                         break;
  147.                                 }
  148.                         }
  149.                         while(1){                //减速行驶180步
  150.                                 delay_ms(50);
  151.                                 motor_start10(3-con1%4);
  152.                                 motor_start11(con2%4);
  153.                                 if(con1 == 600){
  154.                                         con1 = 0;
  155.                                 }
  156.                                 con1++;
  157.                                 if(con2 == 600){
  158.                                         con2 = 0;
  159.                                 }
  160.                                 con2++;
  161.                                 i++;
  162.                                 if(i == 180){
  163.                                         i = 0;
  164.                                         break;
  165.                                 }
  166.                         }
  167.                 }
  168.         }
  169. }

  170. void functionTwo(void){                //功能二
  171.         while(1){
  172.                 lineRun();                //直走
  173.                 if(num == 10){                //判断是否到达终点
  174.                         break;
  175.                 }
  176.                 trunLeft(0);                //左转
  177.                 if(val == 8){                //判断是否进入超车区
  178.                         overCar();                //超车
  179.                 }
  180.         }
  181. }

  182. void functionOne(void){                //功能一
  183.         while(1){
  184.                 lineRun();                //直线走
  185.                 if(num == 10){                //判断是否到达终点
  186.                         break;
  187.                 }
  188.                 trunLeft(0);                //左转
  189.                
  190.         }
  191. }

  192. void trunRight(void){                //右转程序
  193.         int i = 0;
  194.         while(1){                //先直走230步
  195.                 delay_ms(3);
  196.                 motor_start10(3-con1%4);
  197.                 motor_start11(con2%4);
  198.                 if(con1 == 600){
  199.                         con1 = 0;
  200.                 }
  201.                 con1++;
  202.                 if(con2 == 600){
  203.                         con2 = 0;
  204.                 }
  205.                 con2++;
  206.                 i++;
  207.                 if(i == 230){
  208.                         i = 0;
  209.                         break;
  210.                 }
  211.         }
  212.         
  213.         while(1){                //右轮不转左轮转
  214.                 delay_ms(3);
  215.                 motor_start10(3-con1%4);
  216.                 if(con1 == 600){
  217.                         con1 = 0;
  218.                 }
  219.                 con1++;
  220.                 i++;
  221.                 if(i == C3){
  222.                         i = 0;
  223.                         break;
  224.                 }
  225.         }
  226. }


  227. void trunLeft(int c){  //左转程序
  228.         int i = 0;
  229.         while(1){                //先直走165步
  230.                 delay_ms(5);
  231.                 motor_start10(3-con1%4);
  232.                 motor_start11(con2%4);
  233.                 if(con1 == 600){
  234.                         con1 = 0;
  235.                 }
  236.                 con1++;
  237.                 if(con2 == 600){
  238.                         con2 = 0;
  239.                 }
  240.                 con2++;
  241.                 i++;
  242.                 if(i == 165){
  243.                         i = 0;
  244.                         break;
  245.                 }
  246.         }
  247.         
  248.         while(1){        //左轮不转右轮转
  249.                 delay_ms(3);
  250.                 motor_start11(con2%4);
  251.                 if(con2 == 600){
  252.                         con2 = 0;
  253.                 }
  254.                 con2++;
  255.                 i++;
  256.                 if(i == C3-c){
  257.                         i = 0;
  258.                         break;
  259.                 }
  260.         }
  261. }

  262. void right(void){                //向右调平程序
  263.         while(1){                //左轮转动直到左边光电传感器扫描到标志线
  264.                 delay_ms(5);
  265.                 motor_start10(3-con1%4);  
  266.                 if(con1 == 600){
  267.                         con1 = 0;
  268.                 }
  269.                 con1++;
  270.                 if(val==count){
  271.                                 break;
  272.                 }
  273.         }
  274. }

  275. void left(void){                //向左调平程序
  276.         while(1){                //右轮转动直到右边光电传感器扫描到标志线
  277.                 delay_ms(5);
  278.                 motor_start11(con2%4);        
  279.                 con2++;
  280.                 if(con2 == 600){
  281.                         con2 = 0;
  282.                 }
  283.                
  284.                 if(count==val){
  285.                                 break;
  286.                 }
  287.         }
  288. }

  289. void lineRun(void){                //直线走程序
  290.   int value1 = 0;
  291.         int value2 = 0;
  292.         while(1){
  293.                
  294.                 delay_ms(5);
  295.                 motor_start10(3-con1%4);
  296.                 motor_start11(con2%4);
  297.                 if(num == 1&&con1 == 450){                //确保左右光电传感器计数值在经过第一条标志线后一致
  298.                                 count = num;
  299.                                 val = num;                                
  300.                 }
  301.                 if(con1 == 600){
  302.                         con1 = 0;
  303.                 }
  304.                 con1++;
  305.                 if(con2 == 600){
  306.                         con2 = 0;
  307.                 }
  308.                 con2++;
  309.                 if(num == 10){                //判断是否到达终点
  310.                         break;
  311.                 }
  312.                 //在第2、3、4、9、10标志线处调平
  313.                 if((count-value1==1)&&(count==2||count==3||count==4||count==9||count==10)){
  314.                         right();
  315.                         break;
  316.                 }
  317.                 if((val-value2==1)&&(val==2||val==3||val==4||val==9||val==10)){
  318.                         left();
  319.                         break;
  320.                 }
  321.                 value1 = count;
  322.                 value2 = val;
  323.         }
  324. }

  325. /*
  326. * 函数名:System_Init
  327. * 函数功能:系统硬件层初始化
  328. * 入口参数:无
  329. * 返回参数:无
  330. *
  331. */
  332. void System_Init(void){
  333.         
  334.         Stm32_Clock_Init(9);                                          //初始化系统时钟               
  335.         delay_init(72);                                                                        //初始化延时
  336.         MOTOR_Init();                                                                                //初始化电机接口                                                                          
  337.         uart_init(72,9600);                                                        //初始化串口
  338.         KEY_Init();                                                                                        //初始化按键
  339. //        LED_Init();
  340.          EXTI_Init();                                                                                //初始化中断
  341. }
复制代码

全部资料51hei下载地址(word格式的论文内含清晰图片)
智能小车追逐超车系统.zip (2.86 MB, 下载次数: 33)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表