站内搜索
发作品签到
自行车多功能行车仪
专业版

自行车多功能行车仪

简介

基于STC15W4K48S4单片机的多功能自行车行车仪,包含自动开关车灯,实时速度、温度、骑行时间、里程和平均速度的测量、显示等功能。百元以下,一机满足骑行爱好者要求!!

简介:基于STC15W4K48S4单片机的多功能自行车行车仪,包含自动开关车灯,实时速度、温度、骑行时间、里程和平均速度的测量、显示等功能。百元以下,一机满足骑行爱好者要求!!
星火计划2025
复刻成本:53

开源协议

GPL 3.0

创建时间:2025-08-26 12:36:49更新时间:2025-12-09 00:24:33

描述

自行车行车记录仪(非录像型):

自行车简易行车记录仪功能演示及介绍

项目简介

  • 本项目基于STC15W4K48S4单片机,通过读取DS1302、DS18B20、光敏电阻阻值以及霍尔传感器数值,完成测量时间、平均速度、温度、夜间行车自动开关灯、速度和骑行里程等功能。

项目功能

  • 通过读取DS1302获取时间,精度为分钟。读取所得时间,用于计算平均速度、每分钟切换显示骑行时长与温度。
  • 通过读取DS18B20温度传感器,读取温度数值并显示。
  • 通过霍尔传感器与强力磁铁的配合,使用单片机内部时钟的定时功能,车轮滚动一圈触发一次中断,计算这段时间以内自行车行驶的平均速度。
  • 通过读取光敏电阻与10K电阻对电源电压分压以后的电压的ADC转换值,实现在低亮度环境下的自动开关灯。同时搭配按键开关,可以在必要时手动关闭或开启行车灯。

原理解析(硬件说明)

  • 工程采用3.3V可充电电池供电,使用6276电源管理芯片将3.3V电池输入电压转换为5V(实测5.02V)供电电压。
    屏幕截图 2025-12-01 230522.png
  • STC15W4K48S4单片机主控电路、光敏电阻ADC采样、OLED显示、按键以及DS18B20温度传感器读取电路
    屏幕截图 2025-12-01 230539.png
  • DS1302时钟读取电路。需要十分注意选择与DS1302负载电容匹配的晶振,否则难以起振或者起振具有随机性。我选择的是6皮法的。
    屏幕截图 2025-12-01 230450.png
  • 最后是亮灯控制电路。注意在此电路中需要将Light引脚配置为推挽输出模式,否则灯光亮度大为下降。
    屏幕截图 2025-12-01 230549.png

main函数部分软件代码

#include   //all these codes should be used under the frequency of @12Mhz
#include 
#include "DS1302.h"
#include "OLED.h"
#include "18b20.h"
#include "ADC.h"

unsigned int timeflag=0;
unsigned int turn_count=0;
unsigned int light_read = 0;
unsigned int ji = 1000;
unsigned char hour;
unsigned char minute;
float time;
float average_speed = 0.00;
float total_distance = 0.00;
double time_count=0.00;
float temperature = 0.00;
bit light_flag = 0;
bit auto_light = 0;
bit key_light = 1;
sbit T_LED = P2^3;
sbit Light = P2^5;
DS1302_time tim;

/***codes declaration***/

void IO_set(void);
void inter_set(void);
void OLED_background(void);
void speed_display(void);
void Delay1ms(void);
/*** main codes****/

void main(void){
	IO_set();
	InitADC();
	inter_set();
	DS1302_Init();
	DS1302_SetTime();
	OLED_Init();
	OLED_CLS();
	OLED_background();
	speed_display();
	while(1){
		EA = 0;
        Init_DS18B20();
		
		temperature = ReadTemperature();
		
		DS1302_ReadTime(&tim);
	    hour=tim.DS1302_Time[3];
	    minute=tim.DS1302_Time[4];
		time=(float)hour+(float)minute/60.0;
		
		if((minute%2) == 0){
			OLED_ShowASCII(86,6,"      "); //six spaces
			OLED_ShowChinese(64,6,9);
			OLED_ShowChinese(0,6,8);
			OLED_ShowChinese(16,6,9);
			displayfloat(temperature,32,6,4);
		}
		
		if((minute%2) == 1){
			OLED_ShowChinese(0,6,2);
			OLED_ShowChinese(16,6,3);
			OLED_ShowASCII(32,6,"    ");
			OLED_ShowNum(42,6,hour/10);
			OLED_ShowNum(50,6,hour%10);
			OLED_ShowNum(86,6,minute/10);
			OLED_ShowNum(94,6,minute%10);
			OLED_ShowASCII(64,6,"h  ");
			OLED_ShowASCII(103,6,"min");
		}
		light_read = GetADC(0x05);
		EA = 1;
		ji = 500;
		while(ji > 0){
			
			if(light_read <= 450 && key_light){
				Light = 1;
				light_flag = 1;
				auto_light = 1;
			}

			if(T_LED == 0){
				Delay1ms();
				Delay1ms();
				if(T_LED == 0){
					light_flag = !light_flag;
					if(auto_light == 1){auto_light = 0; key_light = 0; Light = 0;}
					else if(light_flag == 1){Light = 1;}
					else if(light_flag == 0){Light = 0;}
				}
				while(T_LED == 0);
			}
			
			Delay1ms();
			ji--;
		}
	}
}

