【单片机】AT24C02存储器(I²C总线)/DS18B20温度传感器(单总线)

news2024/9/21 8:37:30


目录

一、AT24C02存储器

1、AT24C02存储器介绍

2、存储器简化模型

3、AT24C02存储器原理图

二、I²C总线

1、I²C总线的介绍

2、I²C电路

3、I²C时序图

3.1I²C开始和结束时序图

3.2I²C主机发送和接收时序图

3.3I²C主机发送应答/接收应答

4、I²C数据帧发送/接收方式

4.1主机向从机发送数据

4.2主机从从机接收数据

4.3复合格式(主机先发送数据,再接收从机数据)

4.4两种变形——字节写和随机读

5、利用独立按键写入读取数字

6、利用定时器、数码管、独立按键、AT24C02制作秒表

6.1main.c

6.2Nixie.c

6.3key.c

三、DS18B20温度传感器

1、DS18B20温度传感器介绍

2、单总线电路规范

3、单总线时序结构

3.1初始化

3.2发送一位

3.3接收一位

3.4发送/接收一个字节

4、DS18B20操作流程

5、BS18B20读取环境温度

5.1main.c

5.2OneWire.c

5.3DS18B20.c

6、DS18B20温度报警器

6.1main.c

6.2OneWire.c

6.3Key.c

6.4AT24C02.c

6.5Buzzer.c


一、AT24C02存储器

1、AT24C02存储器介绍

AT24C02是一种可以实现掉电不丢失的存储器。易失性存储器RAM存储速度快,非易失性存储器ROM存储速度慢;这俩特性类似缓存和磁盘。

存储介质:E²PROM(可擦写的只读存储器);

通讯接口:I²C总线;

容量:256字节。

2、存储器简化模型

3、AT24C02存储器原理图

二、I²C总线

1、I²C总线的介绍

I²C总线是一种通用数据总线,有两根通信线SCL(串行时钟线)、SDA(串行数据线,只有一根线,双向),是一种同步、半双工带数据应答的通信协议。

2、I²C电路

1、所有I²C设备的中SCL、SDA各自连接在一起;

2、设备的SCL和SDA均要配置成开漏输出模式;

3、SCL和SDA各添加一个上拉电阻,阻值一般KΩ级别;

开漏输出是为了单一模块间通信的过程中,让其他模块对外呈现高阻态。如果在通信的过程中,其他模块是上拉电路,虽然上拉能力弱,但是多路并联会使上拉能力增强,可能会对正在通信的模块造成影响。

上拉电阻作用:如图所示,SCL和SDA各接一个外接电阻,电路就会由开漏输出变成弱上拉模式,那么CPU想输出1,内部开关闭合,反之开关断开即可。

那么问题来了,多机通讯时,如何确定接收端是谁?多机通讯时,通过时序确定谁和谁通信。

3、I²C时序图

3.1I²C开始和结束时序图

3.2I²C主机发送和接收时序图

主机发送一个字节

主机接收一个字节

1、当SCL为高电平时,SDA的跳变表示开始和结束状态;SDA电平不变表示正在读取和发送数据。

2、主机接收从机的数据时,需要解除对SDA的控制权,即从机发送数据前将主机SDA置1。

3.3I²C主机发送应答/接收应答

1、主机接收完从机1个字节数据后,主机需要向从机发送应答。0表示应答,1表示非应答。

2、主机发送至从机1个字节数据后,从机需要向主机接收应答。0表示应答,1表示非应答。因为是从机发送,所以主机要移交SDA控制权。

4、I²C数据帧发送/接收方式

4.1主机向从机发送数据

4.2主机从从机接收数据

4.3复合格式(主机先发送数据,再接收从机数据)

本质是上面两种方式的组合。可以理解为主机向从机提问,从机回复问题。

4.4两种变形——字节写和随机读

