基于STM32的汽车仪表系统设计

收藏和点赞,您的关注是我创作的动力

概要

  本次课题基于STM32F407微型控制器以及CAN总线通信技术,设计一款新型全液晶汽车仪表。相比于传统的机械式指针仪表,本设计的汽车仪表具有简单的接线方式,快速的模块之间通讯以及全液晶显示等特点。同时,该课题中采用emWin技术进行LCD液晶显示屏的设计,具有更直观美化的人机交互界面,而且由于采用了CAN总线通信方式,元器件与控制元件(ECU)之间信息传递性将会更好。本次课题,采用CAN分析仪开发测试工具,通过定义好相关模拟变量,模拟实际汽车中的情况输入CAN信号报文并利用Simulink建模进行汽车仪表灯的逻辑处理。同时将FreeRTOS实时操作系统移植到STM32F407上,利用STM32芯片输入输出信号,进而达到点亮汽车仪表的目的。
通过软件与硬件方面的调试,该课题达到了预期研究要求,证明了课题技术上的可行性以及延展性。

关键词:汽车仪表; CAN总线; STM32F407; Simulink建模; FreeRTOS

一、方案设计

1.1 总体方案论证

本课题对于实现汽车仪表系统提出如下两套设计方案。
方案一:
本设计采用通过串口与按键的方式来进行汽车仪表的实现。该方式通过使用串口调试工具,在PC端向STM32芯片发送指令,经过STM32的识别后,输出到显示模块上。按键控制则是通过改变STM32芯片I/O口的高低电平,实现某个特定的仪表指示功能的点亮与熄灭。该方案分为硬件模块以及软件设计两个模块。其中硬件模块包括:主控芯片、按键控制电路、蜂鸣器报警电路、指针电机电路以及LED显示电路。软件方面采用了Keil5编程软件向STM32芯片烧写代码程序。
其中电源电路包括STM32的最小系统以及下载电路;按键电路主要负责系统的启动/关闭,以及相关指示灯的点亮/熄灭;蜂鸣器电路是根据STM32的输出信号,当某些报警条件触发时,蜂鸣器就会工作;电机电路采用伺服电机进行模块的控制,主要负责车速表的指针转动,转速表的指针转动等;LED显示电路则是根据STM32的输出信号,点亮对应的指示灯或熄灭对应的指示灯。
该方案的弊端主要为,机械式的仪表指针过于传统化,人机交互界面不够美观且智能化。同时,由于现代汽车仪表包含多种功能,需要大量的仪表指示灯与驾驶员进行交互。在本方案中采用的LED显示灯所呈现的信息不够生动、具体,而且需要大量的LED去表达对应的仪表指示灯,容易造成资源的浪费,且给项目的布线和通讯带来很大的麻烦。另一方面,由于项目存在大量的仪表模块,单一的点对点导线通讯很难完成高效的通讯实现,会对项目的实现造成干扰。
方案二:
本设计采用STM32芯片与CAN总线结合的方式实现汽车仪表。通过CAN分析仪发送报文,STM32处理输入输出报文信号,根据相应的条件控制显示模块与蜂鸣器模块。为了更直观的显示,在本设计中也增加了按键的硬线控制模块,通过按键控制某些特定的仪表灯。本设计主要分为硬件设计与软件设计。硬件模块包括:电源电路,蜂鸣器电路,按键电路以及LCD显示电路。软件设计主要由Keil5与Matlab来实现。
在本设计中,在LCD显示模块上,会采用软件烧写的方式,实现一款全液晶的仪表显示屏以取代电机模块与LED模块。相比于机械指针的方式,全液晶显示屏具有更美观,更直观的人机交互界面,同时节省了大量的LED以及布线需求。在通信的传递上,采用新兴的CAN总线传递方式,相比于传动的导线通信,CAN总线具有更高效,更稳定且更安全的通信方式。同时,在本次设计中,将会移植FreeRTOS实时操作系统到STM32芯片上。该方法可以实现多进程任务,可以在更好的处理不同情况下的仪表条件。
因此,采用方案二的汽车仪表系统更符合我们的实际需求,更贴切现代发展,该方案操作性高,维护性好,具有良好的安全性与实用性。因此,本设计采用方案二。

1.2 项目总体设计

本项目基于STM32F407设计的汽车仪表系统由:主控芯片,CAN通讯模块,按键模块,LCD显示模块和报警模块组成。STM32主控制芯片负责在接收到CAN通信传来的信号或者按键按下时的系统任务调度,经过主控芯片处理后,会输送到LCD显示模块和报警模块,执行点亮或熄灭相关指示灯,蜂鸣器警报,同步水温表,车速表等操作。系统功能框图如图1.1所示。

在这里插入图片描述

图1.1 系统功能框图

