STM32项目分享:基于单片机的图书馆座位监测系统

发布于:2025-09-04 ⋅ 阅读:(15) ⋅ 点赞:(0)

“我们不做一锤子买卖,只做技术成长的长期伙伴!”

目录

一、视频展示

二、项目简介

三、原理图设计

四、PCB硬件设计

五、程序设计

六、资料分享


一、视频展示

基于单片机的图书馆座位监测系统 -视频分享

二、项目简介

题目:基于单片机的图书馆座位监测系统
主控:STM32
显示:OLED显示屏
DS1302时钟模块
红外光电
红外测温模块
蓝牙模块
红色led+黄色led
声光报警:LED+蜂鸣器
功能:
1、光电负责检测是否有物品在位置上,红外测温负责识别是人体还是其他物品。
2、若为物品占位则开启蜂鸣器报警提醒不得占位。
3、若为人则正常,当人员长时间使用座位时,黄色灯光亮起一分钟以提醒休息。若人员长时间离开座位时,红色灯光亮起,提示工作人员进行清洁。
4、显示屏显示当前座位编号,数据信息。

三、原理图设计

四、PCB硬件设计

五、程序设计

#include "stm32f10x.h"                  // 包含设备头文件
#include "delay.h"                      // 包含延时库
#include "lcd.h"                        // 包含LCD显示库
#include "ds1302.h"                     // 包含DS1302时钟库
#include "IOput.h"                      // 包含输入输出库
#include "usart.h"                      // 包含USART库

// 定义全局变量
u8 show_flag, BEEP_flag, on_flag, count;
u8 flag_lightel = 0,flag_wd = 0;
float MAX_WD=37.5,wd;
u8 flag_peo = 0;
u8 flag_real_peo = 0;
u8 flag_wuti = 0;
u8 timeM = 0;
u8 timeS = 0;
// 蜂鸣器控制函数


void beep1()
{
    BEEP = 0; // 打开蜂鸣器
    // 延时8秒,模拟蜂鸣器响8秒
	Delay_1ms(1000);
    Delay_1ms(1000);
    Delay_1ms(1000);
    Delay_1ms(1000);
    Delay_1ms(1000);
    Delay_1ms(1000);
    Delay_1ms(1000);
    Delay_1ms(1000);
    
    BEEP = 1; // 关闭蜂鸣器
    
    // 延时8秒,模拟蜂鸣器停止8秒

	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
	Delay_1ms(1000);
  
}

// 显示时间函数
void showtime(void)
{
    OLED_ShowCH(0,0,"编号:");
	OLED_ShowNum(40,0,12,2,16);
	if(flag_peo&&!flag_lightel )
	{
		OLED_ShowCH(64,0,"有人");
		flag_real_peo = 1;
		BEEP = 1;
	}else if(!flag_lightel)
	{
		OLED_ShowCH(64,0,"物体");
		flag_real_peo = 0;
		flag_wuti = 1;
		BEEP = 0;
	}else
	{
		OLED_ShowCH(64,0,"无人");
		flag_real_peo = 0;
		flag_wuti = 0;
		BEEP = 1;
	}
	
    OLED_ShowCH(0, 2, "状态:");        // 显示闹钟标识
    ds1032_read_realTime();             // 读取当前时间
    
    // 显示年份、月份、日期、小时、分钟和秒
    OLED_ShowNum(0, 4, TimeData.year, 4, 16);
    OLED_ShowString(35, 4, "/", 16);
    OLED_ShowNum(43, 4, TimeData.month, 2, 16);
    OLED_ShowString(60, 4, "/", 16);
    OLED_ShowNum(70, 4, TimeData.day, 2, 16);
    OLED_ShowNum(0, 6, TimeData.hour, 2, 16);
    OLED_ShowString(20, 6, ":", 16);
    OLED_ShowNum(30, 6, TimeData.minute, 2, 16);
    OLED_ShowString(50, 6, ":", 16);
    OLED_ShowNum(60, 6, TimeData.second, 2, 16);
}

// 显示修改时间的函数
void show_change_time(void)
{
    OLED_ShowString(0, 4, "20", 16);
    OLED_ShowNum(16, 4, lssj.year, 2, 16);
    OLED_ShowString(35, 4, "/", 16);
    OLED_ShowNum(43, 4, lssj.month, 2, 16);
    OLED_ShowString(60, 4, "/", 16);
    OLED_ShowNum(70, 4, lssj.day, 2, 16);
    OLED_ShowNum(0, 6, lssj.hour, 2, 16);
    OLED_ShowString(20, 6, ":", 16);
    OLED_ShowNum(30, 6, lssj.minute, 2, 16);
    OLED_ShowString(50, 6, ":", 16);
    OLED_ShowNum(60, 6, lssj.second, 2, 16);
    Delay_50ms(2); // 延时
}