AT24C02的固定地址为1010,可配置地址本开发板上为000,所以从机地址+W为0XA0,从机地址+R为0xA1。

5、利用独立按键写入读取数字

unsigned char KeyNum;
unsigned int Num;
void main()
{
	LCD_Init();
	LCD_ShowNum(1,1,Num,5);
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)
		{
			Num++;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==2)
		{
			Num--;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==3)
		{
			AT24C02_WriteByte(0,Num%256);//写入低8位
			delay_ms(5);//每次写完延时5ms
			AT24C02_WriteByte(1,Num/256);//写入高8位
			delay_ms(5);//每次写完延时5ms
			LCD_ShowString(2,1,"Write success");
			delay_ms(1000);
			LCD_ShowString(2,1,"              ");
		}
		if(KeyNum==4)
		{
			Num=AT24C02_ReadByte(0);//读出低8位
			Num|=AT24C02_ReadByte(1)<<8;//读出高8位
			LCD_ShowNum(1,1,Num,5);
			LCD_ShowString(2,1,"Read success");
			delay_ms(1000);
			LCD_ShowString(2,1,"              ");
		}
	}
}

6、利用定时器、数码管、独立按键、AT24C02制作秒表

6.1main.c

#include <REGX52.H>
#include "key.h"
#include "Timer0.h"
#include "Nixie.h"
#include "AT24C02.h"
#include "delay.h"
unsigned char KeyNum;
unsigned char Min,Sec,MiniSec;
unsigned char RunFlag;
void main()
{
	Timer0_Init();
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)//暂停
		{
			RunFlag=!RunFlag;
		}
		else if(KeyNum==2)//清零
		{
			Min=Sec=MiniSec=0;
		}
		else if(KeyNum==3)//写入AT24C02
		{
			AT24C02_WriteByte(0,Min);
			delay_ms(5);
			AT24C02_WriteByte(1,Sec);
			delay_ms(5);
			AT24C02_WriteByte(2,MiniSec);
			delay_ms(5);
		}
		else if(KeyNum==4)//读出AT24C02
		{
			Min=AT24C02_ReadByte(0);
			Sec=AT24C02_ReadByte(1);
			MiniSec=AT24C02_ReadByte(2);
		}
		Nixie_SetBuff(1,Min/10);
		Nixie_SetBuff(2,Min%10);
		Nixie_SetBuff(3,11);
		
		Nixie_SetBuff(4,Sec/10);
		Nixie_SetBuff(5,Sec%10);
		Nixie_SetBuff(6,11);
		
		Nixie_SetBuff(7,MiniSec/10);
		Nixie_SetBuff(8,MiniSec%10);

	}

}
void Sec_Loop()
{
	if(RunFlag!=0)
	{
		MiniSec++;
		if(MiniSec>=100)
		{
			MiniSec=0;
			Sec++;
			if(Sec>=60)
			{
				Sec=0;
				Min++;
			}
		}
	}
}
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1,T0Count2,T0Count3;//函数栈帧结束后保留T0Count
	TH0=64535/256;//每次进中断函数后,让这两个寄存器重新回到初值
	TL0=64535%256;
	T0Count1++;//每中断一次T0Count++
	if(T0Count1>=(20/(12/11)))//达到了定时20毫秒的作用(晶振11.0592)
	{
		T0Count1=0;//重置为0
		Key_Loop();
	}
	T0Count2++;
	if(T0Count2>=(2/(12/11)))//达到了定时2毫秒的作用(晶振11.0592)
	{
		T0Count2=0;//重置为0
		Nixie_Loop();
	}
	T0Count3++;
	if(T0Count3>=(10/(12/11)))//达到了定时10毫秒的作用(晶振11.0592)
	{
		T0Count3=0;//重置为0
		Sec_Loop();
	}
}

使用定时器中断控制数码管持续扫描、独立按键循环检测。(无需延时)

使用定时器中断控制秒表数字流动。

