STM32 出租车计价器系统设计(一) 江科大源码改写

STM32 出租车计价器系统设计

功能目标

驱动步进电机模拟车轮旋转,并实现调速功能。
设置车轮周长和单价,检测车轮转速和运转时间。
计算并显示行驶里程和价格。

硬件材料

28BYJ48 五线四相步进电机和 ULN2003 驱动板模块
测速传感器模块
嵌入式小系统STM32
电源模块

在这里插入图片描述

出租车计费规则假设:

unit_price:设置每圈的价格为 1 元。
distance_of_qibu:设定起步距离为 1000cm,起步价为 7.5 元。
price、distance:分别用于存储当前价格和行驶距离,初始值为 0。
circumference:假设车轮周长为 200cm

float unit_price = 1;
int distance_of_qibu = 1000;
float price = 0;
float distance = 0;
float circumference = 200;

OLED 显示初始化内容

OLED_ShowString(1, 1, "Speed:");
OLED_ShowString(2, 1, "unit_price:");
OLED_ShowString(2, 14, "r");
OLED_ShowString(3, 1, "distance:");
OLED_ShowString(4, 1, "price:");

while中 OLED更新显示

OLED_ShowNum(1, 12, Speed - 1, 3);
OLED_ShowNum(2, 13, unit_price, 1);
OLED_ShowNum(3, 10, distance, 5);
OLED_ShowFNum(4, 10, price, 4, 2);

OLED 界面
在这里插入图片描述

电机驱动

主要就是步进电机的控制,单片机IO口驱动能力较差,所以需要驱动模块
这里使用 ULN2003 驱动 步进电机28BYJ48

电机驱动代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Key.h"
#include "Stepper.h"

uint8_t STEP;	// 用于存储电机正在走过的整步编号
/**
  * @brief  步进电机输出端GPIO初始化函数
  * @param  无
  * @retval 无
  */
void Stepper_GPIOInit(void)
{
	// 选择PA0,PA1,PA2,PA3分别为相A,B,C,D的输出
	RCC_APB2PeriphClockCmd(Stepper_CLK, ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;	// 推挽输出
	GPIO_InitStruct.GPIO_Pin = Stepper_LA | Stepper_LB | Stepper_LC | Stepper_LD;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(Stepper_Output_GPIO, &GPIO_InitStruct);
	
	GPIO_ResetBits(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LC | Stepper_LD);
}

/**
  * @brief  电机停转函数
  * @param  无
  * @retval 无
  */
void Stepper_Stop(void)
{
	GPIO_ResetBits(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LC | Stepper_LD);
}

/**
  * @brief  4拍单相整步驱动函数
  * @param  StepNum 	整步编号,0~3对应A~D
  * @param	Delay_Time_xms 		每步旋转后延时时间x ms,用于控制步进电机速度(一般需大于等于2)
  * @retval 无
  */
void Stepper_SingleStep(uint8_t StepNum, uint16_t Delay_Time_xms)
{
	switch(StepNum)
	{
		case 0:		// A
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA, Bit_SET);
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LB | Stepper_LC | Stepper_LD, Bit_RESET);
		break;
		case 1:		// B
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LB, Bit_SET);	
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA | Stepper_LC | Stepper_LD, Bit_RESET);
		break;			
		case 2:		// C
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LC, Bit_SET);	
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LD, Bit_RESET);
		break;
		case 3:		// D
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LD, Bit_SET);
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LC, Bit_RESET);
		break;
		default: break;
	}
	Delay_ms(Delay_Time_xms);	// 延时,控制电机速度
	Stepper_Stop();				// 断电,防止电机过热
}

/**
  * @brief  步进电机按步旋转
  * @param  direction		电机旋转方向,可以是Foreward(正传)或者Reversal(反转)
  * @param	step			电机转过的步数
  * @param	Delay_Time_xms	每步旋转后延时时间x ms,用于控制步进电机速度(一般需大于等于2)
  * @retval 无
  */
void Stepper_RotateByStep(RotDirection direction, uint32_t step, uint16_t Delay_Time_xms)
{
	
	for (uint32_t i = 0; i < step; i ++)
	{
		if (direction == Foreward)	// 电机正传
		{
			STEP ++;
			if (STEP > 3)
			{
				STEP = 0;
			}
		}
		else if (direction == Reversal)	// 电机反转
		{
			if (STEP < 1)
			{
				STEP = 4;
			}
			STEP --;
		}
		Stepper_SingleStep(STEP, Delay_Time_xms);
		
	
		
	}

}

/**
  * @brief  步进电机按整数圈旋转
  * @param  direction		电机旋转方向,可以是Foreward(正传)或者Reversal(反转)
  * @param  Loop			电机旋转的圈数
  * @param  Delay_Time_xms	每步旋转后延时时间x ms,用于控制步进电机速度(一般需大于等于2)
  * @retval 
  */
