参考——温湿度传感器DHT11驱动_STM32

设备:stm32f407ZGT6

环境:FreeRTOS        HAL

        到网上找DHT11的驱动,但是都无法使用。原因是RTOS环境中,由于多线程,使用循环计数阻塞式的delay_us延时函数就没那么准,且不同设备中delay_us的计数值不一样。而DHT11对时序要求得又十分严格,这就会导致读取数据异常,甚至无法读取。

        虽然考虑过使用其他方法达成更精准的微秒级延时,但是对于单总线传输终归小题大做了。于是下面就简单的使用计数值来模拟延时,不需要考虑延时多少微秒,只需要比较高电平持续时间的相对长短。

/**********************************************************************************************************
函数名称:us延时函数,最小延时为1us
输入参数:时间
输出参数:无
**********************************************************************************************************/
void delay_us(unsigned int time)
{unsigned short i = 0;while (time--){i = 8;while (i--);}
}

需要注意的是,下面代码使用的是C++,如果你使用的是C,那么用相应功能的代码替换掉即可。bool类型需要包含stdbool头文件

DHT11.h

        头文件里未被注释的接口,决定了哪些函数需要重点关注

#ifndef DHT11_H
#define DHT11_Hvoid DHT11_Init();
//bool DHT11_Read_Data(float &temp,float &humi);
bool DHT11_Read_Data_Fast_Pro(float &temp, float &humi);//自定义的快速读取函数
#endif//DHT11_H

DHT11.cpp

        里面的这个std_delay_us是用于调试中用的,在void DHT11_Rst()函数里,你把延时换成你自带的即可,这个不需要多精准。

        下面的函数是与时序图直接对应的,连续读取温度时,最好间隔1s以上

        同时说明一下,下面将作为反面例子!!,找了许久才发现是数组越界引发的硬件中断,下面代码忘了对timeBufIndex清零。后面我会发一个简化版