独立按键用于展示不同的效果,按键1表示秒表运行/暂停,按键2表示秒表数据清零,按键3存储秒表数据至AT24C02,秒表4读取AT24C02的数据至数码管,秒表显示存储的内容。

6.2Nixie.c

unsigned char Nixie_buff[9]={0,10,10,10,10,10,10,10,10};
//数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0X00,0X40};
void Nixie_SetBuff(unsigned char Location,Number)
{
	Nixie_buff[Location]=Number;
}
//数码管显示子函数
void Nixie_Scan(unsigned char Location,Number)
{
	P0=0x00;				//段码清0,消影
	switch(Location)		//位码输出
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];	//段码输出
}
void Nixie_Loop()
{
	static unsigned char i=1;//计数
	Nixie_Scan(i,Nixie_buff[i]);
	i++;
	if(i>=9)
	{
		i=1;
	}
}

6.3key.c

unsigned char Key_KeyNum;
unsigned char Key()
{
	unsigned char Tmp=Key_KeyNum;
	Key_KeyNum=0;
	return Tmp;
}
unsigned char Key_GetStat()
{
	unsigned char KeyNumber=0;
	if(P3_1==0)
	{
		KeyNumber=1;
	}
	if(P3_0==0){KeyNumber=2;}
	if(P3_2==0){KeyNumber=3;}
	if(P3_3==0){KeyNumber=4;}
	return KeyNumber;
}
void Key_Loop()
{
	static unsigned char NowState,LastState;
	LastState=NowState;
	NowState=Key_GetStat();
	if(LastState==1&&NowState==0)//松手状态(按键弹起)
	{
		Key_KeyNum=1;
	}
	if(LastState==2&&NowState==0)
	{
		Key_KeyNum=2;
	}
	if(LastState==3&&NowState==0)
	{
		Key_KeyNum=3;
	}
	if(LastState==4&&NowState==0)
	{
		Key_KeyNum=4;
	}
}

三、DS18B20温度传感器

1、DS18B20温度传感器介绍

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

测温范围:-55°C 到 +125°C

通信接口:1-Wire(单总线)异步、半双工

其它特征:可形成总线结构、内置温度报警功能、可寄生供电

2、单总线电路规范

为了多机通讯,设备的DQ均要配置成开漏输出模式并且DQ需要添加一个上拉电阻,阻值一般为4.7KΩ左右

若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路

3、单总线时序结构

3.1初始化

主机将总线拉低至少480us,然后释放总线,等待15~60us后,存在的从机会拉低总线60~240us以响应主机,之后从机将释放总线。

3.2发送一位

主机将总线拉低60~120us,然后释放总线,表示发送0;主机将总线拉低1~15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us

3.3接收一位

主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us

3.4发送/接收一个字节

发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)

接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)

4、DS18B20操作流程

初始化:从机复位,主机判断从机是否响应(从机是否存在)

ROM操作:ROM指令+本指令需要的读写操作

功能操作:功能指令+本指令需要的读写操作

5、BS18B20读取环境温度

5.1main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "delay.h"
#include "DS18B20.h"
float T;
void main()
{
	LCD_Init();
	DS18B20_ConvertTemperature();//DS18B20温度转换
	delay_ms(1000);//延时1秒,提前读好,进while循环后读出的就是实际温度
	while(1)
	{
		DS18B20_ConvertTemperature();//DS18B20温度转换
		T=DS18B20_ReadTemperature();
		if(T<0)
		{
			LCD_ShowChar(2,1,'-');
			T=-T;
		}
		else
		{
			LCD_ShowChar(2,1,'+');
		}
		LCD_ShowNum(2,2,T,3);
		LCD_ShowChar(2,5,'.');
		LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
	}
}

5.2OneWire.c

#include <REGX52.H>

