51单片机学习笔记-11 DS18B02温度传感器(单总线)

news2024/11/16 10:18:20

11 DS18B02温度传感器

[toc]

注:笔记主要参考B站江科大自化协教学视频“51单片机入门教程-2020版 程序全程纯手打 从零开始入门”。


11.1 温度传感器与单总线通信

11.1.1 DS18B20温度传感器
DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点。

测温范围:-55°C 到 +125°C
通信接口:1-Wire(单总线)
其它特征:可形成总线结构、内置温度报警功能、可寄生供电。

图11-1 DS18B20实物图
图11-2 DS18B20原理图

小知识:
VCC是表示电路的意思,指的是接入电路;
VDD表示器件的意思,指的是器件内部的工作电压;
VSS表示公共连接段的意思,指的是公共接地端电压的意思。

图11-3 DS18B20结构框图
  • 左侧方框为“寄生供电”电路:当VDD无法供电时,DQ会承担起供电的任务,但为保证内部电路正常工作需要DQ强上拉,本次实验不涉及。
  • 中间方框为ROM和单总线接口:ROM中会存放器件地址,用于单总线通信。
  • MEMROY CONTROL LOGIC:相当于“管家”,在进行单总线通信时,将存储在SRATCHPAD(RAM)中的数据放在总线上。
  • SCRATCHPAD(暂存器):本质上是RAM,用于总线的数据交互,存储温度等信息。
  • EEPROM:用于保存温度触发阈值、配置参数(如温度的分辨率)等信息。

注:出厂默认温度分辨率为最高:0.0125℃。

图11-4 DS18B20存储阵列

可见,上面的“暂存器”只包含9个字节的空间:

  • Byte 0&1:存储温度信息。高5位全是符号位,1负0正;其他11位组成数字,注意低4位是小数部分。
  • Byte 2/3:分别存储温度阈值上限及下限;
  • Byte 4:配置寄存器,用于控制温度的分辨率。当然,分辨率越高,温度转换时间越长。
  • Byte 5~6:保留。
  • Byte 7:CRC校验。

通过单总线上的指令,可以实现传感器上的温度信息存入暂存器中,然后再从暂存器将信息通过单总线传输出去。

11.1.2 单总线协议及电路规范
单总线(1-Wire BUS)是由Dallas公司开发的一种通用数据总线。通过一根通信线DQ,实现异步、半双工通信。当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线。但实际上,使用单总线进行通信的器件非常少,实际应用中几乎只有DS18B20比较出名。

设备的DQ均要配置成开漏输出模式(输出1引脚悬空,无驱动能力),所以DQ需要添加一个上拉电阻,阻值一般为4.7KΩ左右。若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路。

图11-5 DS18B20供电示意图

11.1.3 单总线时序结构
本部分将依次介绍:初始化→发送一位→接收一位→发送一个字节→接收一个字节。单总线通信对于时间的把控很重要。

  • 初始化:主机将总线拉低至少480us,然后释放总线,等待15~60us后,存在的从机会拉低总线60~240us以响应主机,之后从机将释放总线。
  • 发送一位:主机将总线拉低60~120us,然后释放总线,表示发送0;主机将总线拉低1~15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us。
  • 接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us。
  • 发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位 (低位在前)
  • 接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位 (低位在前)

11.1.4 单总线数据帧
DS18B20操作流程为:

  1. 初始化:从机复位,主机判断从机是否响应。
  2. ROM操作:ROM指令+本指令需要的读写操作。
  3. 功能操作:功能指令+本指令需要的读写操作。

注:总体思路其实就是先找器件地址(ROM操作),然后执行相应的功能(功能操作)。

下面介绍ROM指令:

  • SEARCH ROM[F0h]: 用于确定挂接在同一总线上 DS1820 的个数和识别 64 位 ROM 地址。为操作各器件作好准备。
  • READ ROM[33h]:读DS1820温度传感器ROM中的编码(即64位地址)
  • MATCH ROM[55h]:发出此命令之后,接着发出 64 位 ROM 编码,访问单总线上与该编码相对应的 DS1820 使之作出响应,为下一步对该 DS1820 的读写作准备。
  • SKIP ROM[CCh]:忽略 64 位 ROM 地址,直接向 DS1820 发温度变换命令。适用于单片工作。
  • ALARM SEARCH[ECh]: 执行后只有温度超过设定值上限或下限的片子才做出响应。