/****** detail codes*****/

void Delay1ms(void)	//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}


void IO_set(void){
    P0M0 = 0x00; P0M1 = 0x00; 
    P1M0 = 0x00; P1M1 = 0x20; 
    P2M0 = 0x20; P2M1 = 0x00; 
    P3M0 = 0x00; P3M1 = 0x00; 
    P5M0 &= ~0xef; P5M1 &= ~0xef; 
}

void inter_set(void){
	Light=0;
	EX0=1;
	ET0=1;
	IT0=1;
	TH0=0x00;
	TL0=0x00;
	AUXR &= 0x7f;
  TMOD = 0x00;   
	TR0=0;
	EA=0;
}

void OLED_background(void){
	OLED_ShowChinese(0,0,0);
	OLED_ShowChinese(16,0,1);
	OLED_ShowChinese(0,2,6);
	OLED_ShowChinese(16,2,7);
	OLED_ShowChinese(32,2,0);
	OLED_ShowChinese(48,2,1);
	OLED_ShowChinese(0,4,4);
	OLED_ShowChinese(16,4,5);
	OLED_ShowChinese(0,6,8);
	OLED_ShowChinese(16,6,9);
	displayfloat(0.000,48,0,6);
	OLED_ShowASCII(103,0,"m/s");
	OLED_ShowASCII(95,2,"km/h");
	OLED_ShowASCII(111,4,"km");
	OLED_ShowChinese(64,6,9);
}

void speed_display(void){
	if(time == 0){
		OLED_ShowASCII(63,2,"0.00");
	}
	if(time != 0){ 
		average_speed = ((float)turn_count/500.0)/time;
		displayfloat(average_speed,63,2,4);
	}
	displayfloat((float)turn_count/500.0,58,4,7);
}

/**** interrupt handler************/

void INT0_ISR (void) interrupt 0
{
	EA = 0;
	TR0=0;
	time_count=timeflag*0.065536+(double)(TH0*256+TL0)/1000000;
	timeflag=0;
	turn_count += 1;
	if(time_count != 0){
	  displayfloat((float)(2.00/time_count),48,0,6);
	}
	speed_display();
	TH0=0x00;
	TL0=0x00;
	TR0=1;
	EA = 1;
}

void Timer0_ISR (void) interrupt 1 
{
	TR0=0;
	timeflag=timeflag+1;
	TH0=0x00;
	TL0=0x00;
	TR0=1;
}


仅展示main.c的代码,其余代码(驱动库和keil工程)请在附件中查看下载。

注意事项

  • 本工程的所有代码均需在12Mhz的系统频率下运行,若不在此频率下,不保证代码的可靠性。如需要的话,可以更改相关的软件延时函数以及数值计算函数。
  • 适配自行车时,注意本工程适配的自行车车轮滚动一圈的距离是2m。
  • 时钟不起振请优先检查晶振负载电容是否匹配DS1302。
  • 在自动车灯亮起以后点击按键为关闭自动车灯,且除非拔电不可恢复自动车灯。
  • 未添加掉电存储功能,拔电后所有数据归零。

实物图

1bd61dcca37cb07a010a4606b18eb8d3.jpg

08b6cceab8dfa5b42826ad592a6cc42b.jpg

9ff5093c1530d6b38e9eb13c7b1e0f71.jpg

338e90126c7aa776275df27b31006fdb.jpg

aad7f2ee8aaf5f524a26207bbf65ba91.jpg

f159f40f8a003ac827eb26f1bade33b8.jpg

装机图

IMG_20251205_195154.jpg

IMG_20251205_200336.jpg

IMG_20251205_200350.jpg

IMG_20251205_200415.jpg

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

3D模型

序号文件名称下载次数
暂无数据

附件

序号文件名称下载次数
1
STC15W_bikeDrive.zip
45
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

知识产权声明&复刻说明

本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。

请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。

底部导航