sbit OneWire_DQ=P3^7;
//初始化
unsigned char OneWire_Init()
{
	unsigned char i;
	unsigned char AckBit;
	OneWire_DQ=1;
	OneWire_DQ=0;//主机将总线拉低
	i = 227;while (--i);//大概延时500μs>480μs
	OneWire_DQ=1;//主机再拉高总线
	i = 29;while (--i);//大概延时70μs
	AckBit=OneWire_DQ;//读取从机应答
	i = 227;while (--i);//再延时500μs走完初始化时序
	return AckBit;
}

//发送一位
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ=0;//主机将总线拉低
	i = 4;while (--i);//延时10μs
	OneWire_DQ=Bit;//把数据给总线。发0,从机将在30μs后读到0;反之读到1
	i = 23;while (--i);//延时50μs
	OneWire_DQ=1;//主机恢复总线
}

//接收一位
unsigned char OneWire_ReceiveBit()
{
	unsigned char Bit;
	unsigned char i;
	OneWire_DQ=0;//主机将总线拉低
	i = 2;while (--i);//延时5μs
	OneWire_DQ=1;//主机将总线释放
	i = 2;while (--i);//延时5μs
	Bit=OneWire_DQ;//主机取样
	i = 23;while (--i);//延时50μs
	return Bit;
}

//发送一个字节
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i=0;
	for(i=0;i<8;++i)
	{
		OneWire_SendBit(Byte&(0X01<<i));
	}
}
//接收一个字节
unsigned char OneWire_ReceiveByte()
{
	unsigned char Byte=0X00;
	unsigned char i=0;
	for(i=0;i<8;++i)
	{
		Byte|=(OneWire_ReceiveBit()<<i);
	}
	return Byte;
}

5.3DS18B20.c

#include <REGX52.H>
#include "OneWire.h"
#define DS18B20_SKIP_ROM 0XCC
#define DS18B20_CONVERT_T 0X44
#define DS18B20_READ_SCRATCHPAD 0XBE
//DS18B20温度转换
void DS18B20_ConvertTemperature()
{
	OneWire_Init();//初始化
	OneWire_SendByte(DS18B20_SKIP_ROM);//跳过ROM
	OneWire_SendByte(DS18B20_CONVERT_T);//温度转变
}
//温度读取
float DS18B20_ReadTemperature()
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();//初始化
	OneWire_SendByte(DS18B20_SKIP_ROM);//跳过ROM
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);//读出暂存器的数据
	TLSB=OneWire_ReceiveByte();//先读出LSB
	TMSB=OneWire_ReceiveByte();//再读出MSB
	Temp=(TMSB<<8)|TLSB;//组合成int
	T=Temp/16.0;//看图,最低位是2^-4而不是2^0,int要/16.0移回去
	return T;
}

目前室温约为17℃。

6、DS18B20温度报警器

这里有一个单总线的缺点,单总线是严格依照时序电平的持续时间来确定当前执行的是什么操作。当我们使用定时器时,就会打断这个时序。所以单总线的时序一旦开始便不能中途打断,时序开始时必须先关闭定时器。所以单总线的模块和其他需要定时器操作的外设在一起时,为了单总线设备的运行,时序开始时必须关闭定时器,可能会影响其他外设(例如秒表的准确性)。

6.1main.c