下面介绍功能指令:

  • CONVERT T[44h]:启动DS1820进行温度转换,12位转换时最长为750ms(9位为93.75ms)。结果存入内部第0、1字节RAM中。
  • WRITE SCRATCHPAD[4Eh]:发出向内部RAM的第2、3和4字节写上、下限温度数据命令,紧跟该命令之后,是传送三字节的数据。
  • READ SCRATCHPAD[BEh]:连续读取内部RAM中9个字节的内容
  • COPY SCRATCHPAD[48h]:将RAM中第2、3和4字节字节的内容复制到EEPROM中。
  • RECALL E2[B8h]:将EEPROM中内容恢复到RAM中的第2、3和4字节。
  • READ POWER SUPPLY[B4h]:读DS1820的供电模式。寄生供电时DS1820发送“ 0 ”,外接电源供电 DS1820发送“ 1 ”。

下面是程序中会用到的两个数据帧:

  1. 温度变换:初始化 → 跳过ROM(发送字节0xcc)→ 开始温度变换(发送字节0x44)。作用就是使传感器将当前温度存放在暂存器的前两个字节上。
  2. 温度读取:初始化 → 跳过ROM(发送字节0xcc)→ 读暂存器(发送字节0xbe)→ 连续的读操作(只读取前两个比特)。作用就是去取出温度和阈值上下限。

11.2 实验:DS18B02温度读取

需求:使用DS18B02的最高分辨率,在LCD上显示屏幕上显示温度。LCD第一行显示“Temperature:”,第二行显示温度。
注:由于延时1us时间太短,所以直接调用软件延时函数的误差极大(循环跳转语句的延时可能比演示本身所需的时间更长);而使用定时器又涉及到中断等操作,会使调用逻辑更复杂。所以推荐直接根据延时时间,使用“软件延时函数”中最核心的延迟部分即可,如延时480us。

延时注释:对于12MHz时钟来说

  • _nop()_函数大约延时1us;
  • 进入函数大约延时4us;
  • 进入一次while大概延时2us;
  • 总结:在使用“软件延时计算器”时,如果要延时5us,就要记住进入函数大约4us,所以要截取“延时9us”的核心部分。
图11-6 “DS18B20温度读取”代码调用关系

代码展示:
- main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "_1Wire.h"
#include "DS18B20.h"

void main(){
  float tempe = 10.5;
  //初始化LCD
  LCD_Init();
  LCD_ShowString(1,1,"Temperature:");
  while(1){
    DS18B02_ConvertTemp();// 温度转换
    tempe = DS18B02_ReadTemp();// 温度读取
//    LCD_ShowBinNum(2,1,tempe,16);//显示16位二进制数字
    if(tempe>0){LCD_ShowChar(2,1,'+');}
    else       {LCD_ShowChar(2,1,'-');tempe=-tempe;}
    LCD_ShowNum(2,2,(int)tempe,3);
    LCD_ShowString(2,5,".");
    LCD_ShowNum(2,6,(int)((tempe-(int)tempe)*10000),4);
    LCD_ShowString(2,11,"C");
  }
}

- _1Wire.h

#ifndef __1WIRE_H__
#define __1WIRE_H__

unsigned char _1Wire_Init(void);//初始化
void _1Wire_SendBit(unsigned char sdata);// 发送1位
unsigned char _1Wire_ReceBit(void);// 接收1位
void _1Wire_SendByte(unsigned char sbyte);// 发送一个字节
unsigned char _1Wire_ReceByte(void);// 接收一个字节

#endif

- _1Wire.c

#include <REGX52.H>

// 总线重新命名
sbit _1Wire_DQ = P3^7;

/**
  * @brief :单总线初始化。
  * @param :无
  * @retval :从机是否应答(1/0)。
 */
unsigned char _1Wire_Init(void){
  unsigned char i, ack=0;
  _1Wire_DQ = 1;
  _1Wire_DQ = 0;
  i = 230; while (--i); //延时500us
  _1Wire_DQ = 1;
  i = 36;	while (--i); //延时80us
  if(!_1Wire_DQ){ack = 1;}
  i = 230; while (--i); //延时500us
  return ack;
}

/**
  * @brief :单总线发送一位数据。
  * @param :sdata发送数据,最低位表示要发送的比特
  * @retval :无
 */
void _1Wire_SendBit(unsigned char sdata){// 发送1位
  unsigned char i;
  _1Wire_DQ = 1;
  _1Wire_DQ = 0;
  i = 4; while (--i); // 延时10us
  _1Wire_DQ = sdata;
  i = 23;	while (--i); // 延时50us,等待从机采样完毕
  _1Wire_DQ = 1;
}