#include "DHT11.h"
#include "cmsis_os2.h"
#include "stm32f4xx_hal.h"#define DHT11_Pin GPIO_PIN_6
#define DHT11_GPIO_Port GPIOE
#define DHT11_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()#define DHT11_Read()  (DHT11_GPIO_Port->IDR & DHT11_Pin) /*HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)*/
#define DHT11_Write(x) HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, (GPIO_PinState) (x))#define DHT11_High() HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_SET)
#define DHT11_Low() HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET)static GPIO_InitTypeDef GPIO_InitStruct = {0};
static uint16_t std_delay_80us=875;//事先测试过
static uint16_t std_delay_50us=566;
static uint16_t time_count;/**动态计算延时,以确保任何情况下都可以得到较为准确的延时*/
void std_delay_us(uint8_t us)
{//   uint16_t count = std_delay_80us * us / 80;//测试得到的uint16_t count =11 * us ;for (uint16_t i = 0; i < count; ++i);
}/**函数*/
void DHT11_Input();
void DHT11_Output();
void DHT11_Rst();void DHT11_Init()
{DHT11_GPIO_CLK_ENABLE();GPIO_InitStruct.Pin = DHT11_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//    GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);DHT11_High();
}void DHT11_Input()
{GPIO_InitStruct.Mode = GPIO_MODE_INPUT;HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
}void DHT11_Output()
{GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);
}void DHT11_Rst()
{DHT11_Output();DHT11_Low();osDelay(25);//根据时序图可知,需要至少拉低18msDHT11_High();std_delay_us(20);//20-40us
}void DHT11_Check()
{DHT11_Input();for (time_count =0;DHT11_Read();++time_count);/* 等待DHT11数据线拉低 */for (time_count =0;!DHT11_Read();++time_count);  /* 等待DHT11数据线拉高 *///持续80usstd_delay_80us = time_count;//获取80us需要的计数值
}//从DHT11读取一个位
//返回值:1/0
uint8_t DHT11_Read_Bit()
{for (time_count =0;DHT11_Read();++time_count);//等待低电平//变低了说明上一次数据位读取结束for (time_count =0;!DHT11_Read();++time_count); //等待变高电平// std_delay_50us = time_count;//测试用的//变高了说明数据位读取开始/**开始读数据*///低电平:26-28us//高电平:70usstd_delay_us(40);// 等待40us,如果延时准确的话if (DHT11_Read())return 1;elsereturn 0;
}//从DHT11读取一个字节
//返回值:读到的数据
uint8_t DHT11_Read_Byte()
{uint8_t dat = 0;for (uint8_t i = 0; i < 8; i++){dat <<= 1;dat |= DHT11_Read_Bit();}return dat;
}//uint16_t timeBuf[40];
//uint8_t timeBufIndex=0;
//uint16_t timeMax=0;
//uint16_t timeMin=10000;
//uint8_t DHT11_Read_Byte_Fast()
//{
//    uint8_t  dat=0;
//    for (uint8_t i = 0; i < 8; i++)
//    {
//        for (time_count =0;DHT11_Read();++time_count);//等待低电平
//        //变低了说明上一次数据位读取结束
//
//        for (time_count =0;!DHT11_Read();++time_count); //等待变高电平
//             // std_delay_50us = time_count;//测试用的
//        //变高了说明数据位读取开始
//
//        /**开始读数据*/
//        //低电平:26-28us   高电平:70us
//        for (time_count =0;DHT11_Read();++time_count);//等待低电平
//        timeBuf[timeBufIndex++]=time_count;
//    //    std_delay_us(30);// 等待40us,如果延时准确的话
//        dat <<= 1;
//        dat |= DHT11_Read();
//    }
//    return dat;
//}uint16_t timeBuf[40];//存储计数值
uint8_t timeBufIndex=0;//存储计数值索引
uint16_t timeMax=0;
uint16_t timeMin=0xFFFF;
void DHT11_Read_Byte_Fast_Pro()
{for (uint8_t i = 0; i < 8; i++){for (time_count =0;DHT11_Read();++time_count);//等待低电平//变低了说明上一次数据位读取结束for (time_count =0;!DHT11_Read();++time_count); //等待变高电平//变高了说明数据位读取开始/**开始读数据*///低电平:26-28us   高电平:70usfor (time_count =0;DHT11_Read();++time_count);//等待低电平timeBuf[timeBufIndex++]=time_count;//存储计数值}
}bool DHT11_Read_Data_Fast_Pro(float &temp, float &humi)
{uint8_t buf[5];DHT11_Rst();DHT11_Check();for (unsigned char & i : buf)//读取40位数据{DHT11_Read_Byte_Fast_Pro();}for (unsigned short i : timeBuf){if(i>timeMax){timeMax=i;}else if(i<timeMin){timeMin=i;}}/**把计数值转为二进制数据*/uint16_t timeMed=(timeMax+timeMin)>>1;//整除2,取中位数uint8_t data;//临时数据bool tempBin;//临时二进制数据for (int i = 0; i < 5; ++i){data=0;//重置for (int j = 0; j < 8; ++j){data<<=1;//比较计数值,读取二进制数据if(timeBuf[i*8+j]>timeMed){tempBin= true;}else{tempBin= false;}data|=tempBin;}buf[i]=data;//存储数据}/**检验**/if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]){humi = (float) (buf[0] + buf[1] * 0.1);temp = (float) (buf[2] + buf[3] * 0.1);return true;}else{return false;}
}//bool DHT11_Read_Data(float &temp, float &humi)
//{
//    uint8_t buf[5];
//    DHT11_Rst();
//    DHT11_Check();
//    for (unsigned char & i : buf)//读取40位数据
//    {
//        i = DHT11_Read_Byte_Fast();
//    }
//
//    for (unsigned short i : timeBuf)
//    {
//        if(i>timeMax)
//        {
//            timeMax=i;
//        }
//        else if(i<timeMin)
//        {
//            timeMin=i;
//        }
//    }
//
//    uint16_t timeMed=(timeMax+timeMin)>>1;
//    uint8_t data;
//    uint8_t tempBin;
//    uint8_t tempBuf[5];
//    for (int i = 0; i < 5; ++i)
//    {
//        data=0;
//        for (int j = 0; j < 8; ++j)
//        {
//            data<<=1;
//            if(timeBuf[i*8+j]>timeMed)
//            {
//                tempBin=1;
//            }
//            else
//            {
//                tempBin=0;
//            }
//            data|=tempBin;
//        }
//        tempBuf[i]=data;
//    }
//
//    //检验
//    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
//    {
//        humi = (float) (buf[0] + buf[1] * 0.1);
//        temp = (float) (buf[2] + buf[3] * 0.1);
//        return true;
//    }
//    else
//    {
//        return false;
//    }
//}

修正版。里面有三个版本,没被注释的是特化版本,其下愈为通用

#include "DHT11.h"
#include "cmsis_os2.h"
#include "delay.h"
#include "stm32f4xx_hal.h"#define DHT11_Pin GPIO_PIN_6
#define DHT11_Pin_Location 6
#define DHT11_GPIO_Port GPIOE
#define DHT11_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
#define DHT11_MAX_DELAY_COUNT 7000//防止卡死#define DHT11_Read() (DHT11_GPIO_Port->IDR & DHT11_Pin) /*HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)*/#define DHT11_High() DHT11_GPIO_Port->ODR |= (0x01 << DHT11_Pin_Location)
#define DHT11_Low() DHT11_GPIO_Port->ODR &= ~(0x01 << DHT11_Pin_Location) /*HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET)*/#define DHT11_IN()                                                  \{                                                               \DHT11_GPIO_Port->MODER &= ~(3 << (2 * DHT11_Pin_Location)); \DHT11_GPIO_Port->MODER |= 0 << 2 * DHT11_Pin_Location;      \}
#define DHT11_OUT()                                                 \{                                                               \DHT11_GPIO_Port->MODER &= ~(3 << (2 * DHT11_Pin_Location)); \DHT11_GPIO_Port->MODER |= 1 << 2 * DHT11_Pin_Location;      \}//static uint16_t std_delay_80us = 875;//事先测试过
//static uint16_t std_delay_50us = 566;/**动态计算延时,以确保任何情况下都可以得到较为准确的延时*/
//void std_delay_us(uint8_t us)
//{
//    //   uint16_t count = std_delay_80us * us / 80;//测试得到的
//    uint16_t count = 11 * us;
//    for (uint16_t i = 0; i < count; ++i)
//        ;
//}
inline void std_delay_25us()
{for (uint16_t i = 0; i < 273; ++i);
}/**函数*/
inline void DHT11_Rst();void DHT11_Init()
{GPIO_InitTypeDef GPIO_InitStruct = {0};DHT11_GPIO_CLK_ENABLE();GPIO_InitStruct.Pin = DHT11_Pin;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;//    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct);DHT11_High();
}inline void DHT11_Rst()
{DHT11_OUT();DHT11_Low();osDelay(30);//根据时序图可知,需要至少拉低18msDHT11_High();std_delay_25us();//20-40us
}inline void DHT11_Check()
{DHT11_IN();while (DHT11_Read());while (!DHT11_Read());
}bool DHT11_Read_Data_Fast_Pro(float &temp, float &humi)
{static uint8_t buf[5];DHT11_Rst();  // 设置输出模式DHT11_Check();// 设置输入模式for (unsigned char & i : buf)// 读取40位数据{uint8_t data=0;for (uint8_t j = 0; j < 8; j++){data<<=1;while (DHT11_Read()) {} // 等待低电平while (!DHT11_Read()) {}// 等待变高电平// 开始读数据uint16_t time_count;for (time_count = 0; DHT11_Read(); ++time_count) {}data|=time_count>>10;// 由于事先已经知道一个为1194,一个为406左右}i = data;// 存储数据}if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]){humi = (buf[0]*10 + buf[1]) / 10.0f;temp = (buf[2]*10 + buf[3] ) / 10.0f;return true;}else{return false;}
}/********************下面为次优级优化********************/全局变量
//static uint8_t timeBuf[40];// 存储计数值
//static uint8_t timeBufIndex = 0;
//
//void DHT11_Read_Byte_Fast_Pro()
//{
//    for (uint8_t i = 0; i < 8; i++)
//    {
//        while (DHT11_Read()) {} // 等待低电平
//        while (!DHT11_Read()) {}// 等待变高电平
//
//        // 开始读数据
//        uint16_t time_count;
//        for (time_count = 0; DHT11_Read(); ++time_count) {}
//        timeBuf[timeBufIndex++] = time_count>>4;// 存储计数值,由于事先已经知道一个为875,一个为275左右,所以除以16
//    }
//}
//
//bool DHT11_Read_Data_Fast_Pro(float &temp, float &humi)
//{
//    static uint8_t buf[5];
//
//    DHT11_Rst();  // 设置输出模式
//    DHT11_Check();// 设置输入模式
//
//    timeBufIndex = 0;          // 重置计数值索引
//    for (unsigned char &i: buf)// 读取40位数据
//    {
//        DHT11_Read_Byte_Fast_Pro();
//    }
//
//    uint16_t timeMax = 0;
//    uint16_t timeMin = 0xFFFF;
//    for (unsigned short i: timeBuf)
//    {
//        if (i > timeMax) timeMax = i;
//        if (i < timeMin) timeMin = i;
//    }
//
//    uint16_t timeMed = (timeMax + timeMin) >> 1;// 取中位数
//    for (uint8_t i = 0; i < 5; ++i)
//    {
//        uint8_t data = 0;
//        for (uint8_t j = 0; j < 8; j++)
//        {
//            data <<= 1;
//            data |= (timeBuf[i * 8 + j] > timeMed);
//        }
//        buf[i] = data;// 存储数据
//    }
//
//    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
//    {
//        humi = (buf[0]*10 + buf[1]) / 10.0f;
//        temp = (buf[2]*10 + buf[3] ) / 10.0f;
//        return true;
//    }
//    else
//    {
//        return false;
//    }
//}//
//static uint16_t timeBuf[40];//存储计数值
//static uint8_t timeBufIndex = 0;
//void DHT11_Read_Byte_Fast_Pro()
//{
//    for (uint8_t i = 0; i < 8; i++)
//    {
//        while (DHT11_Read())
//            ;//等待低电平
//        //变低了说明上一次数据位读取结束
//
//        while (!DHT11_Read())
//            ;//等待变高电平
//        //变高了说明数据位读取开始
//
//        /**开始读数据*/
//        //低电平:26-28us   高电平:70us
//        uint16_t time_count;
//        for (time_count = 0; DHT11_Read(); ++time_count)
//            ;                                //等待低电平
//        timeBuf[timeBufIndex++] = time_count;//存储计数值//存储计数值
//    }
//}
//
//
//bool DHT11_Read_Data_Fast_Pro(float &temp, float &humi)
//{
//    static uint8_t buf[5];
//
//    DHT11_Rst();               //在里面设置了输出模式
//    DHT11_Check();             //在里面设置了输入模式
//                               //  return false;//如果超时,则退出
//    timeBufIndex = 0;          //存储计数值索引
//    for (unsigned char &i: buf)//读取40位数据
//    {
//        DHT11_Read_Byte_Fast_Pro();
//    }
//
//    uint16_t timeMax = 0;
//    uint16_t timeMin = 0xFFFF;
//    for (unsigned short i: timeBuf)
//    {
//        if (i > timeMax)
//        {
//            timeMax = i;
//        }
//        else if(i<timeMin)
//        {
//            timeMin = i;
//        }
//    }
//
//    /**把计数值转为二进制数据*/
//    uint8_t data;                                     //临时数据
//    uint16_t timeMed = (timeMax + timeMin) >> 1;//整除2,取中位数
//    bool tempBin;
//    for (uint8_t i = 0; i < 5; ++i)
//    {
//        data = 0;
//        for (uint8_t j = 0; j < 8; j++)
//        {
//            data <<= 1;
//            //比较计数值,读取二进制数据
//            if (timeBuf[i * 8 + j] > timeMed)
//            {
//                tempBin = true;
//            }
//            else
//            {
//                tempBin = false;
//            }
//            data |= tempBin;
//        }
//        buf[i] = data;//存储数据
//    }
//
//    /**检验**/
//    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
//    {
//        humi = (float) (buf[0] + buf[1] * 0.1);
//        temp = (float) (buf[2] + buf[3] * 0.1);
//        return true;
//    }
//    else
//    {
//        return false;
//    }
//}/********************下面为原版优化********************/
//static uint16_t timeBuf[40];//存储计数值
//
//void DHT11_Read_Byte_Fast_Pro()
//{
//    static uint8_t timeBufIndex = 0;//存储计数值索引
//    for (uint8_t i = 0; i < 8; i++)
//    {
//        while (DHT11_Read())
//            ;//等待低电平
//        //变低了说明上一次数据位读取结束
//
//        while (!DHT11_Read())
//            ;//等待变高电平
//        //变高了说明数据位读取开始
//
//        /**开始读数据*/
//        //低电平:26-28us   高电平:70us
//        uint16_t time_count;
//        for (time_count = 0; DHT11_Read(); ++time_count)
//            ;                                //等待低电平
//        timeBuf[timeBufIndex++] = time_count;//存储计数值
//    }
//}
//
//
//bool DHT11_Read_Data_Fast_Pro(float &temp, float &humi)
//{
//    static uint8_t buf[5];
//    static uint16_t timeMax = 0;
//    static uint16_t timeMin = 0xFFFF;
//
//    DHT11_Rst();               //在里面设置了输出模式
//    DHT11_Check();             //在里面设置了输入模式
//                               //  return false;//如果超时,则退出
//    for (unsigned char &i: buf)//读取40位数据
//    {
//        DHT11_Read_Byte_Fast_Pro();
//    }
//
//    for (unsigned short i: timeBuf)
//    {
//        if (i > timeMax)
//        {
//            timeMax = i;
//        }
//        else
//        {
//            timeMin = i;
//        }
//    }
//    std_delay_25us();
//    std_delay_25us();
//    DHT11_OUT();
//    DHT11_High();
//
//
//    /**把计数值转为二进制数据*/
//    uint16_t timeMed = (timeMax + timeMin) >> 1;//整除2,取中位数
//    uint8_t data;                               //临时数据
//    bool tempBin;                               //临时二进制数据
//    for (int i = 0; i < 5; ++i)
//    {
//        data = 0;//重置
//        for (int j = 0; j < 8; ++j)
//        {
//            data <<= 1;
//            //比较计数值,读取二进制数据
//            if (timeBuf[i * 8 + j] > timeMed)
//            {
//                tempBin = true;
//            }
//            else
//            {
//                tempBin = false;
//            }
//            data |= tempBin;
//        }
//        buf[i] = data;//存储数据
//    }
//
//    /**检验**/
//    if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])
//    {
//        humi = (float) (buf[0] + buf[1] * 0.1);
//        temp = (float) (buf[2] + buf[3] * 0.1);
//        return true;
//    }
//    else
//    {
//        return false;
//    }
//}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847855.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端的提升是什么?

1、提升 用来描述变量和函数移动到其(全局或函数)作用域顶部的术语。 2、执行上下文 执行上下文是指当前正在执行的“代码环境”&#xff0c;有两个阶段编译和执行。 &#xff08;1&#xff09;编译&#xff1a;在此阶段&#xff0c;JS 引荐获取所有函数声明并将其提升到其…

掌握 Python3 函数高级用法:详解与应用

Python3 函数是构建模块化代码的基本单位&#xff0c;允许我们将代码组织成独立的、可重用的块。除了基本用法&#xff0c;Python3 还提供了许多高级用法&#xff0c;使得函数的使用更加灵活和强大。本文将详细介绍 Python3 函数的高级用法、高级语法、常用命令、示例、应用场景…

Spring使用事务的两种方式

1. 为什么需要事务&#xff1f; 前面的博客 对MySQL事务作讲解&#xff0c;事务就是将⼀组操作封装成⼀个执⾏单元&#xff08;封装到⼀起&#xff09;&#xff0c;要么全部成功&#xff0c;要么全部失败。 比如&#xff0c;现在要实现转账操作&#xff1a; 第一步&#xff…

IDEA 开发中一些好用的插件

CodeGlance&#xff1a;这是一款侧边小面板插件&#xff0c;显示代码概览&#xff0c;方便快速浏览文件结构。 Live Templates&#xff1a;用于创建预定义代码片段&#xff0c;提高输入效率&#xff0c;比如常见的方法、变量名模板。 Git Integration&#xff1a;深度集成 Gi…

CentOS 7基础操作09_Linux查看及检索文件

1、查看文件内容 对于一个文本格式的配置文件&#xff0c;可以利用不同的查看方式来获知文件内容&#xff0c;如直接显示整个文件内容.分页查看文件内容&#xff0c;或者只查看文件开头或末尾的部分内容。在Linux操作系统中&#xff0c;分别由不同的命令来实现这些操作. 1.1、…

两张图片进行分析

两张图片进行分析&#xff0c;可以拖动左边图片进行放大、缩小查看图片差异 底图 <template><div class"box_container"><section><div class"" v-for"item in imgData.imgDataVal" :key"item.id"><img :s…

电商运营-2024年6月1日

作为一名电商运营&#xff0c;针对淘工厂平台&#xff0c;需要具备以下核心技能和素质&#xff1a; 核心技能 新店入驻与产品管理 熟练掌握淘工厂平台的新店入驻流程&#xff0c;包括资质准备、资料提交、审核跟进等。精通产品上架技巧&#xff0c;确保产品信息准确、图片清晰…

「vue」vue + nodejs实现防伪码业务逻辑

防伪码业务逻辑的实现涉及到前端的用户界面设计和后端的数据处理。Vue.js 是一个用于构建用户界面的渐进式JavaScript框架,而Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,常用于服务器端的开发。结合 Vue.js 和 Node.js,你可以创建一个完整的防伪码系统。 1. …

Mybatis02-CRUD操作及配置解析

1、CRUD 1.namespace namespace中的包名要和Dao/Mapper 接口的包名一致&#xff01; 1个Dao接口类对应1个mapper&#xff0c;也对应1个namespace&#xff0c; 1个Dao接口中的方法对应1个namespace中一个SQL语句 2.CRUD id&#xff1a;对应的namespace接口中的方法名resul…

Spring AI 第二讲 之 Chat Model API 第七节Mistral AI Chat

Spring AI 支持来自 Mistral AI 的各种 AI 语言模型。您可以与 Mistral AI 语言模型互动&#xff0c;并基于 Mistral 模型创建多语言对话助手。 先决条件 要访问 Mistral AI 语言模型&#xff0c;您需要与 MistralAI 创建一个 API。在 MistralAI 注册页面创建账户&#xff0c…

html+CSS+js部分基础运用14

熟悉插值{{}}的用法&#xff0c;在页面中显示下列内容。图1 插值语法的效果图 在页面中统计鼠标单机按钮的次数。【提示&#xff1a;v-on指令】&#xff0c;页面效果如下图所示&#xff1a;图2 统计效果图 3、①单击按钮可以修改黑体字。②通过调试工具vue-devtools修改黑体字。…

uni-app:利用Vue的原型对象Vue.prototype设置全局方法及其引用

一、在main.js中设置方法checkPermission绑定到Vue.prototype 核心代码 Vue.prototype.$checkPermission function(username) {console.log(Checking permission for:, username); }; 完整代码 import App from ./App// 添加 checkPermission 方法到 Vue.prototype 上,检查…

服务器数据恢复—服务器raid5上层zfs文件系统数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台某品牌X3650M3服务器&#xff0c;服务器中有一组raid5磁盘阵列&#xff0c;上层采用zfs文件系统。 服务器未知原因崩溃&#xff0c;工作人员排查故障后发现服务器的raid5阵列中有两块硬盘离线导致该阵列不可用&#xff0c;服务器内…

Vue3-toRaw 与 markRaw

toRaw 作用&#xff1a;用于获取一个响应式对象的原始对象&#xff0c; toRaw 返回的对象不再是响应式的&#xff0c;不会触发视图更新。 官网描述&#xff1a;这是一个可以用于临时读取而不引起代理访问/跟踪开销&#xff0c;或是写入而不触发更改的特殊方法。不建议保存对原始…

Web3.0区块链技术开发方案丨ICO与IDO代币开发

在Web3.0时代的到来下&#xff0c;区块链技术不仅改变着金融领域的格局&#xff0c;也在资金筹集和代币发行方面掀起了一场变革。初始代币发行&#xff08;ICO&#xff09;和去中心化代币发行&#xff08;IDO&#xff09;成为了项目融资的主要方式&#xff0c;其基于区块链技术…

电脑开机之后要很久才能进入系统?进入WinPE也是卡顿半天?

前言 小白最近接到了一张很奇怪的电脑维修单&#xff0c;客户说他的工作室电脑开机特别慢&#xff0c;开机之后特别卡顿&#xff0c;在使用的时候也会一卡一卡的。 这事情开始看很简单&#xff1a;估计就是电脑还是机械硬盘&#xff0c;所以开机很慢又卡顿。所以应该是把机械…

reset database to incarnation rman 恢复最早的全备方法

核心 reset database to incarnation 7; restore database until time "to_date(2024-06-01 20:24:16, yyyy-mm-dd:hh24:mi:ss)" preview summary; restore database until time "to_date(2024-06-01 22:24:16, yyyy-mm-dd:hh24:mi:ss)" preview summary; …

微服务架构解密

目录 引言微服务架构简介 定义特点微服务架构的优势 灵活性与可扩展性独立部署与技术多样性故障隔离细粒度的扩展微服务架构的挑战 服务间通信数据一致性服务发现与负载均衡运维复杂性微服务与传统架构的对比 单体架构SOA架构实施微服务架构的最佳实践 持续集成与持续部署(CI/…

LSDFi协议赛道4大稳定币项目,以bitget钱包为例

纵览 LSDfi 生态繁荣的基石&#xff0c;LSD 稳定币赛道全解析 近期有许多建立在流动性质押通证的稳定币借贷协议开始出现在大众眼里&#xff0c;今天文章就要带大家来一一了解这些 LSDfi 协议究竟是如何争夺这块诱人的大饼。 LybraFinanceLSD 它透过抵押stETH/ETH 铸造&#…

MySQL经典练习50题(上)(解析版)

所有笔记、生活分享首发于个人博客 想要获得最佳的阅读体验&#xff08;无广告且清爽&#xff09;&#xff0c;请访问本篇笔记 MySQL经典练习50题&#xff08;上&#xff09; 创建数据库和表 -- 建 表 -- 学 生 表 CREATE TABLE Student( s_id VARCHAR(20), s_name VARCHAR(2…