基于STM32的光照度自动调节系统
1、硬件器材
STM32F103C8T6
HC-05
光照度传感器BH1750
一个LED灯(作为被调节对象)一个限流电阻(1k~10k)
2、硬件PCB绘制
这个硬件电路其实很简单,直接用洞洞板焊也很快,但是毕竟是我的课设作业,我还是画了一下PCB,显得高级hhh
最终效果:
需要PCB文件的话可以私信我(免费),画的比较简陋
3、stm32cubeMX配置
时钟和下载方式配置:
定时器1kHZ(72M/72/1000)不用定时器中断:
I2C(光照传感器需要)
串口通信(蓝牙需要)注意波特率一致:
要开串口中断:
勾选这三项,然后生成代码:
4、自己添加的代码
添加光照度传感器的代码,基本上就是普通的I2C通信,不细说了(下图不完整,完整的参考https://blog.csdn.net/weixin_43469377/article/details/120923774?spm=1001.2014.3001.5501 或者在我的资源里下载):
串口通信在usart.c添加下面的代码重定向printf函数:
记得添加头文件#include stdio.h
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
主函数:
头文件需要添加这些
一些参数:
靠调节PWM占空比来调节LED亮度:
初始化串口、LED灯亮度为50%,读取当前光照度:
主要逻辑(注释复制过来乱码了,下面有截图):
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
Set_Value=0;
Now_Value=0;
if(Flag==1) //½ÓÊÕÍêÒ»´ÎÀ¶ÑÀÖ¸Áî
{
Set_Value=strtoul((char *)Light_Buffer,NULL,10); //É趨ֵ±£´æ
HAL_Delay(500);
printf("SET:%lu lx\r\n",Set_Value); //»Ø¸´¸øÊÖ»úÉ趨ֵ
Now_Value=Value_GY30();
HAL_Delay(500);
printf("NOW:%d lx\r\n",Now_Value); //»Ø¸´¸øÊÖ»úµ±Ç°¹âÕÕ¶È
if(Set_Value>Now_Value) //É趨¹âÕÕ¶È>µ±Ç°¹âÕÕ¶È
{
printf("lighter"); //»Ø¸´¸øÊÖ»úµ÷ÁÁ
while(Set_Value>Value_GY30())
{
pwmVal+=15;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //Ôö´óLEDÁÁ¶ÈÖ±µ½µ±Ç°¹âÕÕ¶È´ïµ½É趨ֵ
}
printf("NOW:%d lx\r\n",Value_GY30()); //»Ø¸´¸øÊÖ»úµ±Ç°¹âÕÕ¶È
}
else if(Set_Value<Now_Value) //É趨¹âÕÕ¶È<µ±Ç°¹âÕÕ¶È
{
printf("Darker"); //»Ø¸´¸øÊÖ»úµ÷°µ
while(Set_Value<Value_GY30())
{
pwmVal-=15;
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwmVal); //¼õСLEDÁÁ¶ÈÖ±µ½µ±Ç°¹âÕÕ¶È´ïµ½É趨ֵ
}
printf("NOW:%d lx\r\n",Value_GY30()); //»Ø¸´¸øÊÖ»úµ±Ç°¹âÕÕ¶È
}
Flag=0; //Ò»´Îµ÷½Ú½áÊø£¬µÈ´ýÏÂÒ»´ÎÖ¸Áî
}
}
/* USER CODE END 3 */
串口的中断回调函数:
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(huart->Instance==USART1)
{
RxLine++; //接收到的数据加一
Light_Buffer[RxLine-1]=RecieveBuffer[0]; //保存收到的正确数据
if(RxLine==3)
{
// HAL_UART_Transmit_IT(&huart1, (uint8_t *)Light_Buffer, sizeof(Light_Buffer));
Flag=1;
}
RecieveBuffer[0]=0;
HAL_UART_Receive_IT(&huart1, (uint8_t *)RecieveBuffer, 1);
}
}
/* USER CODE END 4 */
有个使用的BUG就是,手机给单片机发送指定光照度时需要发三位数,例如设定为25LX,需要发送025
如果需要使光照度快速达到要求,可以更改这个值,让占空比改变速度变大(下图中的15),但是可能会调过了:
成果展示
光照度调节-演示视频
整个工程已上传到我的资源,需要的朋友可以看看