该项目分为两种控制方式:CAN总线通信以及按键硬线通信。通过使用CAN收发器实时发送CAN报文给STM32芯片,STM32芯片会判断是否满足相关条件,执行点亮/闪烁/熄灭相关仪表灯或报警。由于在STM32中移植FreeRTOS实时操作系统,会在一个循环周期内不停检测是否接收到CAN报文,执行多个任务调度,实现多个仪表灯的控制。按键控制则是通过定义好的I/O口与仪表灯,当按键按下或取消时,仪表灯和报警会有对应的显示。至此为该项目的流程与功能。

二、软件设计

3.1 主程序设计

本课题设计的主程序流程如图3.1所示,开机后会初始化液晶显示屏,内部时钟以及I/O口。在FreeRTOS里建立两个任务,分别为主程序任务以及显示任务(主程序任务优先级大于显示任务)。主程序任务会根据内部时钟,不停地循环。当STM32收到信息或按键按下,会判断是否有效。如若无效,不执行任何操作,继续循环。如若有效,会切换到显示任务中,根据逻辑,输出对应的信号,更新LCD液晶显示屏上的信息或蜂鸣器鸣响。
在这里插入图片描述

图3.1 程序主流程图

三、软件设计

3.3 emWin图形界面实现

为了完善本设计对仪表仪器人机交互界面操作的人性化、智能化的需求,本设计引用了emWin在stm32嵌入式设计,使用了GUIBuilder作为一种LCD界面图形可视化程序的设计方法,最终驱动硬件电路完成LCD显示[15]。在TaskDisplay中,利用Bmpcvt.exe软件可将png格式的图片转化为16进制的C代码格式。在APP模块中,调用GUIBuilder的API函数“GUI_DrawBitmap”,即可实现图片的显示。项目部分源码如图3.5所示:
在这里插入图片描述

图3.5 emWin实现
emWin可以在操作系统下的多任务中工作。它具有模块化的特点,采用分层结构。emWin总共包括4层,每层可以单独使用。包括第一层:LCD驱动器;第二层:图形库;第三层:插件库;第四层:窗口管理器[16]。emWin是以C语言的形式实现,通过对第一层的修改,就可应用到项目中。emWin模块流程图如3.6所示:

在这里插入图片描述

图3.6 emWin流程图
在汽车仪表的图形化界面设计中,最为重要的就是仪表指针转动的设计。仪表指针需要根据STM32收到的CAN报文,来在图形界面中有相应的显示。为了使指针的精度精准,需要用量角器测出仪表盘的数据刻度,在代码中进行算法优化。以车速表为例,如图3.7所示:
在这里插入图片描述

图3.7 车速表概念图
如上图所示,将该仪表盘看做一个在坐标轴上的圆形,从X轴起始到0刻度大约为225度,到170刻度大约为45度。因此该车速表可以看做一个半径为1的270度圆,既1.25×3.14+0.25×3.14。当CAN报文传输进20KM/h的值时,只需让指针指向约195度的位置,既1.16×3.14,就可以实现仪表指针的精准转动。具体代码如图3.8所示:
在这里插入图片描述

图3.8 指针算法
具体的数据会在调试中,根据实际情况的变化而改变以到达最小误差的效果。

实物

在这里插入图片描述

附录2 源程序清单

#include "GUI.h"
#include "JPGResource.h"
#include "displayapp.h"
#include "sys.h"
#include "delay.h"
#include "key.h"
#include "Beep.h"

uint16_t gEngCoolantValue = 0;
uint16_t gFuelResistanceValue = 0;
uint16_t gESCVehSpeed = 0;								//0-170km/h
uint32_t gEMSEngSpd = 0;									//0-8000
uint32_t gODOMeter = 0;
uint8_t gturnleft = 0;
uint8_t gturnright = 0;
uint32_t flag = 0;
uint8_t gAir = 0;
uint8_t gseatbelt = 0;
uint8_t gseatbelt1 = 0;
uint8_t gABSwarning = 0;
uint8_t gPark = 0;
uint8_t gposition = 0;

static const GUI_POINT aPointer[] = {
   
	{
    0, 10 },
	{
    150, 0 },
	{
    0, -10 },
	{
    -20, 0 },
};
static const GUI_POINT aSmallPointer[] = {
   
	{
    0, 5 },
	{
    40, 0 },
	{
    0, -5 },
	{
    -10, 0 },
};

static GUI_POINT aPointerHiRes[countof(aPointer)];
static GUI_POINT aSmallPointerHiRes[countof(aSmallPointer)];

typedef struct {
   
GUI_AUTODEV_INFO AutoInfo;
GUI_POINT aPoints[countof(aPointer)];
GUI_POINT aSmallPoints[countof(aSmallPointer)];
int Factor;
}PARAMPolygon;

#define HMI_POS_Y	25

static void DrawSpeed(void * p) 
{
   
	int posX = 25, posY = HMI_POS_Y;
	PARAMPolygon * pParam = (PARAMPolygon *)p;
	if (pParam->AutoInfo.DrawFixed) {
   
	GUI_Cle
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值