当前位置: 首页 > news >正文

【单片机】17-温度传感器DS18B20

1.DS18B20相关背景知识

1.温度传感器

(1)测温度的方式:物理(汞柱,气压),电子(金属电性能随温度变化)

(2)早期:热敏电阻(模拟接口---》A/D转换

(3)现代:专用sensor(数字接口,如I2C,DS18B20单总线接口等)

2.DS18B20的基本特征

DS18B20可编程分辨率单总线温度传感器

(1)内置集成ADC,外部数字接口

(2)单总线数字接口,布线成本低【单根数据线进行传输】---》串口【一根线】

(3)温度范围宽,精度率高(相对)---》内部的精确度可以调节

(4)数字值温度分辨率位数可软件设置---》内部的A/D转换器【位数越多,精度越高】

(5)温度阈值报警功能,且阈值(TH和TL)可内置存储掉电不丢失(使用EEPROM)

(6)温度采集速度快(750ms)---》CPU下命令进行A/D转换,然后通过数据总线将数据传输出去。

(7)内置唯一64位的序列码,CPU可以单线串联无限多个DS18B20

(8)支持VDD供电,或通过数据总线(DQ)及内部电容实现寄生电源供电【使用DQ供电】--------》如果使用DQ供电,则表示DQ要一直为高电平(1),如果DQ为低电平(0),则与GND两者都是低电平,无法供电。实际上在DS18B20内部还有一个电容,当DQ为1的时候,会一边供电,一边给电容充电;当DQ为低电平的时候,电容会放电供DS18B20使用。使用我们平常都将DQ置为高电平(1)防止出现两根线都为低电平。

(9)没有CLK,所以是异步通信

3.综合评价

(1)DS18B20是很多年前的东西

(2)现在趋向于温度+湿度的综合传感器

(3)现实应用一般低端用热敏电阻【单片机中有A/D+热敏电阻即可】,热点偶,高端用精度传感器

(4)学习难点是单总线协议的时序编程实现

2.原理图

1.原理图确认

2.实体图确认

3.接线确认

注意不要接反了,否则很容易烧坏

3.数据手册

ds18b20数据手册-中文版-140407 - 豆丁网

https://atta.szlcsc.com/upload/public/pdf/source/20230321/E2B7C84673F98AE08C6B0E4EDF67430D.pdf

1.基本性能

2.结构框图

3.测温操作

4.报警操作信号

5.6 4 位 只 读 存 储 器

7.存储器

8.温度寄存器

3.单总线系统

1.“多点”VS“单点”

单总线系统采用一个单总线控制器(CPU)来控制一个活多个从机。DS18B20总是充当从机。

当只有一个从机挂在总 线上时,系统被称为“单点”系统;

如果由多个从机挂在总线上,系统被称为“多点”系统。

2.字节从低位开始读

所有的数据和指令的传递都是从最低有效位开始通过单总线的。

关于单总线系统分三个方面讨论:硬件结构、执行序列和单总线信号(信号类型和时序)。

3.硬件结构

单总线硬件连接要求:

(1)漏极开路式+5K欧姆是上拉电阻

(2)总线低电平超过480us,从设备(DS18B20)将被复位

4.单总线协议标准执行步骤

(1)主机必须按照单总线协议设定好的完整序列和DS18B20通信,每一个回合包含3个步骤:

初始化+ROM操作指令+功能操作指令

顺序不能错也不能省略任何一个。

1.初始化

通过单总线的所有执行操作都从一个初始化程序序列开始。初始化序列包含一个由总线控制器发出的复位脉冲(将总线拉低超过480us)和 其后由从机发出的存在脉冲(回复主设备)。存在脉冲让总线控制器知道DS18B20在总线上且已经准备好操作。

初始化:就是主设备线拉低数据总线超过480us以发出一个复位脉冲,然后从设备DS18B20收到复位脉冲后内部进行硬件复位,复位完成后回复主设备一个存在脉冲,主设备接收到存在脉冲后就认为从设备已经准备好,初始化完成。

复 位 序 列 : 复 位 和 存 在 脉 冲

2.ROM指令

3.功能指令

4.读 / 写 时 序

1. 写时序--CPU控制

(1)DS18B20有两种写时序:写1时序和写0时序。总线控制器通过写1时序来写逻辑1;通过写0时序来写逻辑0。

写 时序必须最少持续60us,包括两个写周期之间至少1us的恢复时间。【无法连续读】

当总线控制器把数据线从逻辑高电平拉低到低电 平的时候,写时序开始。

(2)总线控制器要写产生一个写时序,必须把数据线拉到低电平然后释放,且需在15us内释放总线。当总线被释放【变为高电平】后, 上拉电阻将总线拉高。总线控制器要生成写0时序,必须把数据线拉到低电平且继续保持至少60us。

(3)总线控制器初始化写时序后,DS18B20在一个15us到60us的窗口内对信号线进行采用【DS18B20将数据接收走--》采样时间不固定】。如果线上是高电平,就 是写1。反之,如果线上是低电平,就是写0。

1. 写“0”

2. 写“1”

3.官方代码实现

//在开始之前数据总线是释放的【高电平】
//所以在调用这个函数之前要确保数据总线状态为1
void Ds18b20WriteByte(unsigned char dat)
{unsigned int i = 0, j = 0;for (j=0; j<8; j++){DSPORT= 0;	     	  	//每写入一位数据之前先把数据总线拉低1usi++;//中间间隔1us,因为太小了,所以不能使用delayDATA = dat & 0x01;  	//然后写入一个数据,从最低位开始delay70us();			// 时序要求最少60usDSPORT= 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值dat >>= 1;     //这句代码就代表可以延时1us并且将数据位移动到对应的位置}
}

2.读时序--CPU和DS18B20一起控制

总线控制器发起读时序时,DS18B20仅被用来传输数据给控制器。因此,总线控制器在发出读寄存器指令[BEh ]或读电源模式指令[B4h]后必须立刻开始读时序,以便DS18B20提供请求的数据。除此之外,总线控制器在发出发送 温度转换指令平[44h]或召回EEPROM指令[B8h]之后读时序,详见DS18B20功能指令节。

所有读时序必须最少60us,包括两个读周期间至少1us的恢复时间。当总线控制把数据线从高电平拉低到低电平时,读时序开始,数据线必须至少保持1us,然后总线被释放。在总线控制器发出读时序后,DS18B20读/写时隙时序图过拉高或拉低总线上来传输1或0。当传输0结束后,总线将被释放,通过上拉电阻回到高电平空闲状态。从DS18B20 输出的数据在读时序的下降沿出现后15us内有效。因此,总线控制器在读时序开始15us内释放总线然后采样总线状态, 以读取数据线的状态。【在0-15us之有效,其他时间没有干其他事情】

1.读“0”

2.读“1”

3.官方代码实现

unsigned char Ds18b20ReadByte()
{unsigned char byte = 0, bi = 0;//bi:存储读出的bitunsigned int i = 0, j = 0;for (j=8; j>0; j--){DATA = 0;		//先将总线拉低1usi++;//中间间隔1us,因为太小了,所以不能使用delayDSPORT= 1;		//然后释放总线i++;i++;			//延时6us等待数据稳定bi = DSPORT;	 	//读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/byte = (byte >> 1) | (bi << 7);	//byte |= (bi << (8-j));//可以替代上面delay45us();}				return byte;
}

5.DS18B20工作流程分析

1.温度获取过程

(1)DS18B20自己本身不会主动取进行温度测量,而是需要主控CPU主动发起一个温度转换的过程,这么设计是因为温度转换本身是要耗电的,所以设计位拼死待机等待温度转换命令后才取进行温度AD转换

(2)主控CPU和DS18B20之间的通信是分周期,比如我们要让DS18B20进行温度转换就是一个周期。这个周期包括=初始化+n个指令(每一个周期的开始都要有一个初始化,然后跟着n个命令)

(3)初始化过程主要是探测目标DS18B20是否存在(查看是否有响应),如存在将芯片初始化。

(4)命令很重要。(18B20中是存在CPU的)所以DS18B20是一个典型的“命令-响应”型外设。

(5)学习这种外设的关键是:命令集。

//开启温度转换
void Ds18b20ChangTemp(void)
{Ds18b20Init();delay1ms();Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 Ds18b20WriteByte(0x44);	    //温度转换命令delay750ms();	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了 
}void Ds18b20ReadTempCom(void)
{	Ds18b20Init();delay1ms();Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令Ds18b20WriteByte(0xbe);	 //发送读取温度命令
}//将读取到的温度输出
int Ds18b20ReadTemp(void)
{unsigned int temp = 0;unsigned char tmh, tml;double t = 0;Ds18b20ChangTemp();			 	//先写入转换命令Ds18b20ReadTempCom();			//然后等待转换完后发送读取温度命令tml = Ds18b20ReadByte();		//读取温度值共16位,先读低字节tmh = Ds18b20ReadByte();		//再读高字节temp = tmh;temp <<= 8;temp |= tml;return temp ;
}

2.ROM操作指令

(1)DS18B20支持多个芯片串联在一根总线上,也就是所谓的单总线协议,所以必须要主控CPU要能够区分总线上多个18B20,因此有个ROM操作指令来完成这个任务(区分多个1SD8B20)

(2)ROM操作指令和温度采集一点关系都没有,所以当我们总线上只有一个18B20的时候ROM操作指令我们不需要去管

(3)一旦系统中单总线上有多个18B20,那么我们必须借助ROM操作指令来区分多个18B20,而且这个区分过程可能需要多个ROM指令来完成。

(4)如果系统中只有一个18B20,那么就用一条skip rom命令(0xCC)就可以跳过这个阶段。【因为只有一个所以可以不用进行响应直接发送即可】

3.功能指令

(1)ROM操作指令目的是为了在单总线上多个18B20中挑选到那个当前我们要操作的18B20,而功能指令是为了和选定的18B20通信从而获取温度。

6.DS18B20的编程要点

1.几种工作思路

(1)参考文档自己编写

(2)参考示例代码移植

2.DS18B20移植注意点

(1)注意延时函数的本地实现---DS18B20对时间要求很高【代码里的时间有关的部分必须重写

(2)注意引脚配置(看原理图)

(3)注意时序

(4)线通过初始化来检测芯片是否能通再做其他的

(5)注意读到的温度值是否会变

3.代码实践

1.移植初始化函数

//初始化函数
//返回0则表示初始化成功,1表示失败
unsigned char Ds18b20Init(void){unsigned char i=0;DQIO=0;//将数据总线拉低Delay750us();//数据手册要求480us-900usDQIO=1;//然后拉高总线,如果DS18B20做出翻译会将再15us-60us后总线拉低//如果DS18B20接收到并且回应则DQIO=1,如果没有回应则DQIO=0i=0;while(DQIO){//ds18b20没有回应i++;if(i>5){//因为我们要求再15us-60us之间进行响应//而且我们设置延迟函数为15us,则表示15us进行一次检验//60/15=4次return 1;}Delay15us();}return 0;//初始化成功}

2.移植串口函数作为调试

uart.c

#include "uart.h"// 串口设置为: 波特率9600、数据位8、停止位1、奇偶校验无
// 使用的晶振是11.0592MHz的,注意12MHz和24MHz的不行
void uart_init(void)
{// 波特率9600SCON = 0x50;   	// 串口工作在模式1(8位串口)、允许接收PCON = 0x00;	// 波特率不加倍// 通信波特率相关的设置TMOD = 0x20;	// 设置T1为模式2TH1 = 253;TL1 = 253;	   	// 8位自动重装,意思就是TH1用完了之后下一个周期TL1会// 自动重装到TH1去TR1 = 1;		// 开启T1让它开始工作
//	ES = 1;
//	EA = 1;
}// 通过串口发送1个字节出去
void uart_send_byte(unsigned char c)
{// 第1步,发送一个字节SBUF = c;// 第2步,先确认串口发送部分没有在忙while (!TI);// 第3步,软件复位TI标志位TI = 0;
}

main.c 

void main(){unsigned char ret=0;uart_init();uart_send_byte('!');//串口测试成功ret=Ds18b20Init();if(ret==0){uart_send_byte('K');//输出,则表示初始化成功}else{uart_send_byte('A');}while(1);
}

10.DS18B20移植

1.写函数

//写函数
void Ds18b20_write_byte(unsigned char dat){unsigned int i=0,j=0;for(j=0;j<8;j++){DQIO=0;//每写入一位数据之前先将总线拉低1usi++;//延时效果DQIO=dat&0x01;//写入一个数据,从最低位开始Delay68us();//时序要求最少60usDQIO=1;//然后释放总线,至少1us给总线恢复时间dat>>=1;//将倒数第二位移动到倒数第一位}}

2.读函数

//读函数
unsigned char Ds18b20_read_byte(){unsigned char byte=0,bi=0;unsigned int i=0,j=0;for(j=8;j>0;j--){DQIO=0;//先将总线低i++;//延时1usDQIO=1;//然后释放总线//【注意点:这个地方的时间控制很重要,如果太长或者太短都可能读取不到数据i++;i++;//延时6us等待数据稳定bi=DQIO;//读取数据,从最低位开始读取//将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉的那位补0【因为我们从最低位开始读取】byte=(byte>>1) | (bi<<7);Delay45us();}

3.转换温度

注意点:温度转换是需要时间的,所以在转换温度后记得要延时一定的时间才可以(750ms)

void Ds18b20ChangeTemp(void){Ds18b20Init();Delay1ms();Ds18b20_read_byte(0xcc);//跳过ROM操作命令Ds18b20_read_byte(0x44);//温度转换命令//因为我们转换温度需要时间才可以进行读取,所以我们需要时间等待//温度转换过程要750msDelay750ms();//等待转换成功,而如果你是一直刷着,就不用延时
}

4.读取温度

void Ds18b20ReadTemp(void){Ds18b20Init();Delay1ms();Ds18b20_read_byte(0xcc);//跳过ROM操作命令Ds18b20_read_byte(0xbe);//发送读取温度命令}

5.将读取到的温度合并

//将寄存器中(包括读取到)的温度(2位)合并成一位
//但是如果这样写不方便在主函数调用
//因为16位,用int无法输出,则我们使用串口直接输出
/*
unsigned int Ds18b20ReadTemp(void){unsigned int temp=0;//合并结果unsigned char tmh,tml;//高8位与低8位Ds18b20ChangeTemp();//先写入转换命令Ds18b20ReadTempCom();//然后等待转换完发送读取温度命令//读取温度一共12位(但是实际上显示16位)tml=Ds18b20ReadByte();//先读取温度的低8位tmh=Ds18b20ReadByte();//再读温度的高8位//将结果合并//(tmh<<8):因为高位是在合并结果的bit8,所以将tmh左移8位temp=tml | (tmh<<8);return temp;
}
*/
void Ds18b20ReadTemp(void){unsigned int temp=0;//合并结果unsigned char tmh,tml;//高8位与低8位Ds18b20ChangeTemp();//先写入转换命令Ds18b20ReadTempCom();//然后等待转换完发送读取温度命令//读取温度一共12位(但是实际上显示16位)tml=Ds18b20ReadByte();//先读取温度的低8位tmh=Ds18b20ReadByte();//再读温度的高8位uart_send_byte(0);uart_send_byte(tml);uart_send_byte(tmh);//前面四位为0
}

主函数

#include"ds18b20.h"
#include"uart.h"void main(){/*unsigned char ret=0;uart_init();//uart_send_byte('!');//串口测试成功ret=Ds18b20Init();if(ret==0){uart_send_byte('K');//输出,则表示初始化成功}else{uart_send_byte('A');}*/while(1){Ds18b20ReadTemp();}
}

6.温度数据的移位组合

7.数字值转为温度值

换算:tml :0x99   tmh:0x01,意味着,温度数字值:0x199,换算成十进制为:409

当前默认精度是12位,每一个数字值对应的应该是0.0625摄氏度

所以计算出来的温度值应该是:409*0.0625=25.56摄氏度

在单片机中,应该尽量避免进行小数运算。小数运算一般转换成整数运算。

409*0.0625=409*625/10000

注意点:

(1)12位对应的是0.0625,可能会溢出

temp=temp*625/10000;//此处产生溢出

(2)强制类型转换


//将数值转换为温度值
void Ds18b20ReadTemp2(void){unsigned int temp=0;//合并结果unsigned int tmh,tml;//高8位与低8位//因为我们要进行温度转换,所以0.0625是doubledouble t=0;Ds18b20ChangeTemp();//先写入转换命令Ds18b20ReadTempCom();//然后等待转换完发送读取温度命令//读取温度一共12位(但是实际上显示16位)tml=Ds18b20ReadByte();//先读取温度的低8位tmh=Ds18b20ReadByte();//再读温度的高8位//将结果合并//(tmh<<8):因为高位是在合并结果的bit8,所以将tmh左移8位temp=tml | (tmh<<8);//temp=temp*625/10000;//此处产生溢出t=temp*0.0625;uart_send_byte(0);//uart_send_byte(temp);uart_send_byte((unsigned char)t);//因为t是double,所以要进行强制类型转换
}

相关文章:

【单片机】17-温度传感器DS18B20

1.DS18B20相关背景知识 1.温度传感器 &#xff08;1&#xff09;测温度的方式&#xff1a;物理&#xff08;汞柱&#xff0c;气压&#xff09;&#xff0c;电子&#xff08;金属电性能随温度变化&#xff09; &#xff08;2&#xff09;早期&#xff1a;热敏电阻&#xff08;模…...

力扣 -- 5. 最长回文子串

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:string longestPalindrome(string s) {int ns.size();vector<vector<bool>> dp(n,vector<bool>(n));//最长回文串的起始位置int start0;//最长回文串的长度int len0;for(int in-1;i>…...

SpringCloud源码探析(十)-Web消息推送

1.概述 消息推送在日常使用中的场景比较多&#xff0c;比如有人点赞了我的博客或者关注了我&#xff0c;这时我就会收到一条推送消息&#xff0c;以此来吸引我点击或者打开应用。消息推送的方式主要分为两种&#xff1a;web消息推送和移动端消息推送。它将所要发送的信息&…...

Vue、React和小程序中的组件通信:父传子和子传父

在前端开发中&#xff0c;组件化是一种常见的开发模式&#xff0c;它可以将复杂的用户界面拆分成多个可重用的组件。在Vue、React和小程序中&#xff0c;组件之间的数据和事件传递是非常关键的&#xff0c;其中父传子和子传父是常见的通信方式。本文将介绍在Vue、React和小程序…...

安卓玩机----展讯芯片机型解锁 读写分区工具 操作步骤解析

国内机型大都使用高通和MTK芯片。展讯芯片使用的较少。相对来说高通和mtk机型解锁以及读取分区工具较多。展讯的几乎没有。目前有大佬开发出了一款展讯芯片解锁 与读写分区工具.开源的tools 官方分享说明&#xff1a; 是一款专为 Windows 计算机设计的免费、用户友好的工具&am…...

微软放大招!Bing支持DALL-E3,免费AI绘画等你来体验!

最近 OpenAI 发布了DALL-E3模型&#xff0c;出图效果和Midjourney不相上下&#xff0c;不过要使用它有些门槛&#xff0c;必须是 ChatGPT Plus 账户&#xff0c;而且还要排队&#xff0c;怎么等都等不到&#xff0c;搞得大家都比较焦虑。 不过现在微软在Bing上也支持 DALL-E3 …...

tp5访问的时候必须加index.php,TP5配置隐藏入口index.php文件

PS&#xff1a;这里说的入口文件指的是public/index.php,配置文件就在这个目录下 可以去掉URL地址里面的入口文件index.php&#xff0c;但是需要额外配置WEB服务器的重写规则。 以Apache为例&#xff0c;需要在入口文件的同级添加.htaccess文件(官方默认自带了该文件)&#x…...

16k面试中的10个问题

你好&#xff0c;我是田哥 节前&#xff0c;有位朋友跟我反馈面试中一些问题&#xff0c;这位朋友的基本情况&#xff1a; 坐标&#xff1a;上海&#xff0c;年限&#xff1a;3年不到&#xff0c;期望薪资&#xff1b;16k 下面我们来看看具体问题&#xff1a; 01&#xff1a;请…...

STM32单片机入门学习(六)-光敏传感器控制LED

光敏传感器模块和LED接线 LED负极接B12,正极接VCC 光敏传感模块一DO端接B13,GND接GND&#xff0c;VCC接VCC,AO不接。 如图&#xff1a; 主程序代码&#xff1a;main.c #include "stm32f10x.h" #include "Delay.h" //delay函数所在头文件 #include …...

MFC 鼠标悬停提示框

MFC 鼠标悬停提示框 运行效果 在MFC窗口中添加一个控件 工具栏中拖拽List Box到MFC窗口给List Box添加变量 CListBox m_listbox 增加成员变量 CWnd* m_tip_parent_wnd; CToolTipCtrl m_tip;给m_listbox创建提示框 void create_tip_window(CWnd* tip_wnd, CToolTipCtrl* ti…...

大数据学习,涉及哪些技术?

学习大数据需要涉及多种技术和概念&#xff0c;因为大数据领域非常广泛&#xff0c;涵盖了数据的采集、存储、处理、分析和可视化等多个方面。以下是学习大数据时需要考虑的一些关键技术和概念&#xff1a; 1、数据采集和存储&#xff1a; 数据库管理系统&#xff08;DBMS&am…...

Clion中使用C/C++开发stm32程序

前言 从刚开始学习阶段&#xff0c;一直是用的keil5开发stm32程序&#xff0c;自从看到稚晖君推荐的CLion开发嵌入式程序后&#xff0c;这次尝试在CLion上开发stm32程序。 1、配置CLion用于STM32开发的环境 这里我就不详细写了&#xff0c;没必要重新写&#xff0c;网上教程很多…...

JavaScript Web APIs第五天笔记

Web APIs - 第5天笔记 目标&#xff1a; 能够利用JS操作浏览器,具备利用本地存储实现学生就业表的能力 BOM操作综合案例 js组成 JavaScript的组成 ECMAScript: 规定了js基础语法核心知识。比如&#xff1a;变量、分支语句、循环语句、对象等等 Web APIs : DOM 文档对象模型&…...

[ICCV-23] Paper List - 3D Generation-related

ICCV-23 paper list 目录 Oral Papers 3D from multi-view and sensors Generative AI Poster Papers 3D Generation (Neural generative models) 3D from a single image and shape-from-x 3D Editing Face and gestures Stylization Dataset Oral Papers 3D from …...

Transformer为什么如此有效 | 通用建模能力,并行

目录 1 更强更通用的建模能力 2 并行计算 3 大规模训练数据 4 多训练技巧的集成 Transformer是一种基于自注意力机制的网络&#xff0c;在最近一两年年可谓是大放异彩&#xff0c;我23年入坑CV的时候&#xff0c;我看到的CV工作似乎还没有一个不用到Transformer里的一些组…...

【初识Jmeter】【接口自动化】

jmeter的使用笔记1 Jmeter介绍与下载安装介绍安装配置配置与扩展组件 jmeter的使用基本功能元素登陆请求与提取cookie其他请求接口关联Cookie-响应成功聚合报告查看 Jmeter介绍与下载安装 介绍 jmeter是apache公司基于java开发的一款开源压力测试工具&#xff0c;体积小&…...

C:数组传值调用和传地址调用

传地址调用 对数组进行修改&#xff1a;排序… #include <stdio.h>// 函数用于交换两个整数的值 void swap(int *a, int *b) {int temp *a;*a *b;*b temp; }// 函数用于对整数数组进行升序排序 void sortArray(int *arr, int size) {for (int i 0; i < size - 1…...

Python数据容器——字典的常用操作(增、删、改、查)

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;Python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注. 目录 一、理解字典 1. Python字典是什么&#xff1f; 2. 字…...

JavaScript入门——(5)函数

1、为什么需要函数 函数&#xff1a;function&#xff0c;是被设计为执行特定任务的代码块 说明&#xff1a;函数可以把具有相同或相似逻辑的代码“包裹”起来&#xff0c;通过函数调用执行这些被“包裹”的代码逻辑&#xff0c;有利于精简代码方便复用。 比如之前使用的ale…...

数据库sql查询成绩第二高

select * from propro; #查询成绩第二高 select max(id) from propro where id <(select max(id) from propro); #查询成绩第二高的第二种方式 select * from (select * from propro order by id desc limit 2) as b order by id asc limit 1;...

十五、异常(5)

本章概要 异常限制构造器 异常限制 当覆盖方法的时候&#xff0c;只能抛出在基类方法的异常说明里列出的那些异常。这个限制很有用&#xff0c;因为这意味着与基类一起工作的代码&#xff0c;也能和导出类一起正常工作&#xff08;这是面向对象的基本概念&#xff09;&#…...

途虎养车上市、京东养车“震虎”,如何突围汽车后市场?

“汽车后市场第一股”终于来了&#xff01; 赶在十一黄金周之前&#xff0c;途虎养车股份有限公司(09690.HK&#xff0c;下称“途虎养车”)于9月26日挂牌港交所&#xff0c;开盘价为28港元/股&#xff0c;与发行价持平&#xff1b;IPO首日报收29.50港元/股&#xff0c;涨幅5.3…...

【算法与数据结构】--算法基础--算法入门

一、什么是算法&#xff1f; 算法是一组有序的操作步骤&#xff0c;用于解决特定问题或执行特定任务。它是一种精确而有限的计算过程&#xff0c;以输入数据作为起点&#xff0c;经过一系列明确定义的步骤&#xff0c;最终产生输出结果。算法可以看作是一种计算机程序的抽象&a…...

AnyDesk密钥

最近最新的密钥&#xff1a;7K2CV32ER6T8F8I 这款软件应该是目前用的最好的可以免费的软件了&#xff0c;记录一下密钥...

C#(Csharp)我的基础教程(二)(我的菜鸟教程笔记)-属性和字段的探究与学习

目录 1、字段字段特点&#xff1a;2、属性属性的特点 1、字段 字段是定义在方法外面的变量&#xff0c;是成员变量&#xff0c;主要是为了类的内部数据交换使用&#xff0c;字段一般是用private修饰&#xff0c;也可以用readonly修饰&#xff0c;表示只读字段&#xff0c;其它…...

Programming abstractions in C阅读笔记:p176-p178

《Programming Abstractions In C》学习第59天&#xff0c;p176-p178总结。 一、技术总结 1.addtive sequences tn tn-1 tn-2 序列&#xff1a;3, 7, 10, 17, 27, 44, 71, 115, 186, 301, 487, 788, 1275, … p177, As a general class, the sequences that follow this…...

LeetCode-496-下一个更大元素

题目描述&#xff1a; 题目链接&#xff1a;LeetCode-496-下一个更大元素 解题思路&#xff1a; 方法一&#xff1a;暴力 方法二&#xff1a;单调栈 方法一代码实现&#xff1a; class Solution {public int[] nextGreaterElement(int[] nums1, int[] nums2) {// 最笨的方法&am…...

C++中的Lambda表达式

一、为什么要有lambda表达式 struct Goods {string _name; // 名字double _price; // 价格int _evaluate; // 评价Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){} }; 对于一个Goods类&#xff0c;需要对其中3个成员分…...

dockerfile搭建lnmp

systemctl stop firewalld systemctl disable firewalld setenforce 0 docker network create --subnet172.18.0.0/16 --opt "com.docker.network.bridge.name""docker1" mynetwork #部署nginx&#xff08;容器IP 为 172.18.0.10&#xff09; mkdir /…...

python之数据库操作详解

一般来说&#xff0c;我们对数据库里的操作需要先连接&#xff0c;创建游标对象&#xff0c;然后通过游标对象执行SQL语句去对SQL的数据进行操作&#xff0c;本篇文章旨在记录与科普。 1.cursor相关 元组是不可变的数据类型&#xff0c;只能查询&#xff0c;不能修改&#xf…...