单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 54|回复: 0
收起左侧

STM32二轮循迹小车程序+实验操作步骤

[复制链接]
日月相皎洁啊 发表于 2019-11-15 10:30 | 显示全部楼层 |阅读模式
此教程针对二轮循迹小车,使用的芯片为STM32F103C8T6
  • 安装keil5,具体的安装方式见文件夹 “keil5安装/” 里《如何安装KEIL5(包含安装芯片包).pdf》,需要用到的安装包(Keil_uVision_MDK522.EXE)
安装好Keil5之后需要使用的破解工具(Keil注册机)
需要扩展的库文件(ARM.CMSIS.3.20.4.pack  Keil.STM32F1xx_DFP.2.1.0.pack)
都已经在文件夹内(官网下载库文件贼慢)
  • 安装好KEIL5之后,打开软件
启动界面
选择菜单栏 Project –> Open Project
在我的这个文件夹里找到 “HELT” 的文件夹,按图中所示路径找到后缀为.uvprojx 的文件打开即可
  •         打开工程之后直接 重新编译
显示没有错误
  • 接着连接 J-LINK 下载器,USB端连接电脑,另一端连接小车
先打开小车电源(即小车上面的几个红灯是亮的),接着在Keil5中点击下载按钮,烧录程序到小车芯片上
烧录结果,如图则证明烧录成功!
  • 拔下下载器,开始调节小车红外感应模块的灵敏度(重要!!)
调节之前,温习一下红外感应循迹原理,网上贴图(懒呀,哈哈)
对于灵敏度的调节,遵循的原则是:
把你要调节的红外感应模块水平对准一条黑线,调节红外感应模块对应的电位器,使得你正在调节的红外模块的指示灯刚好由亮变灭时停止调节。

因为有三个红外感应模块,所以,依次把你想要调节的那个红外感应模块对准黑线而另外两个不要对准黑线,反复调节,使得对准黑线的模块灯灭而另外两个没有检测到黑线的红外模块的灯亮,则证明调节完成哈。
(测试的环境选择明亮的场所,黑线可以用超市里买的电工胶布即可)
图 调节灵敏度
  • 调节完毕,在如下轨道上进行测试,注意在贴轨道时既要有左转弯还要有右转弯,而且要有T字路口(这实验要求真的狗啊,
  • 可能遇到的一个问题:在T字路口不能右转,车很可能会停下来。
解释一下:因为咱们的小车循迹原则是,如果左边的红外感应到有黑线,或者左边和中间的红外模块同时感应到黑线,那么那就会稍稍左转(保证轨道尽量处于中间),即左轮停止而右轮前转。同理,如果是右边的红外模块感应到黑线或者右边和中间的红外感应模块同时感应到黑线,则小车稍稍右转,即右轮停止而左轮前转。如果是只有中间的红外感应模块感应到黑线,那么小车直走,即两个轮子都前转。而当三个红外模块都没有检测到黑线,则小车转圈。如果同时三个检测到黑线,则小车停止,这个条件是为了模拟终点全是一大坨黑块而设计的,但是在T字路口可能出现误判。
针对此问题,我们暂时想到的解决办法是:把两侧的红外感应模块往两边移动,中间的保持不动,使得三个感应模块不在同一条水平线上时,可避免误判的可能(这个不用担心在终点三个红外模块不能同时检测到给黑线的情况,因为终点设计有很大一块黑块,所以完全会使三个红外模块同时检测到黑线而使得小车停止)
同学们也可以依靠上述的原理来验证小车的转向是否正确,让一个红外模块对准黑线,观察轮子转向是否正确,如果反转,可以尝试对调电机的正负极,则可以让他正转。


单片机源程序如下:
  1. #include "stm32f10x.h"

  2. struct motor
  3. {
  4.   enum {STOP, FORWARD, BACKWARD} state;
  5.   int forward_opcode;
  6.   int backward_opcode;
  7. };

  8. static struct motor left_motor, right_motor;

  9. void MotorInit()
  10. {
  11.   RCC->APB2ENR |= 1 << 3;
  12.   GPIOB->CRH &= 0xff0000ff;
  13.   GPIOB->CRH |= 0x00333300; //PB10        左后退 , PB11        左前进, PB12        右前进, PB13  右后退
  14.   GPIOB->BSRR = ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)) << 16;
  15.         
  16.   left_motor.state = STOP;
  17.   left_motor.forward_opcode = 1 << 11;
  18.   left_motor.backward_opcode = 1 << 10;

  19.   right_motor.state = STOP;
  20.   right_motor.forward_opcode = 1 << 12;
  21.   right_motor.backward_opcode = 1 << 13;        
  22. }

  23. //对某电机施加前转驱动电平
  24. static void MotorRotateForward(struct motor *pmotor)
  25. {
  26.         if (pmotor->state != FORWARD)
  27.         {
  28.           GPIOB->BSRR = (pmotor->backward_opcode << 16) | pmotor->forward_opcode;
  29.           pmotor->state = FORWARD;
  30.         }
  31. }

  32. //对某电机施加后转驱动电平
  33. static void MotorRotateBackward(struct motor *pmotor)
  34. {
  35.         if(pmotor->state != BACKWARD)
  36.         {
  37.           GPIOB->BSRR = (pmotor->forward_opcode << 16) | pmotor->backward_opcode;
  38.           pmotor->state = BACKWARD;
  39.         }
  40. }

  41. //对某电机停止驱动电平
  42. static void MotorStop(struct motor *pmotor)
  43. {
  44.         if (pmotor->state != STOP)
  45.         {
  46.           GPIOB->BSRR = (pmotor->forward_opcode | pmotor->backward_opcode) << 16;
  47.           pmotor->state = STOP;
  48.         }
  49. }

  50. //电机控制函数
  51. //输入参数:电机标识字符'r'或’l'(右或左)   操作代码字符'f'、'b'或's'(正转、反转或静止)
  52. void MotorControl(char motor, char op_cmd)
  53. {
  54.   struct motor *pmotor;
  55.   
  56.   if (motor == 'r')
  57.     pmotor = &right_motor;
  58.   else if (motor == 'l')
  59.     pmotor = &left_motor;
  60.   else
  61.     return;
  62.   if (op_cmd == 'f')
  63.     MotorRotateForward(pmotor);
  64.   if (op_cmd == 'b')
  65.     MotorRotateBackward(pmotor);
  66.   if (op_cmd == 's')
  67.     MotorStop(pmotor);
  68. }
复制代码

所有资料51hei提供下载:
二轮循迹小车.7z (6.25 MB, 下载次数: 0)

评分

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

查看全部评分

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

本版积分规则

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

Powered by 单片机教程网

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