预警系统最小例程构建

预警系统最小例程构建

引言

为了更直观, 我们使用最小例程来实现这个预警流程, 环境温湿度读取,然后判断阈值, 超标则触发小灯警报。

最小例程工程备份链接:

https://ww0.lanzoul.com/iz4wd261k21i

仿真文件工程备份链接:

https://ww0.lanzoul.com/i8vTn261syyb

用到的单片机工具

实物:

下面是用到的材料:

stm32最小系统板,面包板,面包线,杜邦线,led灯,dht11,按键

手把手购买视频:

【手把手器件购买视频-哔哩哔哩】 https://b23.tv/nLOVso3

手把手安装视频:

【最小例程插线方法-哔哩哔哩】 https://b23.tv/k3CciWL

仿真:

也可以不购买器件,仿真安装视频:

【仿真软件安装教程】 https://b23.tv/z6qWs1K

仿真文件以及烧录视频:

仿真工程:https://ww0.lanzoul.com/i8vTn261syyb

【仿真烧录步骤-哔哩哔哩】 https://b23.tv/WojZSWY

烧录仿真配置:

输出仿真文件:

image-20240731114249234

仿真图:

image-20240731114058428

烧录步骤:

(1)双击单片机

(2)点击那个文件夹, 然后选中刚才的Output里面的hex文件, 然后确定

(3)然后点击左下角的运行按钮

keil软件开发安装视频:

【开发软件keil5安装-哔哩哔哩】 https://b23.tv/9pYqego

工程构建:

1.桌面新建文件夹

image-20240730190641850

2.打开keil5软件

image-20240730190724603
  1. 新建项目

    image-20240730190859448

4.选中刚才在桌面新建的文件夹

image-20240730190958265

5.随便输入英文工程名字 ,保存

image-20240730191048178

6.选中STM32F103C8 , 然后点击OK

image-20240730191345471

7.然后就会跳出选择配置文件的页面, 如果没跳出,就点击这个绿色菱形

image-20240730191911422

8.勾选下面的对钩, 只选最基本的,然后点击ok

image-20240730192053587

  1. 下面配置一下编译器和环境语言

(1)点锤子

image-20240730192157972

(2)选择version5 , 点击ok

image-20240730192301175

(3)点击Edit->configuration

image-20240730192414850

(4)选择 chinese GB2312 (Simplified), 点击ok (方便输入中文)

image-20240730192517525

(5)启动文件这里变成800, 后面Onenet服务器要增加栈内存

image-20240730192724740

10.工程源码文件夹创建

(1)点品字,下面的 这几块的功能介绍, 下一步直接开建

image-20240730193048445

(2)Project Targets:是工程名字, 我们起zuixiao

Groups: 是组名字,我们先起 user

然后在右侧的Add Files里面,添加mina函数

image-20240730223853820

(3)点击此处文件夹, 新建Source文件夹, 用来存放源码:

image-20240730224019925

(4)点进去Source文件夹, 然后新建User文件夹,用来存放user组的文件

image-20240730224107299

(5)点进去user文件夹, 然后点文件类型, 选择All files(这样就可以看到所有文件了)

image-20240730224224187

(6),然后右键空白处新建main.c文件( 如果没有看到后缀,则百度搜索:如何看到文件后缀名), 可以新建一个txt文件, 然后右键重命名, 选中所有,然后改成main.c

image-20240730224453527

image-20240730224516713

image-20240730224531525

(7)选中main.c, 然后点击add

image-20240730224614759

(8)此处就可以看到main.c了,点击ok,

image-20240730224648339

(9)双击左侧的 main.c文件, 就可以进行编辑了

image-20240730224740727

最小例程实操:

构建思路

我们之前的思路就是, 读取环境信息-> 判断环境与阈值关系->是否启动预警

由于读取环境信息器件众多, 所以我们直接用变量来代替温湿度, 我们通过手动输入变量,来模拟器件读取

int temp;	//读取的环境温度
int humi;	//读取的环境湿度

由于此时条件有限, 我们也通过手动控制 温湿度阈值, 我们其实主要想实现, 判断环境信息与阈值对比,如果能报警,则行的通

int temp_th;	//设置的温度阈值
int humi_th;	//设置的湿度阈值

此时我们手动进行赋值,来模拟读取环境信息

temp = 28;	//温度是28度
humi = 60;	//湿度是60%

此时我们再设置一个阈值

temp_th = 30;	//温度阈值是30度
humi = 60;		//湿度阈值是60%

预警信息触发条件:

温湿度,超过阈值时候,触发