/**
  * @brief :单总线接收一位数据。
  * @param :无
  * @retval :rdata接收数据,最低位表示接收的比特
 */
unsigned char _1Wire_ReceBit(void){// 接收1位
  unsigned char i, rdata=0x00;
  _1Wire_DQ = 1;
  _1Wire_DQ = 0;
  i = 2; while (--i); // 延时5us
  _1Wire_DQ = 1;
  i = 4; while (--i);// 延时10us
  if(_1Wire_DQ) rdata = 0x01;
  i = 20;	while (--i); // 延时45us,等待时间片结束
  //此处由从机释放总线
  return rdata;
}

/**
  * @brief :单总线发送一个字节。
  * @param :sbyte发送的字节。
  * @retval :无。
 */
void _1Wire_SendByte(unsigned char sbyte){// 发送一个字节
  unsigned char i;
  for(i=0;i<8;i++){
    _1Wire_SendBit(sbyte&(0x01<<i));//先发低位
  }
}

/**
  * @brief :单总线接收一个字节。
  * @param :无。
  * @retval :rbyte接收的字节。
 */
unsigned char _1Wire_ReceByte(void){// 接收一个字节
  unsigned char i,rbyte = 0x00;
  for(i=0;i<8;i++){
    if(_1Wire_ReceBit()){
      rbyte |= (0x01<<i);//先收低位
    }
  }
  return rbyte;
}

- DS18B20.h

#ifndef __DS18B02_H__
#define __DS18B02_H__

void DS18B02_ConvertTemp(void);// 温度转换
float DS18B02_ReadTemp(void);// 温度读取

#endif

- DS18B20.c

#include "_1Wire.h"

// ROM指令、功能指令
#define SKIP_ROM 0xCC
#define CONVERT_T 0x44
#define READ_SCRATCHPAD 0xBE

/**
  * @brief :将传感器温度值存放到暂存器中。
  * @param :无。
  * @retval :无。
 */
void DS18B02_ConvertTemp(void){// 温度转换
  //1.初始化
  _1Wire_Init();
  //2.跳过ROM
  _1Wire_SendByte(SKIP_ROM);
  //3.开始温度变换
  _1Wire_SendByte(CONVERT_T);
  //4.不必延时等待
}

/**
  * @brief :将暂存器中的温度值读出。
  * @param :无。
  * @retval :返回单精度浮点类的数据。
 */
float DS18B02_ReadTemp(void){// 温度读取
  unsigned char temp_H,temp_L;
  int temperature;
  //1.初始化
  _1Wire_Init();
  //2.跳过ROM
  _1Wire_SendByte(SKIP_ROM);
  //3.读暂存器
  _1Wire_SendByte(READ_SCRATCHPAD);
  //4.读前两个比特
  temp_L = _1Wire_ReceByte();
  temp_H = _1Wire_ReceByte();
  //5.复位,不再读取后续信息
  _1Wire_Init();
  //6.计算读取到的温度信息
  if(temp_H&0xf8){//负数
    temperature = -(~(temp_H*256+temp_L) + 1);
  }else{
    temperature = temp_H*256 + temp_L;
  }
  return (float)(temperature)*0.0625;
}

LCD1602.hLCD1602.c均与之前的实验相同。

11.3 实验:DS18B20温度报警器

需求:LCD第一行的左侧显示当前温度,右侧显示“High!”/“Low!”的温度报警提示(若在范围内则什么都不显示);LCD第二行显示设定的温度范围上下界。并且要求按键功能:

  • key1:将上限温度加一,并存储在AT24C02中;
  • key2:将上限温度减一,并存储在AT24C02中;
  • key3:将下限温度加一,并存储在AT24C02中;
  • key4:将下限温度减一,并存储在AT24C02中;

注:每次上电都自动读取AT24C02的值。初始温度范围设置为15~20摄氏度。
注:本实验相比于上一个实验的难点在于,定时器扫描按键。而不是真的将温度的上下限传输到DS18B20中。
为显示方便,设置温度的上下限范围都在-60~127内,精度为1℃。

图11-7 “DS18B20温度报警器”代码调用关系

代码如下:
- main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "_1Wire.h"
#include "DS18B20.h"
#include "PushKey.h"
#include "Timer0.h"
#include "AT24C02.h"