int Stepper_RotateByLoop(RotDirection direction, uint32_t Loop, uint16_t Delay_Time_xms)
{

	Stepper_RotateByStep(direction, Loop * 2048, Delay_Time_xms);
	return Loop;
}

#ifndef __STEPPER_H_
#define __STEPPER_H_

// 电机的旋转方向
typedef enum 
{
	Foreward = 0,
	Reversal = 1
} RotDirection;

// 需要使用其他端口时,只需要更改以下的宏定义即可
// 这里需要保证四个输出端口同属一个GPIO
// 如果不能满足这一点,需要更改Stepper.c中初始化函数Stepper_Init和Stepper_RotateByStep中的一些变量名称
// 这里的宏定义是为了提高程序的可读性和可移植性,但使用stm32f10x.h中定义的原始名称也未尝不可
#define		Stepper_CLK				RCC_APB2Periph_GPIOA
#define		Stepper_Output_GPIO		GPIOA
#define 	Stepper_LA				GPIO_Pin_0
#define 	Stepper_LB				GPIO_Pin_1
#define 	Stepper_LC				GPIO_Pin_2
#define 	Stepper_LD				GPIO_Pin_3

void Stepper_GPIOInit(void);
void Stepper_Stop(void);
void Stepper_SingleStep(uint8_t StepNum, uint16_t Delay_Time_xms);
void Stepper_RotateByStep(RotDirection direction, uint32_t step, uint16_t Delay_Time_xms);
int Stepper_RotateByLoop(RotDirection direction, uint32_t Loop, uint16_t Delay_Time_xms);

#endif

上面是电机驱动.c .h文件 接线也很简单 看宏定义就可以,想要具体原理,可以看网上的资料

用杜邦线接线真的很麻烦,后面准备简单画一个PCB
在这里插入图片描述

通过按键实现电机调速,这边加上按键中断会比较好。因为步进电机的简单代码中,会有延时函数,导致按键没有被读到。
也可以通过PWM控制电机进行调速。

有问题可以私聊我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/934777.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Datawhale AI冬令营(第一期)--零基础定制你的专属大模型

本文主要简述如何快速完成和一些小细节 第一步下载嬛嬛数据集 数据来源&#xff1a;self-llm/dataset/huanhuan.json at master datawhalechina/self-llm GitHub 注意:1.一定是数据集下载完成一定是.json结尾的 2.这个是github的网址&#xff0c;可能会遇到打不开的情况 …

Android 车载虚拟化底层技术-Kernel 5.10 -Android12(multi-cards)技术实现

详细代码实现见 Android Display Graphics系列文章-汇总​​​​​​Android Display Graphics系列文章-汇总 Android Display Graphics系列文章-汇总 Android Display Graphics系列文章-汇总 本文主要包括部分&#xff1a; 一、Android12的Kernel 5.10版本 1.1 Kernel 5…

qemu安装arm64架构银河麒麟

qemu虚拟化软件&#xff0c;可以在一个平台上模拟另一个硬件平台&#xff0c;可以支持多种处理器架构。 一、安装 安装教程&#xff1a;https://blog.csdn.net/qq_36035382/article/details/125308044 下载链接&#xff1a;https://qemu.weilnetz.de/w64/2024/ 我下载的是 …

前端入门之VUE--vue组件化编程

前言 VUE是前端用的最多的框架&#xff1b;这篇文章是本人大一上学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。 文章目录 2、Vue组件化编程2.1、组件2.2、基本使用2.2.1、VueComponent 2、Vue组件化编程 2.1、组件 组件&#xff1a;用来实现…

day08 接口测试(3)——postman工具使用

下载 postman 的历史版本&#xff1a;Postman 历史版本下载 - 简书 我自己根据我的电脑&#xff0c;安装的地址为&#xff1a;https://dl.pstmn.io/download/version/9.31.32/osx_64 今天开始学习 postman 这个测试工具啦。 【没有所谓的运气&#x1f36c;&#xff0c;只有绝…

C++游戏开发探秘【3】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C游戏开发的相关内容&#xff01; …

python基础:(七)类

目录 一.创建和使用类二.使用类和实例2.1给属性指定默认值2.2修改属性的值2.2.1直接修改属性的值2.2.2通过方法修改属性的值2.2.3通过方法对属性的值进行递增 三.继承3.1子类的方法__init__()3.2给子类定义属性和方法3.3重写父类的方法 四.导入类4.1语法--1:4.2语法--2 前言 p…

TortoiseGit的下载、安装和配置

一、TortoiseGit的简介 tortoiseGit是一个开放的git版本控制系统的源客户端&#xff0c;支持Winxp/vista/win7.该软件功能和git一样 不同的是&#xff1a;git是命令行操作模式&#xff0c;tortoiseGit界面化操作模式&#xff0c;不用记git相关命令就可以直接操作&#xff0c;读…