温度 >= 温度阈值 : 红灯亮

湿度 >= 湿度阈值 : 蓝灯亮

if(temp >= temp_th)
{
    //红灯亮
}
else
{
   //红灯灭
}
if(humi >= humi_th)
{
    //蓝灯亮
}
else
{
    //蓝灯灭
}   

代码实现

(1)引入stm32头文件,相关变量定义以及初始化
#include "stm32f10x.h"                  // Device header

int temp;	//读取的环境温度
int humi;	//读取的环境湿度

int temp_th;	//设置的温度阈值
int humi_th;	//设置的湿度阈值

_Bool red_led;	//(温度指示灯)

_Bool blue_led;	//(湿度指示灯)

int main()
{
    //手动设置环境温度(模拟上帝)
	temp = 28;	//温度是28度
	humi = 60;	//湿度是60%	
    //手动设置阈值(代替远程)
    temp_th = 30;	//温度阈值是30度
	humi_th = 60;		//湿度阈值是60%
    //小灯初始化
    red_led = 0;
    blue_led = 0;    
    
	while(1)
	{
		
		
	}
	return 0;
}	


(2)然后在while循环里面, 我们就做三件事情

① 设置环境信息阈值(手动输入代替远程控制)

潜台词: (1)当需要设置的时候, 才设置阈值

引申: 所以写代码的时候, 就不能重复赋值了, 当管理员发设置阈值信息的时候, 我们才能 设置阈值

② 读取环境信息 (手动输入代替器件读取)

潜台词: 保证实时性,所以需要一直读取 , 其实也可以隔一段时间(例如100ms)读取一次

③ 每时每刻判断环境信息是否异常

潜台词; (1)为了保证实时性, 拿到阈值和环境信息,就直接判断了

引申风险: 但是如果环境正常还好, 直接跳出了, 但是如果环境异常,

我们是不是就需要启动仪器了. 如果 为了保证实时性, 一直判断异常了就报警, 异常就启动仪器, 那我们是不是就会一直陷入 启动仪器的循环之中?

解决方案: 增加读取仪器状态的信息, 当环境异常的时候. 在启动仪器前, 先看看仪器是否正在运行, 如果在运行, 就不必循环启动了.

if(环境异常)
{
 if(仪器不运行)
 {
     启动应急仪器(开灯演示)
 }
 else
 if(仪器已经在运行了)
 {
     跳过(不操作)
 }
}
Bool set_limit;	//管理员是否设置阈值
set_limit = 1;
while(1)
{
    //(1)设置环境信息阈值(手动输入代替远程控制)
	if(set_limit == 1)
    {
        temp_th = 20;
        humi_th = 30;
        //设置完阈值就清零,下次不设置了, 直到set_limit被管理员置1
        //然后再次进入此功能函数里,进行设置阈值
        set_limit = 0;
    }
    //(2)读取环境信息 (手动输入代替器件读取)
	//if(过了100毫秒) 每隔100毫秒,读取一次, 保证实时性,减轻负担
    if(++timeCount >= 100)
    {
        temp = 26;	//人手输入,代替器件,忽略底层,重视逻辑
        humi = 40;	
    }
    //(3)每时每刻判断环境信息是否异常
    if(temp >= temp_th)
    {
        if(red_led == 0)	//如果是关闭状态则启动,开启则无操作
        {
			red_led = 0;           
        }
    }
    else	//同理,环境正常时候
    {
        if(red_led == 1)	//如果是开启状态则启动,关闭则无操作
        {
			red_led = 0;           
        }        
    }      
    //判断湿度是否报警
    //每时每刻判断环境信息是否异常
    if(humi >= humi_th)
    {
        if(blue_led == 0)	//如果是关闭状态则启动,开启则无操作
        {
			blue_led = 0;           
        }
    }
    else	//同理,环境正常时候
    {
        if(blue_led == 1)	//如果是开启状态则启动,关闭则无操作
        {
			blue_led = 0;           
        }        
    }       
}
(3)小灯初始化, 用小灯代替仪器应急处理

① 先包含 膨胀位处理操作, 方便我们操作led:

右键user, 然后点击Add New item to Group ‘user’…

image-20240731080550953

② 选择Source-> user的目录

image-20240731091626626

③ 点击这个文件夹, 然后确认

image-20240731080748371

④ 然后输入 sys.h , 然后点击Add

image-20240731091708199

⑤ 把下面代码, 直接粘贴上去, 然后ctrl + s保存

image-20240731081014352
#ifndef _SYS_H
#define _SYS_H

