基于STM32F4开发的智能台灯
Posted canoe1996
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于STM32F4开发的智能台灯相关的知识,希望对你有一定的参考价值。
基于STM32F4开发的智能台灯
写这篇博客的目的有2个,首先是记录一下学习STM32大半年来的第一个自己动手开发的项目,整理一下开发过程和思路;其次也是希望可以和更多的同行交流开发经验,有什么问题可以多多讨论,集思广益,共同进步~
设计目标以及功能说明
开发的智能台灯功能有2个:
1.手动模式:可通过按键调节LED灯亮度,共10档;
2.自动模式:当检测到有人在的条件下,根据环境光照强度自动调节LED灯亮度;当检测到无人在,将进入延时,延时时间结束将关闭LED灯。
原理图
由于是在面包板上焊接的电路,原理图画的比较粗糙;
首先核心控制器件选用的是正点原子的STM32F407核心板,这款核心板功能非常齐全,应付一般的项目开发控制绝对是够了,自己手头上项目也是用这个做的。
手动模式下的LED控制:这个就比较简单,直接核心板输出一个定时器TIM13-PWM的脉宽调制信号到LED灯上,按键上下调节占空比即可调节亮度,相信了解PWM控制原理的小伙伴一看就知道是怎么回事~
自动模式下的LED控制:
1.红外探测模块可以去淘宝上搜索,有很多成熟的模块选用,总的来说就是这种模块可以在一定范围内检测到有人即可输出高电平信号,没有人就保持低电平;我选用的是HC-SR501,质量不是很好,本来有2种模式,不可重复触发模式:即探测到人就输出一定时间的高电平然后变为低电平;可重复触发模式:探测到有人一直输出高电平知道人离开延时结束。
2.将红外探测模块接到MCU的ADC1通道2,当adcx2得到的值大于1500,就说明有人,此时光敏电阻与电位器串联的电路通过ADC1通道3检测电压信号即代表了环境亮度,然后经过简单的数学公式建立通道3检测的到的adcx3与PWM占空比的关系,就可以实现根据环境亮度实时调节LED亮度的功能。
3.当检测到无人时,在程序里面设置了for循环+delay,延时时间可以自己设置,延时一段时间后就跳出循环,等待下一个红外探测模块的高电平进入循环。
程序代码
代码是在keil5里面用C语言写的,下面就把主程序的代码放上来,里面注释的很清楚,大家可以看一下
在这里插入代码片int main (void)
{
volatile u8 t=0;
volatile u8 i=0;
volatile u8 key; //按键
volatile u16 led0pwmval = 499;//LED灯亮度值 0为最亮,499为最弱
volatile u8 SD_Mode = 0;//手动模式
volatile u16 adcx0;
volatile u16 adcx1;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LCD_Init(); //LCD初始化
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
Adc_Init(); //adc初始化
TIM13_PWM_Init(500-1,84-1); //84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
TIM_SetCompare1(TIM13,led0pwmval); //修改比较值,修改占空比
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"CANOE @ Light");
delay_ms(5000);
while(1)
{
while (SD_Mode == 0)//自动模式
{
LCD_ShowString(30,70,200,16,16,"zidongmoshi");
LCD_ShowString(30,150,200,16,16,"LIGHT_VAL:");
key=KEY_Scan(0);
if(key==KEY0_PRES||key==WKUP_PRES) //在自动模式下,如果检测到有按键按下,则退出自动模式进入手动模式
{
SD_Mode = 1;
}
TIM_SetCompare1(TIM13,499);
adcx0=Get_Adc_Average(ADC_Channel_2,10); //通过ADC1探测得到红外探测模块的输出值,当有人活动时会监测得到高电平
if (adcx0 > 1500) //当探测得到高电平时,根据ADC通道3采集得到光敏电阻的值来调节亮度值
{
for(i=0;i<100;i++)
{
adcx1=Get_Adc_Average(ADC_Channel_3,10);//采集得到光敏电阻的值,环境亮度越暗得到的值越小,亮度越高得到的值越大
//adcx1的值处于1200~4000范围内
led0pwmval = (adcx1 - 1200)/6;
TIM_SetCompare1(TIM13,led0pwmval); //修改比较值,修改占空比
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowxNum(110,150,(500-led0pwmval),4,16,0); //显示 亮度值
delay_ms(100);
key=KEY_Scan(0);
if(key==KEY0_PRES||key==WKUP_PRES) //在自动模式下,如果检测到有按键按下,则退出自动模式进入手动模式
{
SD_Mode = 1;
i=100;
}
}
}
}
led0pwmval = 300;
while(SD_Mode == 1) //手动模式下 按键增减LED亮度
{
LCD_ShowString(30,70,200,16,16,"shoudongmoshi");
LCD_ShowString(30,90,200,16,16,"WK_UP:+ KEY0:-");
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,150,200,16,16,"LIGHT_VAL:");
t++;
key=KEY_Scan(0);
if(key==WKUP_PRES)
{
if(led0pwmval<499)led0pwmval+=40;
TIM_SetCompare1(TIM13,led0pwmval); //修改比较值,修改占空比
}
else if(key==KEY0_PRES)
{
if(led0pwmval>45)led0pwmval-=40;
else led0pwmval=0;
TIM_SetCompare1(TIM13,led0pwmval); //修改比较值,修改占空比
}
if(t==10||key==KEY0_PRES||key==WKUP_PRES) //WKUP/KEY1按下了,或者定时时间到了
{
LCD_ShowxNum(110,150,(500-led0pwmval),4,16,0); //显示 亮度值
LED0=!LED0;
t=0;
}
delay_ms(10);
}
}
}
实物图
结束语
本人现在是科研狗一枚,这个小东西是在老师给的项目忙里偷闲花了3天时间做出来的,主要是为了熟悉STM32开发的一些东西,后面有时间还会陆续做一些其他有些意思的项目,大家如果有什么好玩的项目想法创意之类的可以私信我一起交流,有机会一起做些有意思的事~
有什么问题留言区或者私信我讨论,邮件也可以(18642896070@163.com),欢迎交流~
以上是关于基于STM32F4开发的智能台灯的主要内容,如果未能解决你的问题,请参考以下文章
STM32F4 HAL库开发 -- 新建基于 HAL 库的工程模板
STM32F4 HAL库开发 -- 新建基于 HAL 库的工程模板