void main(){
  float tempe = 20.5, tempe_show = 20.5;
  char gate_up=20,gate_bo=15; //默认阈值
  unsigned char key_num=0;
  
  //初始化定时器T0
  Timer0_Init();
  
  //从AT24C02中读取温度数据
//  AT24C02_WriteByte(0x00,125);
//  AT24C02_WriteByte(0x01,-125);//此两句仅供测试使用
  gate_up = AT24C02_ReadByte(0x00);
  gate_bo = AT24C02_ReadByte(0x01);
  if(gate_up<=gate_bo || gate_up>127 || gate_bo<-60){
    gate_up = 20; gate_bo = 15;
  }
  
  //初始化LCD
  LCD_Init();
  LCD_ShowString(1,1,"U:     L:");
  LCD_ShowSignedNum(1,3,(int)gate_up,3);
  LCD_ShowSignedNum(1,10,(int)gate_bo,3);
  
  while(1){
    key_num = PushKey_GetKey();
    if(key_num){
      switch(key_num){
        case 1://温度上限+1
          if(gate_up<127){gate_up++;}
          AT24C02_WriteByte(0x00,gate_up);
          break;
        case 2://温度上限-1
          if(gate_up>-59){gate_up--;}
          if(gate_up<=gate_bo){gate_bo--;}
          AT24C02_WriteByte(0x00,gate_up);
          AT24C02_WriteByte(0x01,gate_bo);
          break;
        case 3://温度下限+1
          if(gate_bo<126){gate_bo++;}
          if(gate_up<=gate_bo){gate_up++;}
          AT24C02_WriteByte(0x00,gate_up);
          AT24C02_WriteByte(0x01,gate_bo);
          break;
        case 4://温度下限-1
          if(gate_bo>-60){gate_bo--;}
          AT24C02_WriteByte(0x01,gate_bo);
          break;
        default:;
      }
      //在显示屏上更新显示阈值
      LCD_ShowSignedNum(1,3,(int)gate_up,3);
      LCD_ShowSignedNum(1,10,(int)gate_bo,3);
    }
    
    DS18B20_ConvertTemp();// 温度转换
    tempe = DS18B20_ReadTemp();// 温度读取
    tempe_show = tempe;
    //阈值判断
    if(tempe>gate_up)     {LCD_ShowString(2,12,"High!");}
    else if(tempe<gate_bo){LCD_ShowString(2,12," Low!");}
    else                  {LCD_ShowString(2,12,"Norm!");}
    //温度显示
    if(tempe>0){LCD_ShowChar(2,1,'+');}
    else       {LCD_ShowChar(2,1,'-');tempe_show=-tempe_show;}
    LCD_ShowNum(2,2,(int)tempe_show,3);
    LCD_ShowString(2,5,".");
    LCD_ShowNum(2,6,(int)((tempe_show-(int)tempe_show)*100),2);
    LCD_ShowString(2,9,"C");
  }
}

// 定义定时器T0中断后要执行的动作
void Timer0_Routine() interrupt 1{
  static unsigned int count_T0; //中断次数
  count_T0++; //更新中断次数
  TH0 = 0xfc; TL0 = 0x66; // 恢复溢出周期,近似1ms
  if(count_T0>20){
    count_T0 = 0;
    PushKey_Loop();
  }  
}

- DS18B20.c只是更改了全局中断的关闭和开启。

#include "_1Wire.h"
#include <REGX52.H>

// ROM指令、功能指令
#define SKIP_ROM 0xCC
#define CONVERT_T 0x44
#define READ_SCRATCHPAD 0xBE

/**
  * @brief :将传感器温度值存放到暂存器中。
  * @param :无。
  * @retval :无。
 */
void DS18B20_ConvertTemp(void){// 温度转换
  EA = 0;
  //1.初始化
  _1Wire_Init();
  //2.跳过ROM
  _1Wire_SendByte(SKIP_ROM);
  //3.开始温度变换
  _1Wire_SendByte(CONVERT_T);
  //4.不必延时等待
  EA = 1;
}

/**
  * @brief :将暂存器中的温度值读出。
  * @param :无。
  * @retval :返回单精度浮点类的数据。
 */
float DS18B20_ReadTemp(void){// 温度读取
  unsigned char temp_H,temp_L;
  int temperature;
  EA = 0;
  //1.初始化
  _1Wire_Init();
  //2.跳过ROM
  _1Wire_SendByte(SKIP_ROM);
  //3.读暂存器
  _1Wire_SendByte(READ_SCRATCHPAD);
  //4.读前两个比特
  temp_L = _1Wire_ReceByte();
  temp_H = _1Wire_ReceByte();
  //5.复位,不再读取后续信息
  _1Wire_Init();
  EA = 1;
  //6.计算读取到的温度信息
  if(temp_H&0xf8){//负数
    temperature = -(~(temp_H*256+temp_L) + 1);
  }else{
    temperature = temp_H*256 + temp_L;
  }
  return (float)(temperature)*0.0625;
}

