电子商务网站建设与维护实训报告,哈尔滨网站设计公司地址,如何设立官方网站,淄博网站建设yx718预警器件控制思考
最小示例思想
当读取到环境信息与环境阈值的时候, 我们预警系统就要根据这些信息做出判断,是否要启动器件。 最简单的就是#xff0c; 举温度temp的例子, temp(温度)与temp_th(阈值), 通过判断, 得出是否要启动器件. 如果在一段时间内, 一直是环境异常, 我…预警器件控制思考
最小示例思想
当读取到环境信息与环境阈值的时候, 我们预警系统就要根据这些信息做出判断,是否要启动器件。 最简单的就是 举温度temp的例子, temp(温度)与temp_th(阈值), 通过判断, 得出是否要启动器件. 如果在一段时间内, 一直是环境异常, 我们那只需要启动一次器件就可以了, 按照上面的方法, 就会一直重复启动器件. 所以我们在启动器件前, 需要判断一下, 器件的状态, 如果要切换状态的话, 那么我们就操作硬件. (1)当temp temp_th 时, 当环境刚异常, 并且器件没有启动的时候, 此时我们判断出此状态, 那么我们就启动硬件.
那下一次判断的时候, 环境仍然异常, 但是器件刚才已经启动了, 那么通过判断, 我们就不用启动了.
(2)当temp temp_th 时, 当环境刚恢复正常时, 并且器件启动的时候, 此时我们判断出此状态, 那么我们就可以关闭硬件了.
那下一次判断的时候, 环境仍然正常, 但是器件刚才已经关闭了, 那么通过判断, 我们就不用重复关闭了.
(3) 所以, 当我们要切换器件状态的时候, 我们首先判断器件当前的状态是否和我们所需一致, 如果一致, 那么我们就不进行切换即可.
(4)最小例程的代码, 是用 red_led 和 blue_led 来存储温湿度应急器件的状态的, 并且这个标志位是和器件io口绑定状态, 我们在操作io口后,我们都要更新这个状态。只是为了避免频繁操作器件我们在判断预警操作器件的时候都需要判断当前器件状态是否已经符合 如果符合那么就不操作。我们这里功能不是太复杂所以就用这种方法来实现。
后续如果加入操作系统的思想的话尤其是硬件的操作需要多级容错判断来保证绝对的安全这里只做简单分析。 器件状态绑定
我们通过观察发现 red_led和 PBout(3)深度绑定, 所以直接新建一个文件, 然后新建一个结构体, 来保存器件的状态, 操作器件开关.
我们先观察下面示例, 然后分析学习, 构建我们的工程: (1)观察, 这个函数,是操作器件的, 然后每次操作的时候, 都会传入一个status, 就是我们所需的状态,
但是 传入状态并不代表着我们就要频繁操作io口, 因为在一段时间内环境一直异常,我们100ms钟检测一次,当我们检测到异常, 我们就启动器件, 因为要保证预警系统的实时性, 所以下一个100ms检测的时候, 器件已经运行了,我们就无需重复启动了. 所以当我们传入状态后, 想开器件, 就判断一下器件是否已经启动, 如果启动, 就说明在上一个100ms的时候, 就已经启动了,我们这次进入只是为了保证实时性, 从而重复确认.
同理, 关闭器件也一样, 如果我们检测到 环境 从 异常-正常后,
我们就关闭器件,操作io口前, 也同样判断一下, 器件是否已经处于关闭状态, 如果关闭,则无需操作. (注意我们上图运用的是结构体变量, 其函数状态和io口状态深度绑定, 所以通过判断变量,就可以判断出我们所处的状态,从而操作io口) 代码实操:
在加dht11和oled最小例程的基础上,手把手改写代码, 加思路导向
改前的工程: https://ww0.lanzoul.com/i1jH22680p3a 修改完预警的工程: https://ww0.lanzoul.com/ihhjp26avqub 失效联系qq:2958360390 回复关键词 最小例程系统预警系统构建
(1) 我们解压打开改之前的工程 (2)然后去锁定预警处理部分的代码
会发现, 我们这里是直接在main函数里面访问temp和humi的, 直接做出预警判断 (3)并且, 和上述说的一样, red_led和 PBout(3) 并没有深度绑定, 所以我们先去 构建一下, 操作器件的函数, 我们构建两个文件一个是temp预警器件, 一个是 humi预警器件。
首先还和之前一样, 在品字哪里, 新建一个alarm的文件夹, 来存放预警器件的文件, 然后再去add, 逐个创建文件, 我们起名, temp_led.c 和 temp_led.h , humi_led.c和 humi_led.h吧。
详细步骤(为了避免篇幅过长) https://blog.csdn.net/qq_57484399/article/details/140862473 (4)如下图,我们先做temp_led.c的预警, 这里我们不谈c语言格式, 只谈随心写代码, 甚至我们可以用中文来代替, 至于格式问题, 是编译器和al的事情, 我们只谈逻辑. (5)先看之前原始的预警的时候, 操作器件的时候, 是怎么操作的 我们是先判断状态, 让着当状态切换的时候, 我们才操作器件. 但是这些好像和我们用户没什么关系, 我们用户, 只是想, 在报警的时候, 你操作器件就行了, 至于启动不启动器件, 是我们底层控制启动器件的代码通过判断, 才做的事情, 所以, 我们此处进行替换. (6)至于启动不启动器件, 是函数内部通过判断器件是否处于运行状态, 才操作io口的.我们这里复制 temp_led_Set, 然后直接跳转temp_led.c函数 (7)看到这个是传入的状态, 所以我们还得给led_red绑定一个结构体状态, 通过调用判断这个状态, 再确定是否需要操作io口,
我们去temp_led.h去定义状态结构体 #define red_led_ON 1#define red_led_OFF 0typedef struct
{_Bool red_led_Status;} TEMP_ALARM_INFO;(8)定义完, 之后, 去temp_led.c里面去创建一个temp_alarm_info的变量, 然后 再去构造函数. 相当于定一个了一个状态了 TEMP_ALARM_INFO temp_info {0};(9) 然后我们接着构造控制函数
传入的状态, 我们修改为 _Bool status
void temp_led_Set(_Bool status)
{}(10)还是根据流程图所示, 我们传入的状态, 就是我们想要的状态, 目前如果 机器是此状态, 我们就跳过不操作io口, 相当于我们切换状态的时候, 我们才操作io口 (11)直接上代码, 如果需要开预警设备, 并且当前状态不是开,则操作io口
如果需要关应急设备, 并且当前状态不是关,则操作io口.
(为什么要判断切换状态呢? 因为我们并不能确保这是 第一次从正常-应急, 或者从应急-预警, 第一次操作,当然可以直接操作io口, 因为在一段时间内, 我们只需要操作一次io口,就行了, 但是为了保证实时性, 我们会一直操作判断器件状态, 从而达到实时性, 后续我们采用操作系统思想解决, 我们这里比较简单粗暴.) 下面我把完善的代码奉上, 请直接复制黏贴即可
temp_led.c//单片机头文件
#include stm32f10x.h#include temp_led.h
#include sys.hTEMP_ALARM_INFO temp_info {0};void temp_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_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 } void temp_led_Set(_Bool status)
{if(status red_led_ON temp_info.red_led_Status ! red_led_ON) {//操作小灯开PBout(3) 1;//temp_led//状态设置为开temp_info.red_led_Status status;}elseif(status red_led_OFF temp_info.red_led_Status ! red_led_OFF){//操作小灯关PBout(3) 0;//temp_led//状态设置为关temp_info.red_led_Status status;}
}
temp_led.h#ifndef _TEMP_LED_H_
#define _TEMP_LED_H_#define red_led_ON 1#define red_led_OFF 0typedef struct
{_Bool red_led_Status;} TEMP_ALARM_INFO;extern TEMP_ALARM_INFO temp_info;void temp_led_Init(void);
void temp_led_Set(_Bool status);#endif
humi_led.c//单片机头文件
#include stm32f10x.h#include humi_led.h
#include sys.hHUMI_ALARM_INFO humi_info {0};void humi_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_4;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_Init(GPIOB, GPIO_InitStructure); //配置端口//控制端口寄存器GPIO输出电平PBout(4) 0;//humi_led } void humi_led_Set(_Bool status)
{if(status blue_led_ON humi_info.blue_led_Status ! blue_led_ON) {//操作小灯开PBout(4) 1;//blue_led//状态设置为开humi_info.blue_led_Status status;}elseif(status blue_led_OFF humi_info.blue_led_Status ! blue_led_OFF){//操作小灯关PBout(4) 0;//blue_led//状态设置为关humi_info.blue_led_Status status;}
}
humi_led.h#ifndef _HUMI_LED_H_
#define _HUMI_LED_H_#define blue_led_ON 1#define blue_led_OFF 0typedef struct
{_Bool blue_led_Status;} HUMI_ALARM_INFO;extern HUMI_ALARM_INFO humi_info;void humi_led_Init(void);
void humi_led_Set(_Bool status);#endif
main.c#include stm32f10x.h // Device header
#include sys.h
#include delay.h
#include dht11.h
#include OLED.h#include humi_led.h
#include temp_led.huint8_t temp; //读取的环境温度
uint8_t humi; //读取的环境湿度uint8_t temp_th; //设置的温度阈值
uint8_t humi_th; //设置的湿度阈值_Bool red_led; //(温度指示灯)_Bool blue_led; //(湿度指示灯)_Bool set_limit; //管理员是否设置阈值led小灯初始化
//void led_init(void);int main()
{unsigned short timeCount 0; //发送间隔变量//手动设置环境温度(模拟上帝)temp 66; //温度是28度humi 60; //湿度是60% //手动设置阈值(代替远程)temp_th 30; //温度阈值是30度humi_th 60; //湿度阈值是60%//小灯状态初始化red_led 0;blue_led 0; //测试变量: 管理设置阈值符号位set_limit 1;
// //小灯初始化
// led_init();//滴答定时器Delay_Init();//dht11初始化DHT11_Init();
// while(DHT11_Init())
// {printf(DHT11 Error \r\n);
// OLED_ShowString(0,48, DHT11 Error, 8);
// OLED_Update();
// DelayMs(2000);
// }//oled初始化OLED_Init();humi_led_Init();temp_led_Init();while(1){//(1)设置环境信息阈值(手动输入代替远程控制)if(set_limit 1){temp_th 29;humi_th 88;//设置完阈值就清零,下次不设置了, 直到set_limit被管理员置1//然后再次进入此功能函数里,进行设置阈值set_limit 0;}//(2)读取环境信息 (手动输入代替器件读取)//if(过了100毫秒) 每隔100毫秒,读取一次, 保证实时性,减轻负担if(timeCount 10){DHT11_Read_Data(temp,humi);
// temp 99; //人手输入,代替器件,忽略底层,重视逻辑
// humi 99; OLED_Clear();OLED_ShowChinese(0, 0, 温度);OLED_ShowChinese(0, 24, 湿度);OLED_Printf(48,0,OLED_8X16,%2d,temp);OLED_Printf(48,24,OLED_8X16,%2d,humi); OLED_ShowChinese(80,0 , ℃);OLED_ShowChinese(80,24 , ); OLED_Update();timeCount 0; //从新计时 }DelayXms(10); //10*10 100ms//后面跟 1ms的延时, 我们一切从简,先留着//(3)每时每刻判断环境信息是否异常if(temp temp_th){//启动器件temp_led_Set(red_led_ON);}else //同理,环境正常时候{ temp_led_Set(red_led_OFF);} //判断湿度是否报警//每时每刻判断环境信息是否异常if(humi humi_th){humi_led_Set(blue_led_ON);// if(blue_led 0) //如果是关闭状态则启动,开启则无操作
// {
// blue_led 1;
// PBout(4) 1;
// }}else //同理,环境正常时候{humi_led_Set(blue_led_OFF);
// 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_ledPBout(5) 0; //mq2_led
//
//}