//操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第5章 92页 在 C 语言中使用位带操作 或<<CM3与M4权威指南>>第6章6.7.4 P216
//addr&0xF0000000取出最高的四位,其实就是用于区别SRAM(0x20000000)还是片上外设(0x40000000)的。
//+0x2000000对于SRAM位带区则得到 0x22000000,对于片上外设位带区则得到0x42000000?
//(addr&0xFFFFF)等效于(addr&0x000FFFFF),就是屏蔽掉高12位,地址范围是0x20000000-0x200FFFFF和0x40000000-0x400FFFFF
//<<5就等效于乘以32 ,同样<<2等效于乘以4 。
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//GPIO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 
//GPIO口操作,只对单一的GPIO口!确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#endif

⑥ 我们初始化led的函数, 分配PB3 -> 温度报警小灯, 分配 PB4 湿度报警小灯, 分配 PB5 烟雾浓度报警小灯, 我们先用温湿度小灯, 后续再教大家如何演示浓度小灯, 正好方便后续演示拓展用.

大家直接复制黏贴即可, 如需了解,请看stm32基础教程,其实我们这里配置, 也仅仅是为了让大家看现象, 请不要害怕, 请直接复制黏贴

void led_init(void)
{
	//初始化小灯 , PB3(温度) PB4(湿度) PB5(烟雾浓度)
	GPIO_InitTypeDef GPIO_InitStructure;
	//开启硬件时钟	PB5
	/* GPIOD Periph clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	//开启AFIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	//禁用JTAGD端口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);	
   //配置 pB 3 4 5 GPIO工作模式(推挽输出)
	/* Configure PD0 and PD2 in output pushpull mode */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	//配置端口

	//控制端口寄存器GPIO输出电平
	PBout(3) = 0;//temp_led
	PBout(4) = 0;	//humi_led
//	PBout(5) = 0;	//mq2_led	
	
}
(4) 上面的源代码

在main.c里面的main函数, 也要包含一下第(3)步的 #include “sys.h” , 然后 小灯初始化, 也需要调用一下, 其次就是 我们现在比较简单, 所以操作小灯报警的时候, 就直接用PBout膨胀位了, 下面是综合上面的代码后的main.c代码。

main.c

代码:

#include "stm32f10x.h"                  // Device header
#include "sys.h"

int temp;	//读取的环境温度
int humi;	//读取的环境湿度

int temp_th;	//设置的温度阈值
int humi_th;	//设置的湿度阈值

_Bool red_led;	//(温度指示灯)

_Bool blue_led;	//(湿度指示灯)

_Bool set_limit;	//管理员是否设置阈值


//led小灯初始化
void led_init(void);


int main()
{

	unsigned short timeCount = 0;	//发送间隔变量
    //手动设置环境温度(模拟上帝)
	temp = 28;	//温度是28度
	humi = 60;	//湿度是60%	
    //手动设置阈值(代替远程)
    temp_th = 30;	//温度阈值是30度
	humi_th = 60;		//湿度阈值是60%
    //小灯状态初始化
    red_led = 0;
    blue_led = 0;   
	//测试变量: 管理设置阈值符号位
	set_limit = 1;
	//小灯初始化
	led_init();
	
	while(1)
	{
		//(1)设置环境信息阈值(手动输入代替远程控制)
		if(set_limit == 1)
		{
			temp_th = 50;
			humi_th = 2;
			//设置完阈值就清零,下次不设置了, 直到set_limit被管理员置1
			//然后再次进入此功能函数里,进行设置阈值
			set_limit = 0;
		}
		//(2)读取环境信息 (手动输入代替器件读取)
		//if(过了100毫秒) 每隔100毫秒,读取一次, 保证实时性,减轻负担
		if(++timeCount >= 100)
		{
			temp = 20;	//人手输入,代替器件,忽略底层,重视逻辑
			humi = 20;	
			timeCount = 0; 	//从新计时
		}
		//后面跟 1ms的延时, 我们一切从简,先留着
		
		//(3)每时每刻判断环境信息是否异常
		if(temp >= temp_th)
		{
			if(red_led == 0)	//如果是关闭状态则启动,开启则无操作
			{
				red_led = 1;
				PBout(3) = 1;
			}
		}
		else	//同理,环境正常时候
		{
			if(red_led == 1)	//如果是开启状态则启动,关闭则无操作
			{
				red_led = 0;
				PBout(3) = 0;
			}        
		}      
		//判断湿度是否报警
		//每时每刻判断环境信息是否异常
		if(humi >= humi_th)
		{
			if(blue_led == 0)	//如果是关闭状态则启动,开启则无操作
			{
				blue_led = 1; 
				PBout(4) = 1;
			}
		}
		else	//同理,环境正常时候
		{
			if(blue_led == 1)	//如果是开启状态则启动,关闭则无操作
			{
				blue_led = 0;
				PBout(4) = 0;
			}        
		}       
	}	

}