#include <REGX52.H>
#include "DS18B20.h"
#include "delay.h"
#include "AT24C02.h"
#include "LCD1602.h"
#include "key.h"
#include "Timer0.h"
#include "Buzzer.h"
float T,TShow;//表示温度
char TLow,THigh;//表示温度最高和最低值
unsigned char KeyNum;
void main()
{
	DS18B20_ConvertTemperature();//DS18B20温度转换
	delay_ms(1000);//延时1秒,提前读好,进while循环后读出的就是实际温度
	TLow=AT24C02_ReadByte(0);
	THigh=AT24C02_ReadByte(1);//将0,1地址处TLow和THigh读出来
	if(THigh>125||TLow<-55||THigh<=TLow)//判断AT24C02中存储的数据对不对
	{
		THigh=125;
		TLow=-55;
	}
	LCD_Init();
	LCD_ShowString(1,1,"T:");
	LCD_ShowString(2,1,"TH:");
	LCD_ShowString(2,9,"TL:");
	Timer0_Init();
	while(1)
	{
		//温度读取及显示
		DS18B20_ConvertTemperature();//DS18B20温度转换
		T=TShow=DS18B20_ReadTemperature();
		if(T<0)
		{
			LCD_ShowChar(1,3,'-');
			TShow=-T;
		}
		else
		{
			LCD_ShowChar(1,3,'+');
		}
		LCD_ShowNum(1,4,TShow,3);
		LCD_ShowChar(1,7,'.');
		LCD_ShowNum(1,8,(unsigned long)(TShow*10000)%10000,4);
		//阈值判断及显示
		LCD_ShowSignedNum(2,4,THigh,3);
		LCD_ShowSignedNum(2,12,TLow,3);
		KeyNum=key();
		if(KeyNum!=0)
		{
			if(KeyNum==1)
			{
				++THigh;
				if(THigh>125)
				{
					THigh=125;
				}
			}
			if(KeyNum==2)
			{
				--THigh;
				if(THigh<=TLow)
				{
					++THigh;
				}
			}
			if(KeyNum==3)
			{
				++TLow;
				if(TLow>=THigh)
				{
					--TLow;
				}
			}
			if(KeyNum==4)
			{
				--TLow;
				if(TLow<-55)
				{
					TLow==-55;
				}
			}
			AT24C02_WriteByte(0,TLow);
			delay_ms(5);
			AT24C02_WriteByte(1,THigh);
			delay_ms(5);
		}
		if(T>THigh)
		{
			LCD_ShowString(1,13,"OV:H");
			Buzzer_Time(1000);
		}
		else if(T<TLow)
		{
			LCD_ShowString(1,13,"OV:L");
			Buzzer_Time(1000);
		}
		else
		{
			LCD_ShowString(1,13,"    ");
		}
	} 
}
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;//函数栈帧结束后保留T0Count
	TH0=64535/256;//每次进中断函数后,让这两个寄存器重新回到初值
	TL0=64535%256;
	T0Count++;//每中断一次T0Count++
	if(T0Count>=(20/(12/11)))//达到了定时20毫秒的作用(晶振11.0592)
	{
		T0Count=0;//重置为0
		Key_Loop();
	}
}

6.2OneWire.c

#include <REGX52.H>

sbit OneWire_DQ=P3^7;
//初始化
unsigned char OneWire_Init()
{
	unsigned char i;
	unsigned char AckBit;
	EA=0;//关闭定时器
	OneWire_DQ=1;
	OneWire_DQ=0;//主机将总线拉低
	i = 227;while (--i);//大概延时500μs>480μs
	OneWire_DQ=1;//主机再拉高总线
	i = 29;while (--i);//大概延时70μs
	AckBit=OneWire_DQ;//读取从机应答
	i = 227;while (--i);//再延时500μs走完初始化时序
	EA=1;//重新打开定时器
	return AckBit;
}

//发送一位
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	EA=0;
	OneWire_DQ=0;//主机将总线拉低
	i = 4;while (--i);//延时10μs
	OneWire_DQ=Bit;//把数据给总线。发0,从机将在30μs后读到0;反之读到1
	i = 23;while (--i);//延时50μs
	OneWire_DQ=1;//主机恢复总线
	EA=1;
}

//接收一位
unsigned char OneWire_ReceiveBit()
{
	unsigned char Bit;
	unsigned char i;
	EA=0;
	OneWire_DQ=0;//主机将总线拉低
	i = 2;while (--i);//延时5μs
	OneWire_DQ=1;//主机将总线释放
	i = 2;while (--i);//延时5μs
	Bit=OneWire_DQ;//主机取样
	i = 23;while (--i);//延时50μs
	EA=1;
	return Bit;
}

