0 前言
🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 毕业设计 基于单片机的电动车智能仪表系统设计
🥇学长这里给一个题目综合评分(每项满分5分)
- 难度系数:3分
- 工作量:3分
- 创新点:5分
🧿 选题指导, 项目分享:
1 简介
基于stm32单片机作为主控,采用操作系统采用国产RT-Thread系统; 该系统设计可实现以下功能: 通过OLED12864作为液晶屏幕进行数据显示;
本系统可实现
(1)定速巡航(定速为25Km/h);
(2)OLED屏幕显示速度(0-36km/h);
(3)可以显示年,时分秒,方便骑行者查看数据;
(4)速度过快LED灯模拟报警;
(5)可调电阻作为电动车油门进行控速;
2 主要器件
- stm32单片机
- RT-Thread物联网操作系统
- OLED12864液晶屏幕
3 实现效果
可进行速度检测,超速时LED灯会亮
4 设计原理
硬件设计
主要框架
硬件采用中科蓝讯的AB32VG1单片机进行开发;
AB32VG1主控MCU
AB32VG1是一颗基于RISC-V的MCU,性价比非常高,不管是开发板还是芯片,都比较便宜,具体参数如下:
利用RT-Thread Studio(https://www.rt-thread.org/page/studio.html)进行开发。此外,需要安装Bluetrum开发板支持以及RISC-V-GCC编译器,如图:
AB32VG1:充当主控,使用其SDIO接口,用于读取SD的内容。还使用其串口,用于链接Wi-Fi模组。
实时操作系统采用国产RT-Thread系统;
内核部分:使用了多线程、多任务调度、信号量、互斥量等。
组件部分:硬件ADC、模拟IIC、RTC等。
OLED12864屏
OLED 屏幕作为一种新型的显示技术,其自身可以发光,亮度,对比度高,功耗低,在当下备受追捧。而在我们正常的显示调整参数过程中,我们越来越多的使用这种屏幕。我们使用的一般是分辨率为 128x64 ,屏幕尺寸为 0.96 寸。由于其较小的尺寸和比较高的分辨率,让它有着很好的显示效果和便携性。
基本参数
软件部分
编程软件基于RT_Thread Studio;采用的编程语言为:C语言
代码采用部分信号量和互斥量保证线程同步,通过多线程任务调度实现无缝切换。
OLED显示执行函数在 display.c
OLED底层驱动函数在 oled.c
按键执行函数在 button.c
ADC函数在 adc_val.c
5 部分核心代码
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-02 13175969569 the first version
*/
#include "display.h"
#include <oled.h>
#include "board.h"
static void display_entry(void *parameter)
{
OLED_Clear();
while(1)
{
OLED_ShowNum(45,25,(int)drive_num,2,24,1); OLED_ShowString(80,25, "Km/h",24,1);
//OLED_ShowString(25,0, ".",16,1);
OLED_ShowString(12,1,dest,16,1);//时间显示
if(dingsu_Flag==0)OLED_ShowString(100,46," ON",16,1); //定速模式开启,固定车速25Km/h
else if(dingsu_Flag==1)OLED_ShowString(100,46,"OFF",16,1); //非定速模式
OLED_Refresh();
rt_thread_delay(100);
}
}
rt_thread_t display=RT_NULL;
int display_init(void)
{
OLED_Init();
//创建显示线程 优先级设置为31
display = rt_thread_create("display", display_entry, RT_NULL, 1024, 28, 5);
//启动显示线程
if(RT_NULL != display)
{
rt_thread_startup(display);
// rt_kprintf("display_ok\n");
}
return 0;
}
#include <adc_val.h>
#include "pwm.h"
#include "button.h"
#define ADC_DEV_NAME "adc0" /* ADC 设备名称 */
#define ADC_DEV_CHANNEL 7 /* ADC 通道 */
#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS (1 << 10) /* 转换位数为10位 */
rt_adc_device_t adc_dev;
rt_uint32_t value=0;
float val_l=0,temp=0;
//电压换算成温度
static float temp_data(void)
{
float Rt=0;
float Rp=10;
float T2=273.15+25;
float Bx=3435;
float Ka=273.15;
/* 读取采样值 */
if(dingsu_Flag==0){ //非定速
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
drive_num=value/28;
val_l=((int)value*3.30/1024);
}
else if(dingsu_Flag==1){ //定速
value=888;
drive_num=25;
}
return value;
}
static void temp_get_entry(void *parameter)
{
static int i=0;
while(1)
{
value = temp_data();
if(++i>=100)
{
if(dingsu_Flag==0)
rt_kprintf("AD_Num:%d----val:%d.%02dV\n", value,(int)(val_l * 100) / 100,(int)(val_l * 100) % 100);
rt_kprintf("Current speed is:%d Km/h.\n\n",drive_num);
i=0;
}
rt_thread_delay(10);
if(value>=900)rt_pin_write(GET_PIN(A, 1), PIN_LOW); //报警
else rt_pin_write(GET_PIN(A, 1), PIN_HIGH);
}
}
rt_thread_t temp_get_adc=RT_NULL;
int temp_get_adc_init(void)
{
rt_err_t ret = RT_EOK;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
return RT_ERROR;
}
/* 使能设备 */
ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
/* 关闭通道 */
// ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
//创建温度采集线程
temp_get_adc = rt_thread_create("temp_get_adc", temp_get_entry, RT_NULL, 1024, 11, 20);
//启动线程
if(RT_NULL != temp_get_adc)
{
rt_thread_startup(temp_get_adc);
}
return ret;
}