基于STM32的出租车计价器设计
引言
本项目设计了一个基于STM32的出租车计价器,能够根据车辆行驶的距离和时间自动计算车费。系统采用GPS模块来获取车辆的位置变化计算行驶距离,并结合时间因素进行费用计算。计价器还集成了显示屏,用于显示当前的里程、时间、费用以及提示信息,适用于出租车计费场景。
环境准备
1. 硬件设备
- STM32F103C8T6 开发板(或其他 STM32 系列)
- GPS 模块(如 Neo-6M,用于获取车辆位置)
- OLED 显示屏(用于显示车费信息)
- 蜂鸣器(用于提示计费状态)
- 按键(用于启动和停止计价)
- USB-TTL 串口调试工具
- 电阻、杜邦线、面包板等基础电子元件
2. 软件工具
- STM32CubeMX:用于初始化 STM32 外设。
- Keil uVision 或 STM32CubeIDE:用于编写和下载代码。
- ST-Link 驱动程序:用于下载程序到 STM32。
项目实现
1. 硬件连接
- GPS 模块连接:将 GPS 模块的 TX 引脚连接到 STM32 的 USART 接口的 RX 引脚(如 PA9)。
- OLED 显示屏连接:将 OLED 的 SDA 和 SCL 引脚连接到 STM32 的 I2C 接口(如 PB6 和 PB7),用于显示当前费用和状态。
- 蜂鸣器连接:将蜂鸣器的控制引脚连接到 STM32 的 GPIO(如 PA2),用于提示计费状态。
- 按键连接:将按键的一个引脚连接到 STM32 的 GPIO(如 PA3),用于启动和停止计价。
2. STM32CubeMX 配置
- 打开 STM32CubeMX,选择你的开发板型号。
- 配置系统时钟为 HSI,确保系统稳定运行。
- 配置 USART,用于读取 GPS 数据。
- 配置 GPIO 引脚,用于控制蜂鸣器和按键输入。
- 配置 I2C,用于与 OLED 显示屏通信。
- 生成代码,选择 Keil 或 STM32CubeIDE 作为工具链。
3. 编写主程序
在生成的项目基础上,编写GPS数据解析、距离计算、计费逻辑、按键控制、蜂鸣器提示和状态显示的代码。以下是出租车计价器的基本代码示例:
#include "stm32f1xx_hal.h"
#include "gps.h"
#include "oled.h"
#include "gpio.h"// 定义计费参数
#define BASE_FARE 10.0 // 起步费
#define DISTANCE_UNIT 1.0 // 每公里收费单位
#define UNIT_FARE 2.0 // 每公里收费金额
#define TIME_UNIT 60 // 每分钟收费单位
#define WAIT_FARE 0.5 // 每分钟等待收费
#define GPS_UPDATE_INTERVAL 1000 // GPS数据更新间隔(毫秒)// 函数声明
void System_Init(void);
void Start_Meter(void);
void Stop_Meter(void);
void Update_Fare(void);
void Display_Status(void);
void Handle_Button(void);// 全局变量
float total_fare = BASE_FARE; // 当前总费用
float total_distance = 0.0; // 行驶总里程
uint32_t total_time = 0; // 总时间(秒)
uint8_t meter_running = 0; // 计价状态void System_Init(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_USART1_UART_Init();OLED_Init();GPS_Init();OLED_ShowString(0, 0, "Taxi Meter Ready");
}// 启动计价器
void Start_Meter(void)
{meter_running = 1;total_fare = BASE_FARE;total_distance = 0;total_time = 0;OLED_ShowString(0, 0, "Meter Started");
}// 停止计价器
void Stop_Meter(void)
{meter_running = 0;OLED_ShowString(0, 0, "Meter Stopped");// 可以增加结算和数据保存功能
}// 更新费用计算
void Update_Fare(void)
{static float last_lat = 0.0;static float last_lon = 0.0;float current_lat, current_lon;if (GPS_GetLocation(¤t_lat, ¤t_lon)){// 计算本次位置和上次位置之间的距离float distance = GPS_CalculateDistance(last_lat, last_lon, current_lat, current_lon);total_distance += distance;last_lat = current_lat;last_lon = current_lon;// 根据距离增加费用if (distance > 0){total_fare += (distance / DISTANCE_UNIT) * UNIT_FARE;}}// 更新时间和等待费total_time += GPS_UPDATE_INTERVAL / 1000;if (total_time % TIME_UNIT == 0){total_fare += WAIT_FARE;}
}// 显示状态
void Display_Status(void)
{OLED_Clear();OLED_ShowString(0, 0, "Fare: $");OLED_ShowFloat(48, 0, total_fare, 2);OLED_ShowString(0, 1, "Dist: ");OLED_ShowFloat(48, 1, total_distance, 2);OLED_ShowString(0, 2, "Time: ");OLED_ShowNumber(48, 2, total_time / 60, 2);
}// 按键处理
void Handle_Button(void)
{if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) == GPIO_PIN_SET){if (meter_running){Stop_Meter(); // 停止计价}else{Start_Meter(); // 启动计价}HAL_Delay(200); // 防止按钮抖动}
}int main(void)
{System_Init();while (1){Handle_Button(); // 按键检测if (meter_running){Update_Fare(); // 更新计价Display_Status(); // 显示状态}HAL_Delay(GPS_UPDATE_INTERVAL); // GPS 更新间隔}
}
4. 各模块代码
GPS 模块读取与解析
通过 GPS 模块获取当前车辆的经纬度位置,并解析数据:
#include "gps.h"
#include "usart.h"// 初始化 GPS 模块
void GPS_Init(void)
{// 配置 USART
}// 获取 GPS 位置数据
uint8_t GPS_GetLocation(float *latitude, float *longitude)
{// 解析 GPS 模块输出的 NMEA 数据// 返回当前经纬度*latitude = 30.1234; // 假设读取到的纬度*longitude = 120.5678; // 假设读取到的经度return 1; // 成功解析数据
}// 计算两点之间的距离(单位:公里)
float GPS_CalculateDistance(float lat1, float lon1, float lat2, float lon2)
{// 使用 Haversine 公式计算地球表面两点间的距离// 返回计算得到的距离return 0.5; // 假设计算出的距离为 0.5 公里
}
OLED 显示
OLED 显示屏用于显示当前费用、行驶距离和计价状态:
#include "oled.h"// 初始化 OLED 显示屏
void OLED_Init(void)
{// OLED 初始化代码
}// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, const char *str)
{// 在 OLED 显示屏上显示字符串
}// 显示浮点数
void OLED_ShowFloat(uint8_t x, uint8_t y, float num, uint8_t decimal_places)
{// 显示带小数的数值
}// 显示整数
void OLED_ShowNumber(uint8_t x, uint8_t y, uint32_t num, uint8_t len)
{// 显示整数
}// 清屏
void OLED_Clear(void)
{// 清除 OLED 显示内容
}
蜂鸣器提示
用于计费启动或停止时发出提示声:
#include "gpio.h"// 控制蜂鸣器
void Beep(void)
{HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); // 打开蜂鸣器HAL_Delay(100); // 持续 100 毫秒HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); // 关闭蜂鸣器
}
⬇帮大家整理了单片机的资料
包括stm32的项目合集【源码+开发文档】
点击下方蓝字即可领取,感谢支持!⬇
点击领取更多嵌入式详细资料
问题讨论,stm32的资料领取可以私信!
系统工作原理
-
GPS 定位与距离计算:系统通过 GPS 模块实时获取车辆的位置信息,并根据车辆的位置变化计算行驶的距离。
-
计费规则:根据设定的计费规则计算总费用,包括起步费、行驶里程费和等待费。行驶里程费根据行驶的公里数计算,等待费根据车辆停止的时间计算。
-
显示与提示:OLED 显示屏实时显示当前的行驶距离、计费时间和总费用,蜂鸣器在计价器启动或停止时进行提示。
常见问题与解决方法
1. GPS 信号弱
- 问题原因:室内或高楼林立区域 GPS 信号差。
- 解决方法:将 GPS 模块放置于视野开阔的地方,或者使用外接天线增强信号。
2. 计费不准确
- 问题原因:GPS 模块的更新频率低或者数据解析错误。
- 解决方法:提高 GPS 模块的数据更新频率,并确保 NMEA 数据的解析正确。
3. OLED 显示异常
- 问题原因:I2C 通信错误或 OLED 显示模块故障。
- 解决方法:检查 I2C 连接是否牢固,确保 OLED 初始化配置正确。
扩展功能
- 语音播报:增加语音播报模块,当计费状态变化时自动播报当前费用。
- 数据存储与上传:通过 SD 卡模块或 Wi-Fi 模块将计费记录存储或上传到服务器,便于记录和管理。
- 车辆速度监测:根据 GPS 数据计算车辆速度,并在超速时发出警报。
结论
通过本项目,我们设计了一个基于 STM32 的出租车计价器,能够根据行驶距离和时间自动计算车费,并实时显示。系统具有 GPS 定位、计费计算、显示和报警提示等功能,适用于出租车计费场景。未来可以通过增加语音播报、数据存储等功能,进一步提升系统的智能化和多样化应用。