//发送一个字节
void OneWire_SendByte(unsigned char Byte)
{
	unsigned char i=0;
	for(i=0;i<8;++i)
	{
		OneWire_SendBit(Byte&(0X01<<i));
	}
}
//接收一个字节
unsigned char OneWire_ReceiveByte()
{
	unsigned char Byte=0X00;
	unsigned char i=0;
	for(i=0;i<8;++i)
	{
		Byte|=(OneWire_ReceiveBit()<<i);
	}
	return Byte;
}

6.3Key.c

#include "key.h"
#include "delay.h"
#include <REGX52.H>
unsigned char Key_KeyNum;
unsigned char Key()
{
	unsigned char Tmp=Key_KeyNum;
	Key_KeyNum=0;
	return Tmp;
}
unsigned char Key_GetStat()
{
	unsigned char KeyNumber=0;
	if(P3_1==0)
	{
		KeyNumber=1;
	}
	if(P3_0==0){KeyNumber=2;}
	if(P3_2==0){KeyNumber=3;}
	if(P3_3==0){KeyNumber=4;}
	return KeyNumber;
}
void Key_Loop()
{
	static unsigned char NowState,LastState;
	LastState=NowState;
	NowState=Key_GetStat();
	if(LastState==1&&NowState==0)//松手状态(按键弹起)
	{
		Key_KeyNum=1;
	}
	if(LastState==2&&NowState==0)
	{
		Key_KeyNum=2;
	}
	if(LastState==3&&NowState==0)
	{
		Key_KeyNum=3;
	}
	if(LastState==4&&NowState==0)
	{
		Key_KeyNum=4;
	}
}

6.4AT24C02.c

#include <REGX52.H>
#include "IIC.h"
#define AT24C02_ADDRESS 0XA0
//字节写:在写入地址中写入Data
void AT24C02_WriteByte(unsigned char WordAddress,unsigned char Data)
{
	IIC_Start();//开始函数
	IIC_SendByte(AT24C02_ADDRESS);//发送从机地址+W
	IIC_ReceiveAck();//接收应答
	IIC_SendByte(WordAddress);//发送写入地址
	IIC_ReceiveAck();//接收应答
	IIC_SendByte(Data);//发送Data
	IIC_ReceiveAck();//接收应答
	IIC_Stop();//终止函数
}
//随机读:读出WordAddress地址中的Data
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{
	unsigned char Data;
	IIC_Start();//开始函数
	IIC_SendByte(AT24C02_ADDRESS);//发送从机地址+W
	IIC_ReceiveAck();//接收应答
	IIC_SendByte(WordAddress);//发送写入地址
	IIC_ReceiveAck();//接收应答
	IIC_Start();//开始函数
	IIC_SendByte(AT24C02_ADDRESS|0X01);//发送从机地址+R
	IIC_ReceiveAck();//接收应答
	Data=IIC_ReceiveByte();//接收一个字节
	IIC_SendAck(0X01);//发送应答
	IIC_Stop();//终止函数
	return Data;
}

6.5Buzzer.c

#include "Buzzer.h"
#include <REGX52.H>
#include "delay.h"
#include <INTRINS.H>
sbit Buzzer=P2^5;
void Buzzer_Delay500us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 227;
	while (--i);
}

//调用这个函数,蜂鸣器就响多少秒
void Buzzer_Time(unsigned int ms)
{
	unsigned int i;
	for(i=0;i<ms*2;++i)
	{
		Buzzer=!Buzzer;
		Buzzer_Delay500us();//必须要有延时,保证高低电平维持0.5ms(几字波形)
	}	
}

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

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

相关文章

数据可视化系列-02各类图表的综合使用介绍及实践-上篇