Avalonia实战实例一:使用Prism创建项目,并创建窗口

文章目录 一、安装Avalonia的项目模板二、安装Prism框架三、简单更改App.axaml为Prism基类四、创建窗口一、安装Avalonia的项目模板 这里安装的是Avalonia 11.2.1,.Net 6.0 安装完成,创建Avalonia项目。 二、安装Prism框架 打开Nuget,搜索Prism: 不要安装Prism.Core: …

【Spark】Spark的两种核心Shuffle工作原理详解

Spark 的shuffle机制 一、Spark ShuffleManager 发展历程 Spark 1.1.0 之前 在 Spark 1.1.0 之前&#xff0c;Spark 使用 BlockStoreShuffleFetcher 来处理 Shuffle 操作。这个实现主要依赖于直接从 BlockManager 获取 Shuffle 数据&#xff0c;并通过网络进行交换。 Spark …

Y3编辑器文档4:触发器1(对话、装备、特效、行为树、排行榜、不同步问题)

文章目录 一、触发器简介1.1 触发器界面1.2 ECA语句编辑及快捷键1.3 参数设置1.4 变量设置1.5 实体触发器1.6 函数库与触发器复用 二、触发器的多层结构2.1 子触发器&#xff08;在游戏内对新的事件进行注册&#xff09;2.2 触发器变量作用域2.3 复合条件2.4 循环2.5 计时器2.6…

Scala递归中求汉罗塔游戏的步骤

记&#xff1a;f(n,"A","B","C")表示n个盘子从A柱子上移动到C柱子上&#xff0c;借用B柱子的过程 f(要移动的盘子的个数&#xff0c;起点&#xff0c;辅助柱子&#xff0c;终点) 1.基本情况(直接能求的)&#xff1a;f(1,"A","B&…

UE5制作简单水材质

首先准备一张水材质法线贴图&#xff0c;也可以去 爱给网 和 花瓣网 找一张 导入后创建一个材质&#xff0c;如图所示 根据 Unreal 文档&#xff0c;吸收系数设置为红色 0.0033、绿色 0.0016、蓝色 0.0011。水看起来会更真实 然后放到一块平面上&#xff0c;就成功了&#xf…

【Web】2024“国城杯”网络安全挑战大赛题解

目录 Ez_Gallery 法一&#xff1a;shell盲注 法二&#xff1a;反弹shell 法三&#xff1a;响应钩子回显 Easy Jelly 法一&#xff1a;无回显XXE 法二&#xff1a;Jexl表达式RCE signal 法一&#xff1a;SSRF 法二&#xff1a;filterchain RCE Ez_Gallery 用这个bp验证…

【Rust 学习笔记】Rust 基础数据类型介绍——数组、向量和切片

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 博客内容主要围绕&#xff1a; 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 Rust 基础数据类型介绍——数组、向量和切片一、数组、向量和…

【软件工程】一篇入门UML建模图(状态图、活动图、构件图、部署图)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;软件开发必练内功_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

BGP路由优选

BGP是一个应用广泛的边界网关路由协议&#xff0c;定义了多种路径属性&#xff0c;拥有丰富的路由策略工具 BGP路由的各种属性的操作会影响路由的优选&#xff0c;从而对网络流量产生影响&#xff0c;BGP路由的优选规则十分重要 BGP路由优选的规则 当到达同一个目的网段存在…

路径规划之启发式算法之十四:蜘蛛蜂优化算法(Spider Wasp Optimizer, SWO)

蜘蛛蜂优化算法(Spider Wasp Optimizer, SWO)是一种受自然界中蜘蛛蜂行为启发的元启发式智能优化算法。由Mohamed Abdel-Basset等人于2023年提出,算法模拟了雌性蜘蛛蜂的狩猎、筑巢和交配行为,具有独特的更新策略,适用于具有不同探索和开发需求的广泛优化问题。 一、算法背…

在 Ansys Q3D 中求解直流和交流电感

提取电缆的电感对于确保电气和电子系统的性能和可靠性至关重要。本篇博客文章将介绍使用 Ansys Q3D 求解直流和交流电感的过程。 概述 在这个例子中&#xff0c;我们将考虑一个由两组电缆组成的简单几何&#xff1a;正极和负极&#xff0c;如下所示&#xff1a; 可以使用“自…

算法日记 47 day 最小生成树(prim,kruskal)

今天主要是针对最小生成树的两种算法。 用题目来举例 题目&#xff1a;寻宝 53. 寻宝&#xff08;第七期模拟笔试&#xff09; (kamacoder.com) 题目描述 在世界的某个区域&#xff0c;有一些分散的神秘岛屿&#xff0c;每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这…