HNU-嵌入式系统-实验一

工程文件自取(点击跳转)

一、实验目标

  1. 学习软件设计的层次化抽象方法并实践;
  2. 实验具体目标:以简单“无人驾驶汽车”应用场景为例,设计具有同时控制三个步进功能的程序模块(分别对应“转向”、“刹车”、“油门”控制),该模块能提供适当的 API 函数(一个或多个),方便应用层程序调用编写控制电机程序;
  3. 获取通过查阅手册解决实际问题的能力。

二、实验内容

  1. 自行查找资料,学习并熟悉四线步进电机控制方法( 以
    28BYJ-48 型步进电机 为例);
  2. 阅读所提供的 displayer 模块参考源程序和其 API 函数设计方法, 规划构造控制三个步进电机程序模块的 API 函数(一个或多个函数)。三个步进电机分别假设为: SM 接口(可以 LED灯模拟,测试时应接 1 个真实步进电机)、 8 个 LED 指示灯(假设为另外 2 个步进电机控制接口(模拟));
  3. (可以基于原 StepMotor 定义进行功能扩充)从模块的初始化程序、后台服务程序(即,驱动)、应用层接口 API 函数三个层次设计该模块对应程序, 最终实现(个人所规划的) API 函数,并验证 API 函数的正确性。 (所编写的程序模块可根据需要,加载到模板任何模块上,如各种回调函数或主函数中, 不硬性要求按模板方式封装,比如说,可以将步进电机与导航键结合起来,导航键的调用可自行实现;当然如果实现了模板方式封装,有加分) 。
  4. 注意:本次实验不可使用小学期中应用的 BSP 。

三、具体实现

(一)最终实现功能如下:

(1)按键:

按下key1–>步进电机转向
按下key–>使步进电机加速使车加速
按下key–>让步进电机停下刹车

(2)导航键:

持续向上–>使步进电机不断增加转动速度/开始转动使车子平滑加速/启动车子
持续向下–>使步进电机不断减小转动速度使车子平滑减速直到停下
数码管能实时显示速度大小。

(二)工程模块化

在这里插入图片描述

1.首先是核心步进电机模块(StepMotor)

(1)使用 Motor 结构体定义了三个电机对象:motor1、motor2 和 motor3(步进电机2和3就是用led0~7进行模拟,我实现了代码,但结果展示时就不展示了,只展示真实的步进电机1)。
在这里插入图片描述

(后续要改变步进电机的状态,就只需要改变这些参数就行)
(2)初始化程序:StepMotorInit() 函数用于初始化电机1、2、3。电机1通过引脚 S1 到 S4 控制,电机2、3通过LED引脚 LED1 到 LED8 模拟控制。
在这里插入图片描述在这里插入图片描述

(3)驱动程序:StepMotorDrv() 函数根据 Motor 结构体的状态驱动步进电机或LED模拟电机。通过检查 motor->direction 决定电机的转动方向,motor->speed 控制电机的速度,motor->steps 决定每次的步数。通过 delay_time = 255 / speed 来控制延迟,从而控制步进电机的转速。驱动逻辑根据电机方向分别设置对应的引脚高低电平,产生步进信号,从而控制电机的转动。
核心代码如下:
在这里插入图片描述

(只截取了步进电机1“正向转动”时候的部分)
(4)API程序:
在这里插入图片描述

2.先完成对数码管的控制

(1)定义结构体及模块初始化程序(DisplayerInit())

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

(1) 要使图2的使能信号E3置为1,而E3信号在图3中,则要使P2.3为0才能让E3为1。
(2) P0.0~0.7置为1,点亮数码管(见图1)
(3) 设置工作模式为推挽模式(见图4)。
在这里插入图片描述
在这里插入图片描述

(2)硬件驱动程序(myDrvDisplayer())
该函数是动态扫描的核心驱动程序,用来逐位点亮数码管。它每次调用只更新一个数码管的显示内容。
在这里插入图片描述

所以后续要实现动态显示数码管,就用定时器0(后面实现)的中断函数调用myDrvDisplayer()函数,例如每毫秒逐次显示一个数,给人的感官就是每个数码管都在显示

3.要实现按键、导航键来控制这些参数如方向,速度,步数进一步控制步进电机的状态。

(1)实现了按键检测功能并基于按键的输入控制步进电机的方向、速度和刹车功能。代码的主要部分是按键检测函数 key() 和按键事件处理函数 EventKey()。
在这里插入图片描述
在这里插入图片描述

这个EventKey()函数也会在后续定时器0的中断函数里调用,保证每1ms检测一次是否有按键按下。
(2)实现了一个基于ADC(模数转换)的应用,用于监测导航键AD值变化并控制步进电机的动作。每次ADC转换完成时触发中断,处理AD值并通过一定的防抖逻辑防止抖动。整个设计目标是基于AD输入的变化来调整步进电机的速度和步数
首先对ADC模数转换器有关的寄存器进行初始化设置,并且将控制P1.7口的寄存器“打开”
在这里插入图片描述在这里插入图片描述

下面是ADC中断处理函数,这里是对ADC转换后的数字信号进行1000次采集,并对其进行防抖操作,最后得到的数字信号的高三位存储在uiAdHigh3中,对其进行switch判断执行相应的操作。
在这里插入图片描述

其中导航按键对应产生的数字信号如下:
在这里插入图片描述
在这里插入图片描述

说明一下我的执行功能:
Case 0是按下key3键(这里有个小插曲,我是先实现的按键控制,后实现的导航键(没有对case0执行功能),写完这个后测试单片机,发现之前按下key3键不起作用(没有让步进电机停止转动),后来查资料才知道当用ADC将P1.7口作为模拟输入时,我们是不能检测其数字信号的):让其步数=0(steps=0)让步进电机“刹车”
Case 5是导航键向上:

  1. 当steps=0(此时步进电机停止转动)时,将其赋值为1能够实现启动步进电机
  2. 对speed++能够让步进电机加速、如果一直向上按下按键,则速度一直稳定增长实现对“车子”平滑加速
  3. 只要速度在改变,就更改其要显示的值,让其也加1让速度能实时在数码管上更新

Case 2是导航键向下:

  1. 与case5平滑加速类似,它是让“车子”平滑减速直到停下,并且也是实时更新速度在数码管

4.初始化和管理单片机定时器功能的模块(初始化相关的控制寄存器),其中使用了定时器0来触发周期性中断

在这里插入图片描述

定时器0工作在1T、16位自动重装初值、1mS定时模式
即每1ms会中断执行下面这个中断程序:
在这里插入图片描述

定时器0中断函数里我调用的是前面提到的检测按下按键事件以及动态数码管显示。

(三)main函数

在这里插入图片描述

调用前面提到的API应用程序进行状态和变量初始化。
在这里插入图片描述

在while循环中一直调用StepMotor1启动步进电机(这里只以步进电机1为例)

四、效果展示

(一)通过按键实现的基本功能:转向,“加速”,“刹车”

1.转向

在这里插入图片描述

2.加速

在这里插入图片描述

3.刹车

在这里插入图片描述

(二)通过结合导航键拓展的功能:启动“车子”,平滑加速,平滑减少直至停下

1.启动“车子”

在这里插入图片描述

2.平滑加速

在这里插入图片描述

3.平滑减速直至停下

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值