文章目录3.各类图表的综合使用介绍及实践3.1了解数据功能图1、可视化中的数据2、基于数据的研究3、数据的可视化组件4、可视化图表的作用、制作流程和类型3.2北极星指标展示1、指标类知识回顾&#xff1a;指标类简介、指标类主要场景2、指标类图表&#xff1a;指标看板、指标趋…

C++关联容器(复习题篇)

本篇博客将介绍标准库关联容器&#xff0c;包括&#xff1a; 关联容器的概念和简单的使用关联容器涉及的类型和操作&#xff0c;特别是与顺序容器的差异无序关联容器&#xff0c;特别是与有序关联容器的差异 练习1.1 描述map和vector的不同 vector是顺序容器其中的元素是“顺序…

分布式事务的介绍

本地事务 单服务进程&#xff0c;单数据库资源,同一个连接conn多个事务操作 在JDBC编程中&#xff0c;我们通过java.sql.Connection对象来开启、关闭或者提交事务。代码如下所示&#xff1a; Connection conn ... //获取数据库连接 conn.setAutoCommit(false); //开启事务 t…

educoder数据结构与算法 栈 第2关:实现一个链接存储的栈

本文已收录于专栏 &#x1f332;《educoder数据结构与算法_大耳朵宋宋的博客-CSDN博客》&#x1f332; 目录 任务描述 相关知识 编程要求 测试说明 AC_Code 任务描述 本关任务是实现 step2/LnkStack.cpp 中的LS_IsEmpty、LS_Length、LS_Push、LS_Pop和LS_Top五个操作函数…

π122E30兼容Si8622BC-B-IS 双通道数字隔离器

π122E30兼容Si8622BC-B-IS 双通道数字隔离器 &#xff0c;具有出色的性能特征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器产品。 产品传输通道间彼此独立&#xff0c;可实现多种传输方向的配置&#xff0c;可实现 3.0kVrms 隔离耐压等级和 DC 到 200Mbp…

Day 17-Vue3 技术_其它

1.全局API的转移 Vue 2.x 有许多全局 API 和配置。例如&#xff1a;注册全局组件、注册全局指令等。 //注册全局组件 Vue.component(MyButton, {data: () > ({count: 0}),template: <button click"count">Clicked {{ count }} times.</button> })//注…

acwing-1015 摘花生

项目场景&#xff1a; 线性dp 题源 数字三角形 问题描述 Hello Kitty想摘点花生送给她喜欢的米老鼠。 她来到一片有网格状道路的矩形花生地(如下图)&#xff0c;从西北角进去&#xff0c;东南角出来。 地里每个道路的交叉点上都有种着一株花生苗&#xff0c;上面有若干颗花…

用Typora,PicGo和OSS实现自动上传图片

前言&#xff1a; 以前写博客要发布到好些个平台&#xff0c;我是将图片一张张上传到每个平台&#xff0c;后来发现是真的麻烦&#xff0c;上传图片花的时间太多&#xff0c;极大的降低了我写文章的积极性。 后来改进为使用oss&#xff0c;把博客的图片都上传到oss上面。然后…

JAVA : ArrayList和数组的转换

一、ArrayList转换为数组 ArrayList提供public T[] toArray(T[] a)方法返回一个按照正确的顺序包含此列表中所有元素的数组&#xff0c;返回数组的运行时类型就是指定数组的运行时类型。 import java.util.ArrayList; import java.util.List; public class Test { public st…

戴尔笔记本电脑重装系统后进不了系统怎么办

​戴尔电脑是一款很棒的电脑品牌&#xff0c;不少小伙伴都在使用这个牌子的电脑。但有不少小伙伴在重装完系统之后却进不去&#xff0c;那么碰到这种情况应该怎么办呢&#xff1f;下面就和小编一起来看看戴尔笔记本电脑重装系统后进不了系统怎么办的吧。 工具/原料&#xff1a…

【设计模式】-创造篇-工厂方法