/**************************************************
函数名: led_init
功  能: 温湿度,烟雾浓度小灯初始化
参  数: 无
配置参数: PB3(温度) PB4(湿度) PB5(烟雾浓度)
		  推挽输出
		 小灯正极接io口, 负极接地
返回值: 无
**************************************************/
void led_init(void)
{
	//初始化小灯 , PB3(温度) PB4(湿度) PB5(烟雾浓度)
	GPIO_InitTypeDef GPIO_InitStructure;
	//开启硬件时钟	PB5
	/* GPIOD Periph clock enable */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	//开启AFIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	//禁用JTAGD端口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);	
   //配置 pB 3 4 5 GPIO工作模式(推挽输出)
	/* Configure PD0 and PD2 in output pushpull mode */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);	//配置端口

	//控制端口寄存器GPIO输出电平
	PBout(3) = 0;//temp_led
	PBout(4) = 0;	//humi_led
//	PBout(5) = 0;	//mq2_led	
	
}


sys.h

代码:

#ifndef _SYS_H
#define _SYS_H

//操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第5章 92页 在 C 语言中使用位带操作 或<<CM3与M4权威指南>>第6章6.7.4 P216
//addr&0xF0000000取出最高的四位,其实就是用于区别SRAM(0x20000000)还是片上外设(0x40000000)的。
//+0x2000000对于SRAM位带区则得到 0x22000000,对于片上外设位带区则得到0x42000000?
//(addr&0xFFFFF)等效于(addr&0x000FFFFF),就是屏蔽掉高12位,地址范围是0x20000000-0x200FFFFF和0x40000000-0x400FFFFF
//<<5就等效于乘以32 ,同样<<2等效于乘以4 。
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//GPIO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
 
//GPIO口操作,只对单一的GPIO口!确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#endif

烧录调试:

(1)配置烧录设置

① 插上stlink , 然后按照如下方式连线

连线文字说明

image-20240731094838588

实物说明(最小板和上述图引脚顺序一样,但stLink可能不一样,请对准,并且是下面那一排):

image-20240731095035494

(2)stlink配置方法

①驱动:https://ww0.lanzoul.com/ipWDD261eamb

下载后直接安装

② 然后去小锤子里面进行调整烧录工具, 选择ST-Link Debugger

image-20240731095656730

③ 这样就选中了stLink工具

image-20240731095819625

④ 烧录插上stLink , 然后依次点击 即可烧录

image-20240731100004441

⑤ 如果出错, 请再次检查 上述配置, 或者查看线是否插对插紧

(2)人工调整变量, 查看程序能否正常运行

通过调整 temp与 temp_th, 当temp > temp_th ,查看

红灯是否亮, temp <= temp_th , 红灯是否灭

调整humi与humi_th , 当humi > humi_th, 查看蓝灯是否亮, humi <= humi_th, 蓝灯是否灭

(3)观察现象

红灯报警现象:

温度 > 温度阈值

image-20240731100925783 image-20240731101004486

蓝灯报警现象:

image-20240731101319444 image-20240731101339168

总结反思:

到这里, 其实我们已经算实现了一个小案例了, 其实还有完善的空间,那就是

读取到的数值

是需要真实的器件, 每隔一段时间100ms,然后读取一次环境信息。判断预警的时候, 我们只是简单的判断了是否超过阈值,并且这个阈值还是我们手动输入的, 后续需要优化到wifi.

应急处理措施

比如小灯, 我们通过查看代码,就可以看出,我们写的太多了,

我们完全可以另外建立一个文件, 把温湿度以及温湿度阈值传进去, 然后通过判断, 再进行应急处理措施.

led灯状态优化

比如led灯, 其实它有两个变量, 一个是代表此时灯的状态, 另一个是

控制灯的亮灭, 我们可以通过结构体,来把他们进行组成一个函数, 我们只需要通过传进去小灯的状态即可, 至于小灯后续, 是亮还是灭, 需要更多的优先级判断, 才能决定, 我们不用考虑太多,请看如下示例,后面会进行优化.

image-20240731102538529

传入状态, 至于启不启动器件, 再次在此函数内进行判断, 然后传回状态, 把他们深度绑定, 并且自我消化, 可以减少不必要的麻烦.

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值