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~5uint8_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)rn", 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--rn", light_vol); // 如果是自动模式(work_mode==0),根据光照强度自动计算亮度等级 if(work_mode == 0) light_level = light_level_intensity(); // 自动调节亮度等级 UsartPrintf(USART_DEBUG, " light_level = %drn", 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_Clearrn"); } } else { // 非设置模式下,按键触发重新初始化显示 if(key_ctrl){ Display_Init(); key_ctrl = 0; UsartPrintf(USART_DEBUG, "Display_Initrn"); } } // 刷新显示数据(光照值、工作模式、亮度等级等) 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 OKrn"); 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
阅读全文
196