STM32单片机光照检测智能调光系统Protest仿真+代码+报告+讲解视频
·
STM32单片机光照检测智能调光系统
本设计包含proteus仿真+程序代码+设计报告+讲解视频
一、开发环境
仿真图:proteus 8.17
程序编译器:keil 5
编程语言:C语言
设计编号:C0136
二、主要功能
-
采用STM32F103系列单片机作为控制核心,实现光照检测与LED亮度调节;
-
仿真环境光照检测范围为0~999lx,显示分辨率不低于10lx;
-
LED台灯亮度可在10%~100%范围内调节,至少具有5档亮度等级;
-
具有自动调光与手动调光两种工作模式,通过按键切换;
-
自动模式下,当环境光变化时,系统响应时间不大于2s;
-
采用OLED显示当前光照值、工作模式和亮度等级;
-
使用Proteus仿真实现亮度自动调节功能。

资料下载链接:
KEY_C0136 STM32智能台灯控制OLED显示设计
链接: https://pan.baidu.com/s/14liAWxV4vjPOY_2gfqGDkw?pwd=pc1q
提取码: pc1q
以下为本设计资料展示:
三、仿真设计
打开仿真工程,双击proteus中的单片机,选择hex文件路径,然后开始仿真。


四、程序代码
程序是用keil5 mdk版本打开的,如果打开有问题,核实下keil的版本。程序有注释可以结合讲解视频理解。
// 函数声明
void Hardware_Init(void);
void Display_Init(void);
void Refresh_Data(void);
// 全局变量
u8 humi, fan_adj; // 湿度、风扇调节(未使用)
u8 set_sta = 0; // 设置状态标志(0:正常显示,1:设置模式)
u8 key_ctrl = 0; // 按键控制标志,用于刷新显示
float mq2_vol, smog_th = 100.0; // MQ2烟雾传感器电压、烟雾阈值(未使用)
u8 temp_th = 30; // 温度阈值(未使用)
uint32_t light_vol; // 光照强度值(Lux)
uint8_t work_mode = 0; // 工作模式:0-自动模式,1-手动模式
uint8_t light_level = 1; // 亮度等级 1~5
uint8_t Fan_Status = 0; // 风扇状态(未使用)
uint8_t Beep_Status; // 蜂鸣器状态(未使用)
uint8_t Fire_Status = 0; // 火焰检测状态(未使用)
uint8_t relay_Status = 0; // 继电器状态(未使用)
uint8_t Status_Change; // 状态变化标志,用于刷新显示
float temp; // 温度值(未使用)
/*
************************************************************
* 函数名称: main
* 函数功能: 主函数,程序入口
* 入口参数: 无
* 返回参数: 0
* 说明: 循环检测光照、控制风扇亮度等级、刷新显示
************************************************************
*/
int main(void)
{
unsigned short timeCount = 0; // 发送间隔变量(用于定时任务,约2.5秒)
Hardware_Init(); // 初始化外围硬件
Display_Init(); // 初始化OLED显示界面
Led_Set(LED_OFF); // 关闭LED(指示灯)
SystemCoreClockUpdate(); // 更新系统核心时钟变量
// 通过串口1打印系统时钟频率
UsartPrintf(USART_DEBUG, "system_clock:%lu Hz (%.2f MHz)\r\n", SystemCoreClock, SystemCoreClock / 1000000.0);
while(1)
{
// 定时任务:每50次循环(约500ms,因为循环内DelayMs(10))执行一次
if(++timeCount >= 50) // 发送间隔2.5s
{
timeCount = 0;
// 读取光照强度(Lux)
light_vol = light_intensity();
UsartPrintf(USART_DEBUG, "light----%d--\r\n", light_vol);
// 如果是自动模式(work_mode==0),根据光照强度自动计算亮度等级
if(work_mode == 0)
light_level = light_level_intensity(); // 自动调节亮度等级
UsartPrintf(USART_DEBUG, " light_level = %d\r\n", light_level);
// 如果状态发生变化,重新初始化显示界面
if(Status_Change){
Status_Change = 0;
Display_Init();
}
}
// 处理设置模式下的显示清除
if(set_sta){
if(key_ctrl){
OLED_Clear();
key_ctrl = 0;
UsartPrintf(USART_DEBUG, "OLED_Clear\r\n");
}
} else {
// 非设置模式下,按键触发重新初始化显示
if(key_ctrl){
Display_Init();
key_ctrl = 0;
UsartPrintf(USART_DEBUG, "Display_Init\r\n");
}
}
// 刷新显示数据(光照值、工作模式、亮度等级等)
Refresh_Data();
// 根据亮度等级设置PWM占空比控制灯光
if(light_level == 1){
Fan_Set(PWM_L1);
} else if(light_level == 2){
Fan_Set(PWM_L2);
} else if(light_level == 3){
Fan_Set(PWM_L3);
} else if(light_level == 4){
Fan_Set(PWM_L4);
} else if(light_level == 5){
Fan_Set(PWM_L5);
}
DelayMs(10); // 延时10ms,主循环周期约10ms
}
}
/*
************************************************************
* 函数名称: Hardware_Init
* 函数功能: 硬件初始化
* 入口参数: 无
* 返回参数: 无
* 说明: 初始化单片机外设及外接模块:中断分组、延时、串口、
* 、LED、ADC、OLED、按键
************************************************************
*/
void Hardware_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断控制器分组设置(2位抢占优先级,2位子优先级)
Delay_Init(); // SysTick 延时初始化
Usart1_Init(115200); // 串口1初始化,波特率115200,用于打印调试信息
Usart2_Init(115200); // 串口2初始化,备用
Led_Init(); // LED指示灯初始化
AD_Init(); // ADC初始化(用于光照、烟雾等模拟量采集)
OLED_Init(); // OLED显示屏初始化
Fan_Init(); // PWM初始化 控制灯光
UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
OLED_Clear();
OLED_ShowString(0,0,"Hardware init OK",16);
DelayMs(1000);
Key_Init(); // 按键初始化
}
/*
************************************************************
* 函数名称: Display_Init
* 函数功能: 初始化OLED显示界面(绘制静态文字)
* 入口参数: 无
* 返回参数: 无
* 说明: 清屏后显示中文标签:
* 第0行:"光照:"
* 第3行:"工作模式:"
* 第6行:"亮度等级:"
************************************************************
*/
void Display_Init(void)
{
OLED_Clear();
// 第0行:显示"光照:"(中文字符,索引10,11,12,0)
OLED_ShowCHinese(0,0,10); // "光"
OLED_ShowCHinese(18,0,11); // "照"
OLED_ShowCHinese(18*2,0,12); // ":"
OLED_ShowCHinese(18*3,0,0); // ":"0是冒号)
// 第3行:显示"工作模式:"
OLED_ShowCHinese(0,3,13); // "工"
OLED_ShowCHinese(18*1,3,14); // "作"
OLED_ShowCHinese(18*2,3,15); // "模"
OLED_ShowCHinese(18*3,3,16); // "式"
OLED_ShowCHinese(18*4,3,0); // ":"
// 第6行:显示"亮度等级:"
OLED_ShowCHinese(0,6,17); // "亮"
OLED_ShowCHinese(18*1,6,18); // "度"
OLED_ShowCHinese(18*2,6,19); // "等"
OLED_ShowCHinese(18*3,6,20); // "级"
OLED_ShowCHinese(18*4,6,0); // ":"
}
/*
************************************************************
* 函数名称: Refresh_Data
* 函数功能: 刷新OLED上的动态数据(光照值、工作模式文字、亮度等级)
* 入口参数: 无
* 返回参数: 无
* 说明: 根据Status_Change标志决定是否清屏,仅在非设置模式(set_sta==0)
* 且非状态变化时更新显示数值。工作模式显示"自动"/"手动"。
************************************************************
*/
void Refresh_Data(void)
{
static u8 last_status = 0; // 记录上一次的Status_Change状态,用于检测上升沿
char buf[20]; // 临时字符串缓冲区
// 如果状态发生变化,且上一次状态为0(即刚变为1),则清屏
if(Status_Change) {
if(last_status == 0) {
OLED_Clear();
}
} else {
// 非设置模式下才更新显示数值
if(set_sta == 0){
memset(buf, 0, sizeof(buf));
// 显示光照强度值,单位Lux
sprintf(buf, "%dLux", light_vol);
OLED_ShowString(18*4, 0, (u8*)buf, 16); // 从第4个中文字符位置开始显示
// 显示工作模式:自动模式显示"自动",手动模式显示"手动"
if(work_mode == 0){ // 0是自动模式
OLED_ShowCHinese(18*5, 3, 21); // "自"
OLED_ShowCHinese(18*6, 3, 23); // "动"
} else {
OLED_ShowCHinese(18*5, 3, 22); // "手"
OLED_ShowCHinese(18*6, 3, 23); // "动"
}
// 显示亮度等级
memset(buf, 0, sizeof(buf));
sprintf(buf, "%d", light_level);
OLED_ShowString(18*5, 6, (u8*)buf, 16); // 从第5个中文字符位置显示等级数字
}
}
last_status = Status_Change; // 更新状态记录,用于下次判断边沿
}

程序流程图:

五、设计说明书
8265字,内容包括硬件设计、软件设计、结论等。

六、资料清单&下载链接

资料下载链接:
链接: https://pan.baidu.com/s/14liAWxV4vjPOY_2gfqGDkw?pwd=pc1q
提取码: pc1q

更多推荐



所有评论(0)