制造业是一个国家工业经济发展的重要支柱&#xff0c;而工厂则是其根基所在。程序设计中的工厂类往往是对对象构造、实例化、初始化过程的封装&#xff0c;而工厂方法(Factory Method)则可以升华为一种设计模式&#xff0c;它对工厂制造方法进行接口规范化&#xff0c;以允许子…

Vector - VT System - 板卡_VT7001

接上篇我们介绍完了背板VT8006和VT8012&#xff0c;今天我们来介绍下电源模块板卡VT7001&#xff0c;这个板卡是我们在不需要程控电源的时候依然能够实现精细化的电压、电流控制及检查的板卡&#xff0c;并且在脚本开发中无需考虑时延的一个模块。我们使用的大部分设备无论是继…

14---实现文件上传和下载(头像上传功能)

1、建Files表 接下来开始完成文件管理的内容&#xff0c;首先是数据库建Files表 DROP TABLE IF EXISTS file;CREATE TABLE file (id int(11) NOT NULL AUTO_INCREMENT COMMENT id,name varchar(255) DEFAULT NULL COMMENT 文件名称,type varchar(255) DEFAULT NULL COMMENT 文…

Detection of Individual Tree Crowns in Airborne Lidar Data

Abstract 激光扫描提供了一种收集林分信息的好方法。本文介绍了一种在落叶林和混合温带森林中的小足迹光检测和测距&#xff08;激光雷达&#xff09;数据中自动描绘单棵树的方法。在光栅化激光数据中&#xff0c;可能的树顶用局部最大值滤波器检测。之后&#xff0c;结合浇注…

【Bootstrap】基础知识和环境配置

目录 一、Bootstrap基础 1. 概念 2. 特点 3. 组成 3.1 基本结构 3.2 丰富的CSS样式库 3.3 布局组件 3.4 插件 二、bootstrap的环境配置 1. 在页面中引入本地文件 2. 使用CDN加速器 一、Bootstrap基础 1. 概念 Bootstrap是一个基于HTML、CSS和JavaScript语言编写的…

动手学习深度学习-《自动求导》

向量链式求导法则 标量链式法则&#xff1a; 扩展到向量&#xff1a; yyy是关于标量uuu的一个标量&#xff0c;x\bf{x}x是一个向量 yyy是关于向量u\bf{u}u的一个标量&#xff0c;x\bf{x}x是一个向量 y\bf{y}y是关于向量u\bf{u}u的一个向量&#xff0c;x\bf{x}x是一个向量…

Nginx+keepalived 实现高可用,防盗链及动静分离配置详解

一、Nginx Rewrite 规则 1. Nginx rewrite规则 Rewrite规则含义就是某个URL重写成特定的URL&#xff08;类似于Redirect&#xff09;&#xff0c;从某种意义上说为了美观或者对搜索引擎友好&#xff0c;提高收录量及排名等。 语法&#xff1a; rewrite <regex> <r…

Oracle11g彻底卸载教程(详细版)

目前项目结束,暂时不需要Oracle了,为清理电脑并便于后续重装,现记录彻底卸载的步骤如下: 1、按下“Windows”+“R”键,在运行窗中,输入compmgmt.msc,进入计算机管理------>服务,停止所有Oracle服务(对于状态为 正在进行 的服务,右键------>停止)。 2、在开始…

遗传算法解决旅行商问题(TSP)

遗传算法解决旅行商问题 作者&#xff1a;Cukor丘克环境&#xff1a;MatlabR202a vscode 问题描述 旅行商问题&#xff08;TSP&#xff09;. 一个商人欲从自己所在的城市出发&#xff0c;到若干个城市推销商品&#xff0c;然后回到其所在的城市。如何选择一条周游路线&…

SpringBoot3初体验 - 第457篇

历史文章&#xff08;文章累计450&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 5个月的精华&#xff1a;Spring/SpringB…