DS18B20.h_1Wire.h_1Wire.cLCD1602.hLCD1602.c与上一节实验相同;AT24C02.hAT24C02.cPushKey.hTimer0.h、与12-2实验“秒表(定时器扫描按键和数码管)”相同。

编程感想:

  1. 单总线操作会被定时器中断打乱,进而使得温度的显示“闪烁”。那么在单总线上操作时,直接关闭全局中断,单总线传输结束后,再开启全局中断。但注意,这个方法的缺点就是,不能对定时器的中断要求严格(如秒表等应用场景)。
  2. 对单总线的评价:单总线工作时不允许中断,这就很大程度上限制了单总线的应用;而IIC总线只与自己的时钟线有关,所以允许任意时刻的中断,IIC也就应用得更广泛一些。

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

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

相关文章

SAP ADM100-Unit3 系统配置介绍:系统如何评估它的参数

本节将了解系统评估配置文件参数的顺序,并了解这些参数存储的位置。 1、配置profile参数 各个实例和SAP系统都是使用Profile配置文件参数来配置的。这些参数的默认值被定义在内核程序代码中。 可以通过配置文件改变这些参数的默认值,当实例被开启时将读取配置文件中参数值。…

大屏加载速度优化--突破chrome 6个请求线程限制

1. 问题 当大屏中的内容很多时&#xff0c;比如50个以上&#xff0c;整个页面呈现速度会慢很多&#xff0c;影响用户体验。 通过 chrome开发者工具可以看到&#xff0c;默认情况下&#xff0c;chrome仅开启6个请求线程&#xff0c;用于发起ajax请求。 2. 解决方案 改进的方式…

epoll模型要点总结

