DS18B20的原理及实例代码(51单片机、STM32单片机)
一、DS18B20介绍
DS18B20数字温度传感器是DALLAS公司生产的单总线器件,用它来组成一个测温系统具有线路简单,体积小,在一根通信线上可以挂很多这样的数字温度传感器,十分方便。
温度传感器种类众多,应用在高精度、高可靠性的场合时DALLAS公司生产的DS18B20温度传感器当仁不让。超小的体积,超低的硬件开销,抗干扰能力强,精度高,附加功能强,使得DS18B20更受欢迎。DS18B20的优势更是我们学习单片机技术和开发温度相关小产品的不二选择。了解工作原理和应用可以拓宽您对单片机开发的思路。
二、DS18B20特点

三、DS18B20在实际应用中的典型接法
1、工作在寄生电源下的典型接法
2、 外部供电下的典型接法
四、单总线时序
DS18B20采用1-wire Bus所有数据都在一条线上传输,因此单总线协议对时序要求非常严格以确保数据的完整性。
单总线信号类型:复位脉冲、存在脉冲、写0、写1、读0、读1。所有这些信号除存在脉冲由DS18B20发出的以外其他信号都由总线控制器发出。
数据传输总是从最低有效位开始。
1、初始化时序
初始化时序里面包含了复位DS18B20和接收DS18B20返回的存在信号。
主机和DS18B20做任何通讯前都需要对其初始化。初始化期间,总线控制器拉低总线并保持480us以上挂在总线上的器件将被复位,然后释放总线,等到15-60us,此时18B20将返回一个60-240us之间的低电平存在信号。
复位脉冲和存在脉冲时序图:
2、写时序
写时序分为写0时序和写1时序。
总线控制器通过控制单总线高低电平持续时间从而把逻辑1或0写DS18B20中。
总线控制器要产生一个写时序,必须将总线拉低最少1us,产生写0时序时总线必须保持低电平60~120us之间,然后释放总线,产生写1时序时在总线产生写时序后的15us内允许把总线拉高。注意:2次写周期之间至少间隔1us
3、读时序
读时序分为读0时序和读1时序。
总线控制器通过读取由DS18B20控制的总线高低电平接收DS18B20数据,总线控制器要产生一个读时序,必须将总线拉低至少1us,然后释放总线,在读信号开始后15us内总线控制器采样总线数据,读一位数据至少保持在60us以上。注意:2次读周期之间至少间隔1us
读时序图:
读1详细时序图:
五、DS18B20暂存器
温度寄存器图表:
配置寄存器图表:
部分ROM指令及功能指令:
执行序列 |
通过单线总线端口访问DS18B20的协议如下: |
步骤1. 初始化 |
步骤2. ROM操作指令 |
步骤3. DS18B20功能指令 |
忽略ROM指令(CCh):
这条指令允许总线控制器不用提供64 位ROM 编码就使用功能指令。例如,总线控制器可以先发出一条忽略ROM 指令,然后发出温度转换指令[44h],从而完成温度转换操作。在单点总线情况下使用该命令,器件无需发回64 位ROM 编码,从而节省了时间。如果总线上有不止一只从机,若发出忽略ROM指令,由于多只从机同时传送信号,总线上就会发生数据冲突。
六、DS18B20功能指令
1、温度转换指令(44h)
这条命令用以启动一次温度转换。温度转换指令被执行,产生的温度转换结果数据以2个字节的形式被存储在高速暂存器中,而后DS18B20保持等待状态。
2、读暂存器指令(BEh)
这条命令读取暂存器的内容。读取将从字节0 开始,一直进行下去,直到读完暂存器所有字节,如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。
3、写暂存器指令(4Eh)
这条命令向DS18B20 的暂存器写入数据,开始位置在TH 寄存器(暂存器的第2个字节),接下来写入TL 寄存器(暂存器的第3 个字节),最后写入配置寄存器(暂存器的第4 个字节)
4、拷贝暂存器指令(48h)
这条命令把TH,TL 和配置寄存器(第2、3、4 字节)的内容拷贝到EEPROM 中。
七、执行序列
通过单线总线端口访问DS18B20的协议如下:
步骤1. 初始化
步骤2. ROM操作指令
步骤3. DS18B20功能指令
温度转换命令
读取暂存器命令
八、DS18B20驱动代码
1、51单片机(数码管显示)
#include <reg52.h>
#include <intrins.h>
#define MAIN_Fosc 11059200UL //宏定义主时钟HZ
/*====================================自定义类型名
====================================*/
typedef unsigned char INT8U;
typedef unsigned char uchar;typedef unsigned int INT16U;
typedef unsigned int uint;/*====================================硬件接口位声明
====================================*/
sbit DS = P2^2; //DS18B20单总线
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
/*====================================
共阴极数码管段选码
====================================*/
uchar code table[]={
//0 1 2 3 4 5 6 7 8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9 A B C D E F - . 关显示
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00};/*====================================
数码管位选码
====================================*///第1位 2位 3位 4位 5位 6位 7位 8位
uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码/*====================================
函数:void Delay_Ms(INT16U ms)
参数:ms,毫秒延时形参
描述:12T 51单片机自适应主时钟毫秒级延时函数
====================================*/
void Delay_Ms(INT16U ms)
{INT16U i;do{i = MAIN_Fosc / 96000; while(--i); //96T per loop}while(--ms);
}
/*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/
void Delay_us(uchar us)
{while(us--);
}
/*====================================
函数:void Display(INT16U Value)
参数:Value,显示值 取值0-65535
描述:共阴极数码管显示函数可显示一个字节的数
====================================*/
void Display(INT16U Value) //注意由于需要显示的数大于一个字节所有形参需为int型
{
//------------------------------DU = 0; //关闭段选P0 = table[Value/100]; //数码管显示百位DU = 1; //打开段选DU = 0; //关闭段选WE = 0; //关闭位选P0 = T_COM[0]; //第一位数码管WE = 1; //打开位选WE = 0; //关闭位选Delay_Ms(3);
//-------------------------------DU = 0;P0 = table[Value%100/10]|0x80; //显示十位DU = 1;DU = 0;WE = 0;P0 = T_COM[1]; //第二位数码管WE = 1;WE = 0;Delay_Ms(3);
//-------------------------------DU = 0;P0 = table[Value%10]; //显示个位DU = 1;DU = 0;WE = 0;P0 = T_COM[2]; //第三位数码管WE = 1;WE = 0;Delay_Ms(3);
}
/*单总线初始化时序*/
bit ds_init()
{bit i;DS = 1;_nop_();DS = 0;Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位DS = 1; //释放总线Delay_us(4); //延时37.95us 等待18B20发回存在信号i = DS;Delay_us(20); //141.95usDS = 1;_nop_();return (i);
}
/*写一个字节*/
void write_byte(uchar dat)
{uchar i;for(i=0;i<8;i++){DS = 0;_nop_();//产生些时序DS = dat & 0x01;Delay_us(10);//76.95usDS = 1; //释放总线准备下一次数据写入_nop_();dat >>= 1;}
}uchar read_byte()
{uchar i, j, dat;for(i=0;i<8;i++){DS = 0;_nop_();//产生读时序DS = 1;_nop_();//释放总线j = DS;Delay_us(10);//76.95usDS = 1;_nop_();dat = (j<<7)|(dat>>1); }return (dat);
}
void main()
{uint i;uchar L, M;
/* ds_init();//初始化DS18B20write_byte(0xcc);//发送跳跃ROM指令write_byte(0x4e);//写暂存器指令write_byte(0x7f);write_byte(0xf7);write_byte(0x1f);//配置工作在9位模式下ds_init();//初始化DS18B20write_byte(0xcc);//发送跳跃ROM指令 write_byte(0x48);*/while(1){ds_init();//初始化DS18B20write_byte(0xcc);//发送跳跃ROM指令write_byte(0x44);//发送温度转换指令ds_init();//初始化DS18B20write_byte(0xcc);//发送跳跃ROM指令write_byte(0xbe);//读取DS18B20暂存器值L = read_byte();M = read_byte();i = M;i <<= 8;i |= L; i = i * 0.0625 * 10 + 0.5;Display(i);}
}
2、51单片机(LCD1602液晶显示)
#include <reg52.H>
#include <intrins.H>
#include <math.H>#define uchar unsigned char#define uint unsigned intsbit dula = P2^6;sbit wela = P2^7;sbit rw = P3^6; sbit RS = P3^5; sbit LCDEN = P3^4; void delayUs()
{_nop_();
}void delayMs(uint a)
{uint i, j;for(i = a; i > 0; i--)for(j = 100; j > 0; j--);}void writeComm(uchar comm)
{RS = 0; P0 = comm;LCDEN = 1;delayUs();LCDEN = 0;delayMs(1);
}//写数据:RS=1, RW=0;
void writeData(uchar dat)
{RS = 1;P0 = dat;LCDEN = 1;delayUs();LCDEN = 0;delayMs(1);}void init(){rw = 0; dula = wela = 0;writeComm(0x38);writeComm(0x0c); writeComm(0x06);writeComm(0x01);
}void writeString(uchar * str, uchar length)
{uchar i;for(i = 0; i < length; i++){writeData(str[i]);}}/**//*****************************DS18B20*******************************/sbit ds = P2^2;
void dsInit(){unsigned int i; ds = 0;i = 100; while(i>0) i--;ds = 1; i = 4;while(i>0) i--;}void dsWait(){unsigned int i;while(ds); while(~ds);i = 4;while(i > 0) i--;
}bit readBit()
{unsigned int i;bit b;ds = 0;i++; ds = 1; i++; i++; b = ds;i = 8; while(i>0) i--;return b;
}unsigned char readByte()
{unsigned int i;unsigned char j, dat;dat = 0;for(i=0; i<8; i++){j = readBit();dat = (j << 7) | (dat >> 1);}return dat;
}void writeByte(unsigned char dat)
{unsigned int i;unsigned char j;bit b;for(j = 0; j < 8; j++){b = dat & 0x01;dat >>= 1;if(b) {ds = 0; i++; i++; ds = 1; i = 8; while(i>0) i--; }else {ds = 0;i = 8; while(i>0) i--; ds = 1;i++; i++;}}
}void sendChangeCmd()
{dsInit(); dsWait(); delayMs(1); writeByte(0xcc);writeByte(0x44);
}void sendReadCmd()
{dsInit();dsWait();delayMs(1);writeByte(0xcc); writeByte(0xbe);
}int getTmpValue()
{unsigned int tmpvalue;int value; float t;unsigned char low, high;sendReadCmd();low = readByte(); high = readByte();tmpvalue = high;tmpvalue <<= 8;tmpvalue |= low;value = tmpvalue;\t = value * 0.0625;\value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5return value;
}void display(int v)
{unsigned char count;unsigned char datas[] = {0, 0, 0, 0, 0};unsigned int tmp = abs(v);datas[0] = tmp / 10000;datas[1] = tmp % 10000 / 1000;datas[2] = tmp % 1000 / 100;datas[3] = tmp % 100 / 10;datas[4] = tmp % 10;writeComm(0xc0+3);if(v < 0){writeString("- ", 2);}else{writeString("+ ", 2);}if(datas[0] != 0){writeData('0'+datas[0]);}for(count = 1; count != 5; count++){writeData('0'+datas[count]);if(count == 2){writeData('.');}}
}
/**//*****************************DS18B20*******************************/void main()
{uchar table[] = " xianzaiwendu: ";sendChangeCmd();init();writeComm(0x80);writeString(table, 16);while(1){delayMs(1000); //温度转换时间需要750ms以上writeComm(0xc0);display(getTmpValue());sendChangeCmd();}
}
3、STM32
#include "stm32f4xx_hal.h"// DS18B20引脚定义
#define DS18B20_GPIO_PORT GPIOA
#define DS18B20_GPIO_PIN GPIO_PIN_0// 定义DS18B20相关命令
#define DS18B20_CMD_SKIP_ROM 0xCC
#define DS18B20_CMD_CONVERT_T 0x44
#define DS18B20_CMD_READ_SCRATCHPAD 0xBE// 函数声明
void DS18B20_DelayUs(uint32_t us);
void DS18B20_Init(void);
uint8_t DS18B20_Reset(void);
void DS18B20_WriteByte(uint8_t byte);
uint8_t DS18B20_ReadByte(void);
float DS18B20_GetTemperature(void);int main(void)
{// 初始化HAL库HAL_Init();// 初始化GPIO引脚__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = DS18B20_GPIO_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStruct);while (1){// 测量温度并输出结果float temperature = DS18B20_GetTemperature();printf("Temperature: %.2f°C\r\n", temperature);// 延时一段时间HAL_Delay(1000);}
}// 微秒级延时函数
void DS18B20_DelayUs(uint32_t us)
{uint32_t ticks = us * (SystemCoreClock / 1000000) / 3;while (ticks--){__NOP();}
}// 初始化DS18B20
void DS18B20_Init(void)
{// 复位DS18B20DS18B20_Reset();// 发送跳过ROM命令DS18B20_WriteByte(DS18B20_CMD_SKIP_ROM);
}// 复位DS18B20并检测设备存在
uint8_t DS18B20_Reset(void)
{uint8_t presence = 0;// 拉低总线HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);DS18B20_DelayUs(480);// 释放总线HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);DS18B20_DelayUs(60);// 检测DS18B20响应presence = HAL_GPIO_ReadPin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN);DS18B20_DelayUs(420);return presence;
}// 发送一个字节给DS18B20
void DS18B20_WriteByte(uint8_t byte)
{for (uint8_t i = 0; i < 8; i++){// 发送低位HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);DS18B20_DelayUs(2);// 发送高位,根据byte的第i位来决定if (byte & (1 << i)){HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);}DS18B20_DelayUs(60);// 释放总线HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);}
}// 从DS18B20读取一个字节
uint8_t DS18B20_ReadByte(void)
{uint8_t byte = 0;for (uint8_t i = 0; i < 8; i++){// 发送低位HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_RESET);DS18B20_DelayUs(2);// 释放总线HAL_GPIO_WritePin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN, GPIO_PIN_SET);DS18B20_DelayUs(8);// 读取高位数据if (HAL_GPIO_ReadPin(DS18B20_GPIO_PORT, DS18B20_GPIO_PIN)){byte |= (1 << i);}DS18B20_DelayUs(50);}return byte;
}// 读取DS18B20温度
float DS18B20_GetTemperature(void)
{DS18B20_Init();// 发送温度转换命令DS18B20_WriteByte(DS18B20_CMD_CONVERT_T);// 等待转换完成HAL_Delay(800);// 复位DS18B20并跳过ROMDS18B20_Init();// 发送读取寄存器命令DS18B20_WriteByte(DS18B20_CMD_READ_SCRATCHPAD);// 读取温度数据uint8_t tempLow = DS18B20_ReadByte();uint8_t tempHigh = DS18B20_ReadByte();// 计算温度值int16_t temp = (tempHigh << 8) | tempLow;float temperature = (float)temp / 16.0f;return temperature;
}
相关文章:

DS18B20的原理及实例代码(51单片机、STM32单片机)
一、DS18B20介绍 DS18B20数字温度传感器是DALLAS公司生产的单总线器件,用它来组成一个测温系统具有线路简单,体积小,在一根通信线上可以挂很多这样的数字温度传感器,十分方便。 温度传感器种类众多,应用在高精度、高可…...
两种单例模式
1.单例模式分为两种,饿汉模式和懒汉模式.以下是饿汉模式: public class SingleTonHungry {private static SingleTonHungry singleTonHungry new SingleTonHungry();private SingleTonHungry() {}public static SingleTonHungry getInstance() {return singleTonHungry;} }2.…...
List中交集的使用
前言 新增了一个需求,需要将所有药品和对应数量库存的药房查询出来,要求:‘所有药品该药房都要有,并且库存大于购药数量’; 这就得考虑一个问题,有的药房有该药品,有的药房没有该药品…...
TypeScript基础篇 - TS的函数
目录 构造函数表达 泛型和函数 泛型函数 Contextual Typing【上下文映射,上下文类型】 泛型约束 手动指定类型 泛型的使用规范 对比 可选参数 思考:onClick中e的设计 函数重载 修改办法 操作符重载 THIS void【空返回值】 思考为什么这样…...

Vue项目如何生成树形目录结构
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、有兴趣的可以关注一手。 前言 项目的目录结构清晰、可以帮助我们更快理顺项目的整体构成。在写文档之类的时候也比较方便。生成树形目录的方式有多种,我这里简单介绍其中一种较为简单的实现 过…...

postgresql四种逻辑复制的状态
准备 CreateCheckpoint,或者bgwriter启动时,或者创建logicalreplicationslot时都会调用LogStandbySnapshot 记录一个XLOG_RUNNING_XACTS类型的日志。日志中记录了所有提交的事务的xid(HistoricSnapshot) 启动(SNAPBUILD_BUILDING_SNAPSHOT&…...
梯度下降法和牛顿法
梯度下降法和牛顿法都是优化方法。 梯度下降法 梯度下降法和相关知识可以参考导数、偏导数、梯度、方向导数、梯度下降、二阶导数、二阶方向导数一文。梯度下降法是一种迭代地每次沿着与梯度相反方向前进的不断降低损失函数的优化方法。梯度下降只用到一阶导数的信息…...

elment-ui的侧边栏 开关及窗口联动
<template><div class"asders"><el-aside width"200px"><div class"boxbody"><div>源码外卖</div><el-switch v-model"isCollapse" :active-value"true" :inactive-value"fals…...

【从零开始学习JAVA | 第三十二篇】 异常(下)新手必学!
目录 前言: Exceptions(异常): 异常的两大作用: 异常的处理方式: 1.JVM默认处理 2.自己捕获异常 3.抛出处理 自定义异常: 异常的优点: 总结: 前言: 前…...

onnxruntime (C++/CUDA) 编译安装
一、克隆及编译 git clone --recursive https://github.com/Microsoft/onnxruntime cd onnxruntime/ git checkout v1.8.0如果克隆的时候报错: 执行以下: apt-get install gnutls-bin git config --global http.sslVerify false git config --global h…...
第三篇-Tesla P40+CentOS-7+CUDA 11.7 部署实践
第一篇-ChatGLM-webui-Windows安装部署-CPU版 第二篇-二手工作站配置 第三篇-Tesla P40CentOS-7CUDA 11.7 部署实践 硬件环境 系统:CentOS-7 CPU: 14C28T 显卡:Tesla P40 24G 准备安装 驱动: 515 CUDA: 11.7 cuDNN: 8.9.2.26 安装依赖 yum clean al…...

Unity游戏源码分享-ARPG游戏Darklight.rar
Unity游戏源码分享-ARPG游戏Darklight.rar 玩法 项目地址:https://download.csdn.net/download/Highning0007/88105464...
类型转换运算符
当我们想要将自定义类的对象转换为目标类型时,我们可以通过重载类型转换运算符(conversion operator)来实现。 以下是一个示例代码,展示了如何在 C 中定义一个自定义类,并重载类型转换运算符将对象转换为目标类型&…...

Kafka 入门到起飞系列 - 消费者组管理、位移管理
消费者组 - Consumer Group 上文我们已经讲过消费者组了,我们知道消费组的存在可以保证一个主题下一个分区的消息只会被组内一个消费者消费,从而避免了消息的重复消费 什么是消费组 - Consumer Group? 消费者组是Kafka 提供的可扩展且具有容…...

SpringBoot——数据层三组件之间的关系
简单介绍 在之前的文章中,我们介绍了一下SpringBoot中内置的几种数据层的解决方案,在数据层由三部分组成,分别是数据库,持久化技术以及数据源,但是我今天写着写着,突然就想不起来这三部分到底是干什么的了…...

LeetCode647.Palindromic-Substrings<回文子串>
题目: 思路: 错误代码:(缺少部分判断) 使用的是寻找回文子串的方法。以一个点为中心向两边扫描。但是有一点小问题。 因为回文子串是分奇偶的,所以需要两种判断方式。 看了下答案后发现我的代码距离答案一…...
React的hooks---useContext
Context 提供了一个无需为每层组件手动添加 props ,就能在组件树间进行数据传递的方法,useContext 用于函数组件中订阅上层 context 的变更,可以获取上层 context 传递的 value prop 值 useContext 接收一个 context 对象(React.…...

【Terraform学习】TerraformCloud入门介绍(快速入门)
TerraformCloud入门介绍 什么是 TerraformCloud? Terraform Cloud是Hashicorp Terraform的SaaS版本。 免费版功能 免费版功能包括版本控制集成、远程计划和实施远程计划和实施、通知及webhook、全http API驱动、状态管理、模拟计划、私有化模块注册器以及全HTTP界…...

linux实现运行java分包部署
1.打好包之后 找到bin文件夹下的 startup.sh文件 2.cd 进入bin文件夹下 3.执行 sh startup.sh 运行命令 4.如果出现此错误 是Windows和Linux的.sh脚本文件格式不同,如果在脚本中有空行,脚本是在Windows下进行编辑之后上传到linux上去执行的话,…...

数据安全之全景图系列——数据分类分级落地实践
1、数据分类分级现状 我们正处于一个数据爆炸式增长的时代,随着产业数字化转型升级的推进,数据已被国家层面纳入生产要素,并且成为企业、社会和国家层面重要的战略资源。数据分类分级管理不仅是加强数据交换共享、提升数据资源价值的前提条件…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...