一、项目介绍
随着科技的发展,人们对低碳环保的认知和需求不断提高。骑自行车既能够低碳环保,又能够锻炼身体,成为了很多人出行的首选。然而,由于自行车本身没有带指示灯,比如刹车指示灯等,所以自行车的安全性并不是很好,如果人们在骑自行车时紧急刹车,后车无法及时判断前方自行车的行为,容易造成交通事故。因此,设计一款自动刹车灯系统具有十分重要的意义。
本项目实现了通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能。当自行车上安装了该设备后,ADXL345通过IIC通信协议将X,Y,Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片,并结合STM32高级定时器的PWM功能,输出不同占空比的脉冲,控制不同的LED灯输出多种亮度等级,从而控制不同的LED的开关以及明暗,并且通过不同亮度的红光和绿光混合,能够得到黄色的LED灯光。这样,在自行车急刹或者加速时,实时地控制LED灯的亮度和颜色,让后方车辆能够更清楚地了解前方自行车的行为,从而做出快速的反应,保障骑行者以及后车的安全。同时,该系统也能够提高自行车的可见性,并且对于追求低碳环保的人群来说,让自行车既能低碳环保,又能够锻炼身体。
二、设计思路
2.1 项目目标
本项目通过安装ADXL345陀螺仪和四枚LED灯还有STM32F103C8T6主控芯片来实现自行车自动刹车灯的功能,使得自行车在急刹或者加速时,实时地控制LED灯的亮度和颜色,提高其可见性,降低交通事故的风险。同时,该系统还能够使自行车既能低碳环保,又能够锻炼身体。
2.2 项目硬件构成
(1)自行车:作为安装系统的物体,需要有一个固定的位置来安装ADXL345陀螺仪和四枚LED灯。
(2)ADXL345陀螺仪:通过IIC通信协议与STM32F103C8T6主控芯片通信,并将X、Y、Z三轴的加速度实时值发送给SMT32F103C8T6主控芯片。
(3)四枚LED灯:使用不同亮度的红光和绿光混合,能够得到黄色的LED灯光。通过控制其亮度和颜色来提高自行车的可见性。
(4)STM32F103C8T6主控芯片:根据接收到的ADXL345数据,结合STN32的高级定时器的PWM功能,输出不同占空比的脉冲,控制不同的LED灯输出多种亮度等级。
2.3 项目功能实现
(1)自行车加速度监测:ADXL345陀螺仪通过IIC通信协议与STM32F103C8T6主控芯片通信,实时地感知自行车的加速度变化。
(2)LED灯亮度和颜色控制:STM32F103C8T6主控芯片运用高级定时器的PWM功能,能够输出不同占空比的脉冲,并控制不同的LED灯输出多种亮度等级,通过不同亮度的红光和绿光混合,能够得到黄色的LED灯光,提高自行车的可见性。
(3)系统安装和调试:需要将ADXL345陀螺仪和四枚LED灯与STM32F103C8T6主控芯片连接起来,并进行系统测试和调试。
三、系统测试
3.1 功能样机安装与焊接
绘制好电路原理图之后,按照原理图将自动刹车灯系统的各个模块安装在事先购买好的洞洞板上,然后用导线将他们连接在一起,最后再焊接在一起,做成完整的自动刹车灯电路板。
3.2 ADXL345模块调试
当上电后,将自动刹车灯电路的串口2外设引脚连接至PC端,将加速度解算后的实际值发送至PC端,通过PC端串口调试助手显示出具体数值,再观察数值是否符合常理。
通过显示的数据信息,可以推测出ADXL345陀螺仪能够正常工作。
3.3 实物调试
最后阶段,将对自行车自动刹车灯进行实物调试,确定其基本功能能够正常实现。
当系统上电后,左右各一枚LED发出低亮黄色灯光,如下图。
静置30S后,所有LED均熄灭,如下图。
当检测到震动后,重新亮起两盏黄色LED灯,如下图。
当检测到刹车时,四枚LED灯均以高亮发出红色灯光,如下图。
结合自行车自动刹车灯的功能需求和实物调试结果,可以发现,调试结果完全符合自动刹车灯的预期功能。
四、代码设计
4.1 主函数
#include "stm32f10x.h"
#include "usart.h"
#include "led.h"
#include "RTC_Time.h"
#include < stdio.h >
#include "delay.h"
#include "sys.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "adxl345.h"
int main(void)
{
u32 flag=0;
short x, y, z;
float accelerated;
LED_GPIO_Config();//初始化LED
USART2_Config();
delay_init(); //延时函数初始化
PWM_LED_INIT(); //PWM PA8-9
LED_Init(); //PB7 LED-R
PBout(7) = 1;
ADXL345_Init(); //PB 10,11
ADXL345_Read_Average(&x, &y, &z, 20);
ADXL345_AUTO_Adjust((char *)&x, (char *)&y, (char *)&z);
TIM_SetCompare1(TIM1, 50); //设置TIMx捕获比较1寄存器(通道1)值(脉冲宽度) 占空比%20
TIM_SetCompare2(TIM1, 50); //设置TIMx捕获比较2寄存器(通道2)值(脉冲宽度) 占空比%20
while (1)
{
ADXL345_Read_Average(&x, &y, &z, 5); //读加速度值
accelerated=(x*3.9/1000*9.8); //加速度实际值
printf("X=%4.1f Y=%4.1f Z=%4.1f
",accelerated,(y*3.9/1000*9.8),(z*3.9/1000*9.8));
while(flag >425)
{
TIM_SetCompare1(TIM1, 0); //通道2 占空比%0
TIM_SetCompare2(TIM1, 0); //通道2 占空比%0
ADXL345_Read_Average(&x, &y, &z, 5);
accelerated=(x*3.9/1000*9.8);
if(accelerated< -5||accelerated >5)
{
break;
}
}
flag++;
if(accelerated< -4)
{
//四个LED低电平导通
TIM_SetCompare1(TIM1, 0); //GREEN不亮
TIM_SetCompare2(TIM1, 1000); //RED高亮
PBout(7) = 0;
flag=0;
}
if(accelerated >0)
{
PBout(7) = 1;
TIM_SetCompare1(TIM1, 50); //RED低亮
TIM_SetCompare2(TIM1, 50); //GREEN低亮
}
if(accelerated >5)
{
flag=0;
}
}
}
4.2 LED灯控制
#include "led.h"
#include "delay.h"
void LED_GPIO_Config(void)
{
//定义一个GPIO_InitTypeDef 类型的结构体,名字叫GPIO_InitStructure
GPIO_InitTypeDef GPIO_InitStructure;
//使能GPIOC的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
//选择要用的GPIO引脚
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13;
///设置引脚模式为推免输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//设置引脚速度为50MHZ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//调用库函数,初始化GPIO
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void TIME_INIT()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//TIM1定时器初始化 10ms
TIM_TimeBaseInitStructure.TIM_Period = 999;
TIM_TimeBaseInitStructure.TIM_Prescaler = 719;
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);
//TIM1的PWM配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = 0;//设置初始PWM脉冲宽度为0
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //PWM输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//当定时器计数值小于CCR_Val时为低电平
//通道的使能
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //通道1
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //通道2
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIM1重载寄存器ARR
TIM_Cmd(TIM1, ENABLE); //使能
TIM_CtrlPWMOutputs(TIM1, ENABLE); //高级定时器必须加
}
void PWM_LED_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //GPIOA8,9,10是TIM1的通道1,2,3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIME_INIT();
}
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
4.3 adxl345.c
#include "adxl345.h"
#include "sys.h"
#include "delay.h"
#include "math.h"
u8 ADXL345_Init(void)