(图是网上的&#xff0c;懒得自己画了) 1 epoll_ctl是向红黑树rbr插入、删除、修改fd。epoll_wait在双向链表rdllist中查询IO可读、可写、错误事件。 为什么使用红黑树&#xff1f;从插入、删除考虑。 2 epoll_ctl插入新fd时&#xff0c;新建epitem&#xff0c;会设置回调函…

2023年第五届清洁能源与智能电网国际会议(CCESG 2023)

2023年第五届清洁能源与智能电网国际会议&#xff08;CCESG 2023&#xff09; 重要信息 会议网址&#xff1a;www.ccesg.org 会议时间&#xff1a;2023年4月21-23日 召开地点&#xff1a;广西-南宁 截稿时间&#xff1a;2023年2月28日 录用通知&#xff1a;投稿后2周内 收…

结合代谢组学和网络药理学研究康复消炎栓治疗慢性盆腔炎作用机制

文章标题&#xff1a;Integrated Metabolomics and Network Pharmacology Study on the Mechanism of Kangfuxiaoyan Suppository for Treating Chronic Pelvic Inflflammatory Disease 发表期刊&#xff1a;Frontiers in Pharmacology 影响因子&#xff1a;5.988 发表年份&…

读书:《好奇心:保持对未知世界永不停息的热情》

刚看到《好奇心》这本书的书名&#xff0c;我对《好奇心》还是有点好奇心的。 为什么小孩的好奇心比大人多&#xff1f;也不一定&#xff0c;如果家长或老师没有足够好的引导的话&#xff0c;孩子也会对周围的世界没有兴趣。 好奇心为两种&#xff1a;消遣性好奇、认识性好奇…

【go-zero】在微服务架构中是否要使用分布式事务 如何避免分布式的耦合 微服务与分布式事务的对立

微服务要不要引入分布式事务讨论问题&#xff1a;微服务要不要引入分布式事务&#xff1f;1、分布式事务的场景分析2、分析利与弊3、如何优化分布式事务3.1 什么是CAP理论3.2 方式一&#xff1a;避免使用分布式事务1&#xff09;同步阻塞2&#xff09;异步调用3&#xff09;粗粒…

Linux中的Nginx平滑升级与回退

目录 一、平滑升级概述 1.平滑升级的定义 2.平滑升级的思路 &#xff08;1&#xff09;关于版本和备份 &#xff08;2&#xff09;向旧的Nginx的master进程发送USR2信号 &#xff08;3&#xff09;向旧的master进程发送winch信号&#xff0c;旧的worker子进程退出 &…

【疑难杂症】allennlp安装报错:Installing build dependencies ... error

背景&#xff1a; 配置PURE的算法环境&#xff0c;安装allennlp 0.9.0 &#xff08;pip install allennlp0.9.0&#xff09;报错&#xff0c;如图所示&#xff1a; 探索&#xff1a; 发现allennlp的依赖中有spacy&#xff0c;是在安装spacy 2.1.9的依赖时报错了。 此时我尝试…

PCB如何添加SMT定位孔经验总结

&#x1f3e1;《总目录》 目录1&#xff0c; 什么是SMT定位孔2&#xff0c;SMT定位孔有什么特征3&#xff0c;添加SMT定位孔的经验原则4&#xff0c;其他注意事项1&#xff0c; 什么是SMT定位孔 SMT定位孔是指在PCBA的SMT贴片焊接阶段&#xff0c;为了准确固定和定位板卡的机械…

【OpenGL学习】颜色和光照

颜色和光照 一、颜色的物理解释 颜色&#xff08;英语&#xff1a;colour&#xff0c;color&#xff09;又称色彩、色泽&#xff0c;是眼、脑和我们的生活经验对光的颜色类别描述的视觉感知特。这种对颜色的感知来自可见光谱中的电磁辐射对人眼视锥细胞的刺激。颜色是由光反射…

boost搜索引擎

文章目录1.项目介绍2.搜索引擎技术栈和项目环境3.正排索引和倒排索引 - 搜索引擎具体原理4.编写数据去标签和数据清洗模块Parser5.编写建立索引模块Index6.编写搜索引擎模块Searcher7.编写http_server8.效果展示1.项目介绍 Boost官网没有对应的搜索引擎&#xff0c;不方便我们…

04 frameset-iframe【尚硅谷JavaWeb教程】

04 frameset-iframe【尚硅谷JavaWeb教程】 frameset、iframe这个标签基本上已经不用了。 frameset标签 一个大的网页由很多个小的网页组成&#xff0c;会用到frameset。 frameset 表示页面框架&#xff0c;这个标签已经淘汰&#xff0c;了解&#xff0c;不需要掌握。 frame表…

Element ui Avatar头像管理组件 实现当用户没有头像时 以名称最后一个字为头像

el-avatar是一个比较方便的头像管理组件 src控制他的图片展示 <el-avatarclass "avatar":src"item.images" ></el-avatar>样式的话 可以用avatar控制 <style> .avatar{width: 18px;height: 18px;line-height: 18px; } .avatar img{b…

【可解释性机器学习】TextExplainer: 调试黑盒文本分类器

TextExplainer: 调试黑盒文本分类器示例问题&#xff1a;20个新闻组数据集的LSA SVM模型TextExplainer文本解释器的工作原理我们应该相信这个解释吗&#xff1f;让它们犯错吧让它们再次犯错吧自定义TextExplainer: 采样过程自定义TextExplainer&#xff1a;分类器参考资料尽管…

记录每日LeetCode 237.删除链表中的节点 Java实现

题目描述&#xff1a; 有一个单链表的 head&#xff0c;我们想删除它其中的一个节点 node。 给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。 链表的所有值都是 唯一的&#xff0c;并且保证给定的节点 node 不是链表中的最后一个节点。 删除给定的节点。注…

Kotlin之使用DSL构建专有的语法结构

DSL的全称是领域特定语言(Domain Specific Language)&#xff0c;它是编程语言赋予开发者的一种特殊能力&#xff0c;通过它我们可以编写出一些看似脱离其原始语法结构的代码&#xff0c;从而构建出一种专有的特殊结构。 Kotlin也是支持DSL的&#xff0c;并且在Kotlin中实现DSL…

CF——1766C - Hamiltonian Wall

题目链接 1766C - Hamiltonian Wall Rating&#xff1a;1300 题目描述 Sir Monocarp Hamilton is planning to paint his wall. The wall can be represented as a grid, consisting of 2 rows and m columns. Initially, the wall is completely white. Monocarp wants to p…

Leetcode力扣秋招刷题路-0101

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1…

[LeetCode周赛复盘] 第 330 场周赛20230129

[LeetCode周赛复盘] 第 330 场周赛20230129 一、本周周赛总结二、 [Easy] 6337. 统计桌面上的不同数字1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6338. 猴子碰撞的方法数1. 题目描述2. 思路分析3. 代码实现四、[Hard] 6339. 将珠子放入背包中1. 题目描述2. 思路分析3. 代…