// 定时函数,检查是否到达设定的闹钟时间
void DINGSHI(u8 minute_flag,u8  flag_led)
{
    if(TimeData.minute == minute_flag && TimeData.second < 30)
    {
        BEEP_flag = 1;
    }
    if(BEEP_flag == 1)
    {
		
		if(flag_led)
		{
			OLED_ShowCH(40,2,"该休息了");
			YELLOW = 1;
		}else
		{
			RED = 1;
			OLED_ShowCH(40,2,"该打扫了");
		}
		if(TimeData.second > 30)
		{
			RED = 0;
			YELLOW = 0;
			on_flag = 0;
			BEEP_flag = 0;
		}
    }


}
void check_people(void)
{
	u8 WENDU_H,WENDU_L;

//	OLED_ShowCH(0,0,"  红外体温计  ");	
//	OLED_ShowCH(0,2,"温度阈值:");	
//	OLED_ShowCH(0,4,"当前体温:");
//	OLED_Showdecimal(72,2,MAX_WD,2,1,16);
	
	if(USART_RX_STA&0X8000)//接收到一次数据
	{
		WENDU_H=USART_RX_BUF[2];		
		WENDU_L=USART_RX_BUF[3]/10;
		WENDU_H=WENDU_H&0X00FF;
		
		if(WENDU_H>=55)
		{
			
			WENDU_H=0;
			WENDU_L=0;
			wd = (float)WENDU_H+(float)WENDU_L;
			UsartPrintf(USART1,"编号:%d\r\n",12);
			if(flag_real_peo)
			{
				UsartPrintf(USART1,"有人\r\n");
			}else if(flag_wuti)
			{
				UsartPrintf(USART1,"有物品\r\n");
			}else
			{
				UsartPrintf(USART1,"没人\r\n");
			}
			UsartPrintf(USART1,"\r\n\r\n");
			OLED_ShowNum(104,0,wd,2,16);
			if(wd>1 && wd < 39.5)
			{
				flag_peo = 1;
			}else
			{
				flag_peo = 0;
			}
			USART_RX_STA=0;//启动下次接收
		}
		else
		{
			wd = (float)WENDU_H+(float)WENDU_L;
			UsartPrintf(USART1,"编号:%d\r\n",12);
			if(flag_real_peo)
			{
				UsartPrintf(USART1,"有人\r\n");
			}else if(flag_wuti)
			{
				UsartPrintf(USART1,"有物品\r\n");
			}else
			{
				UsartPrintf(USART1,"没人\r\n");
			}
			UsartPrintf(USART1,"\r\n\r\n");
			OLED_ShowNum(104,0,wd,2,16);
			if(wd>1 && wd < 39.5)
			{
				flag_peo = 1;
			}else
			{
				flag_peo = 0;
			}
			USART_RX_STA=0;//启动下次接收
		}
	}
	delay_ms(200);
	//发送测温指令 0XFA 0XCA 0XC4
	USART2_SendData(0XFA);
	USART2_SendData(0XCA);
	USART2_SendData(0XC4);
}
// 主函数
int main(void)
{
    delay_init(); // 初始化延时
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 配置优先级分组
    
    OLED_Init(); // 初始化OLED
    delay_ms(1);
    OLED_Clear(); // 清屏
    
    ds1302_gpio_init(); // 初始化DS1302
    input_init(); // 初始化输入
    output_init(); // 初始化输出
    
	Usart1_Init(9600);
    Usart2_Init(9600);
	
	//发送体温模式指令 0XFA 0XC5 0XBF
	USART_SendData(USART2,0XFA);
	USART_SendData(USART2,0XC5);
	USART_SendData(USART2,0XBF);
	delay_ms(50);

    while(1)
    {
		check_people();
		flag_lightel= GD;
		key_scan();
        if(key1_flag == 1)
        {
            key1_flag = 0;
            show_flag++;
            if(show_flag == 7)
            {
                show_flag = 0;
                lssj.month = (lssj.month) / 10 * 16 + (lssj.month) % 10;
                lssj.day = (lssj.day) / 10 * 16 + (lssj.day) % 10;
                lssj.hour = (lssj.hour) / 10 * 16 + (lssj.hour) % 10;
                lssj.minute = (lssj.minute) / 10 * 16 + (lssj.minute) % 10;
                lssj.second = (lssj.second) / 10 * 16 + (lssj.second) % 10;
                lssj.year = lssj.year;
                ds1032_init(); // 初始化DS1032
            }
        }
        
        if(show_flag == 0)
        {
            showtime(); // 显示时间
            lssj.year = TimeData.year - 2000;
            lssj.month = TimeData.month;
            lssj.day = TimeData.day;
            lssj.hour = TimeData.hour;
            lssj.minute = TimeData.minute;
            lssj.second = TimeData.second;
            lssj.week = TimeData.week;
            
            if(flag_real_peo == 1)
            {
				OLED_ShowCH(40,2,"位置有人");
//				flag_real_peo = 0;
				on_flag++;
				if(on_flag == 1)
				{
					timeM = TimeData.minute;
					timeS = TimeData.second;
				}

            }else 
			{
				on_flag = 0;
			}
            if(on_flag)
            {
                DINGSHI(timeM+1,1);//有人黄灯提醒
            }else
			{
				DINGSHI(timeM+1,0);//无人红灯提醒
				OLED_ShowCH(40,2,"位置没人");
			}
            
//            count++; // 增加计数
//            if(count >= 100)
//            {
//                // 通过串口打印时间和闹钟状态
//                UsartPrintf(USART1, "时间:\r\n%d年", TimeData.year);
//                UsartPrintf(USART1, "%d月", TimeData.month);
//                UsartPrintf(USART1, "%d日\r\n", TimeData.day);
//                UsartPrintf(USART1, " %d", TimeData.hour);
//                UsartPrintf(USART1, ":%d", TimeData.minute);
//                UsartPrintf(USART1, ":%d\r\n", TimeData.second);
//                if(on_flag == 1)
//                {
//                    UsartPrintf(USART1, "闹钟:开\r\n");
//                }
//                else
//                {
//                    UsartPrintf(USART1, "闹钟:关\r\n");
//                }
//                count = 0; // 重置计数
//            }
        }
        
        // 以下是调整年、月、日、小时、分钟和秒的功能
        if(show_flag == 1)
        {
            show_change_time();
            if(key2_flag == 1)
            {
                key2_flag = 0;
                lssj.year++;
            }
            if(key3_flag == 1)
            {
                key3_flag = 0;
                lssj.year--;
            }
            if(lssj.year > 100)
                lssj.year = 0;
            OLED_ShowChar(24, 4, '_', 16);
            Delay_50ms(2);
        }
        if(show_flag == 2)
        {
            show_change_time();
            if(key2_flag == 1)
            {
                key2_flag = 0;
                lssj.month++;
            }
            if(key3_flag == 1)
            {
                key3_flag = 0;
                lssj.month--;
            }
            if(lssj.month > 12)
                lssj.month = 1;
            if(lssj.month < 1)
                lssj.month = 12;
            OLED_ShowChar(51, 4, '_', 16);
            Delay_50ms(2);
        }
        if(show_flag == 3)
        {
            show_change_time();
            if(key2_flag == 1)
            {
                key2_flag = 0;
                lssj.day++;
            }
            if(key3_flag == 1)
            {
                key3_flag = 0;
                lssj.day--;
            }
            if(lssj.day > 31)
                lssj.day = 1;
            if(lssj.day < 1)
                lssj.day = 31;
            OLED_ShowChar(78, 4, '_', 16);
            Delay_50ms(2);
        }
        if(show_flag == 4)
        {
            show_change_time();
            if(key2_flag == 1)
            {
                key2_flag = 0;
                lssj.hour++;
                if(lssj.hour > 23)
                    lssj.hour = 0;
            }
            if(key3_flag == 1)
            {
                key3_flag = 0;
                lssj.hour--;
                if(lssj.hour > 200)
                    lssj.hour = 23;
            }
            OLED_ShowChar(8, 6, '_', 16);
            Delay_50ms(2);
        }
        if(show_flag == 5)
        {
            show_change_time();
            if(key2_flag == 1)
            {
                key2_flag = 0;
                lssj.minute++;
                if(lssj.minute > 59)
                    lssj.minute = 0;
            }
            if(key3_flag == 1)
            {
                key3_flag = 0;
                lssj.minute--;
                if(lssj.minute > 200)
                    lssj.minute = 59;
            }
            OLED_ShowChar(38, 6, '_', 16);
            Delay_50ms(2);
        }
        if(show_flag == 6)
        {
            show_change_time();
            if(key2_flag == 1)
            {
                key2_flag = 0;
                lssj.second++;
                if(lssj.second > 59)
                    lssj.second = 0;
            }
            if(key3_flag == 1)
            {
                key3_flag = 0;
                lssj.second--;
                if(lssj.second > 200)
                    lssj.second = 59;
            }
            OLED_ShowChar(68, 6, '_', 16);
            Delay_50ms(2);
        }
    }
}

六、资料分享

点击即可查看当前资料分享。