文章介绍了ESP8266的特性以及连网模式(AP,station),使用串口(USART)接入STM32,实现连网功能。
esp8266 内置超低功耗 Tensilica L106 32 位 RISC 处理器,CPU 时钟速度最高可达 160 MHz,支持实时操作系统 (RTOS) 和 Wi-Fi 协议栈。标准数字外设接口、天线开关、射频 balun、功率放大器、低噪放大器、过滤器和电源管理模块等。低功耗
无线参数 | 值 |
---|---|
无线标准 | 802.11 b/g/n |
频率范围 | 2.4G-2.5G(2400M-2483.5M) |
发射功率 | 802.11 b: 20 dBm;802.11 g: 17 dBm;802.11 n: 14 dBm |
接收灵敏度 | 802.11 b: (11Mbps) -91db;802.11 g: (54Mbps) -75db;802.11 n: (MCS7) -72db |
硬件参数 | 值 |
---|---|
数据接口 | UART、PWM、 GPIO |
工作电压 | 3.3V |
工作电流 | 平均电流 80mA |
工作温度 | -40° ~125° |
软件参数 | 值 |
---|---|
无线网络模式 | station/softAP/SoftAP+station |
安全机制 | WPA/WPA2 |
加密类型 | WEP/TKIP/AES |
UART成帧
ESP8266 判断 UART 传来的数据时间间隔,若时间间隔大于 20ms, 则认为一帧结束;否则, 一直接收数据到上限值 2KB, 认为一帧结束。 ESP8266 模块判断UART 来的数据一帧结束后, 通过 WIFI 接口将数据转发出去。
成帧时间间隔为 20ms, 一帧上限值为 2KB。
ESP8266 支持 softAP 模式, station 模式, softAP + station 共存模式三种。
SoftAP: 即无线接入点, 是一个无线网络的中心节点,类似于无线路由器。手机 用户设备、 其他 ESP8266 station 接口等均可以作为 station 连入ESP8266, 组建成一个局域网。(透传)
Station:即无线终端, 是一个无线网络的终端。
通过连接路由器(AP) 连入 internet ,可向云端服务器上传、 下载数据。用户可随时使用移动终端(手机、 笔记本等) ,通过云端连接ESP8266。
网络相关的模块,比如4G、lora等模块都有AT指令,使用AT指令配置模块,ESP8266的AT指令如下
分类 | 指令格式 | 指令功能 |
---|---|---|
测试命令 | AT+=? | 该命令用于查询设置命令或内部程序设置的 |
查询命令 | AT+? | 该命令用于返回参数的当前值 |
设置命令 | AT+=<…> | 该命令用于设置用户自定义的参数值 |
执行命令 | AT+ | 该命令用于执行受模块内部程序控制的变参 |
基础指令
命令 | 说明 |
---|---|
AT | 测试 AT 启动 |
AT+RST | 重启模块 |
AT+GMR | 查看版本信息 |
wifi 功能指令
命令 | 说明 |
---|---|
AT+CWMODE | 选择 WIFI 应用模式 |
AT+CWJAP | 加入 AP |
AT+CWLAP | 列出当前可用 AP |
AT+CWQAP | 退出与 AP 的连接 |
AT+CWSAP | 设置 AP 模式下的参数 |
AT+ CWLIF | 查看已接入设备的 IP |
TCP/IP 指令
命令 | 说明 |
---|---|
AT+CIPSTATUS | 获得连接状态 |
AT+CIPSTART | 建立 TCP 连接或注册 UDP 端口号 |
AT+CIPSEND | 发送数据 |
AT+CIPCLOSE | 关闭 TCP 或 UDP |
AT+CIFSR | 获取本地 IP 地址 |
AT+CIPMUX | 启动多连接 |
AT+CIPSERVER | 配置为服务器 |
AT+CIPMODE | 设置模块传输模式 |
AT+CIPSTO | 设置服务器超时时间 |
RST复位引脚,与CH_PD片选引脚,在模式初始化阶段使用。RST拉高,CH_PD先复位 再置位,模块正常工作。采用串口方式与STM32进行通信,使用串口中断,有数据时,去读取数据。
// CH_PD引脚
// Enables or disables the High Speed APB (APB2) peripheral clock
#define macESP8266_CH_PD_APBxClock_FUN RCC_APB2PeriphClockCmd
//RCC_APB2Periph: specifies the APB2 peripheral to gates its clock
#define macESP8266_CH_PD_CLK RCC_APB2Periph_GPIOB
//PORT
#define macESP8266_CH_PD_PORT GPIOB
//PIN
#define macESP8266_CH_PD_PIN GPIO_Pin_8
RST引脚
#define macESP8266_RST_APBxClock_FUN RCC_APB2PeriphClockCmd
#define macESP8266_RST_CLK RCC_APB2Periph_GPIOB
#define macESP8266_RST_PORT GPIOB
#define macESP8266_RST_PIN GPIO_Pin_9
//
static void ESP8266_GPIO_Config ( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE );
//CH_PD引脚
GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure );
//RST引脚
macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE );
GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN;
GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure );
}
#define macESP8266_USART_BAUD_RATE 115200
#define macESP8266_USARTx USART3
#define macESP8266_USART_APBxClock_FUN RCC_APB1PeriphClockCmd
#define macESP8266_USART_CLK RCC_APB1Periph_USART3
#define macESP8266_USART_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define macESP8266_USART_GPIO_CLK RCC_APB2Periph_GPIOB
//发送TX
#define macESP8266_USART_TX_PORT GPIOB
#define macESP8266_USART_TX_PIN GPIO_Pin_10
//接受RX
#define macESP8266_USART_RX_PORT GPIOB
#define macESP8266_USART_RX_PIN GPIO_Pin_11
//中断
#define macESP8266_USART_IRQ USART3_IRQn
#define macESP8266_USART_INT_FUN USART3_IRQHandler
extern struct STRUCT_USARTx_Fram //´¿ÚÊý¾ÝÖ¡µÄ´¦Àí½á¹¹Ìå
{
char Data_RX_BUF [ RX_BUF_MAX_LEN ];
union {
__IO u16 InfAll;
struct {
__IO u16 FramLength :15; // 14:0
__IO u16 FramFinishFlag :1; // 15
} InfBit;
};
} strEsp8266_Fram_Record;
struct STRUCT_USARTx_Fram strEsp8266_Fram_Record = {
0 };
//USART 的 NVIC中断
static void ESP8266_USART_NVIC_Configuration ( void )
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x );
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
static void ESP8266_USART_Config ( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* config USART clock */
macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE );
macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE );
/* USART GPIO config */
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = macESP8266_USART_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure);
/* USART1 mode config */
USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(macESP8266_USARTx, &USART_InitStructure);
/* 中断配置 */
USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断
USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口空闲中断
ESP8266_USART_NVIC_Configuration ();
USART_Cmd(macESP8266_USARTx, ENABLE);
}
void macESP8266_USART_INT_FUN ( void )
{
uint8_t ucCh;
//获取RX中断状态
if ( USART_GetITStatus ( macESP8266_USARTx, USART_IT_RXNE ) != RESET )
{
ucCh = USART_ReceiveData( macESP8266_USARTx );//接收数据
if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) ) //长度判断
//向BUF缓冲区中写入数据ucCh,FramLength 在不断增加
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ] = ucCh;
}
//获取IDEL中断状态 ,数据帧接收完毕
if ( USART_GetITStatus( macESP8266_USARTx, USART_IT_IDLE ) == SET )
{
strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;//条件置位
ucCh = USART_ReceiveData( macESP8266_USARTx );
ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;
}
}
ESP8266的一般使用顺序,ESP8266连接当前环境的热点,与服务器建立TCP连接,传输数据。
AT+CWMODE=1:设置工作模式(STA模式)
AT+RST:模块重启(生效工作模式)
AT+CWJAP=“111”,“11111111”:连接当前环境的WIFI热点(热点名,密码)
AT+CIPMUX=0:设置单路连接模式
AT+CIPSTART=“TCP”,“xxx.xxx.xxx.xxx”,xxxx:建立TCP连接
AT+CIPMODE=1:开启透传模式
AT+CIPSEND:透传模式下,传输数据
+++:退出透传模式
程序的主处理流程
void ESP8266_StaTcpClient_UnvarnishTest ( void )
{
uint8_t ucStatus;
char cStr [ 100 ] = {
0 };
//使能PD_CH
macESP8266_CH_ENABLE();
//AT测试
ESP8266_AT_Test ();
//选择网络模式
ESP8266_Net_Mode_Choose ( STA );
//连接AP
while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );
//启动多连接关闭
ESP8266_Enable_MultipleId ( DISABLE );
//连接服务器IP 端口号
while ( ! ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );
//设置模式进入透传模式
while ( ! ESP8266_UnvarnishSend () );
while ( 1 )//进入循环
{
//此处可以修改数据源,此处为一串字符串,也可以是从开发版上获取传感器数据,比如温湿度传感器
sprintf ( cStr,"ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n" );
ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 ); //发送数据
Delay_ms ( 100 );
if ( ucTcpClosedFlag ) //检测是否丢失链接
{
ESP8266_ExitUnvarnishSend (); //如果丢失,退出透传模式
do ucStatus = ESP8266_Get_LinkStatus (); //获取链接状态
while ( ! ucStatus );
if ( ucStatus == 4 ) //失去链接后重连
{
while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );
while ( !ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );
}
while ( ! ESP8266_UnvarnishSend () );
}
}
发送AT指令函数
/*
cmd:待发送的命令,
reply1,reply2期待的回复
waittime 等待时间
*/
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{
strEsp8266_Fram_Record .InfBit .FramLength = 0; //数据长度置零
macESP8266_Usart ( "%s\r\n", cmd );
if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //没有收到数据
return true;
Delay_ms ( waittime ); //延时函数
//中断接收函数
strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0';
macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF );
if ( ( reply1 != 0 ) && ( reply2 != 0 ) )
return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ||
( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
else if ( reply1 != 0 )
return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );
else
return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
}
选择NET模式
bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{
switch ( enumMode )
{
case STA:
return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 );
case AP:
return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 );
case STA_AP:
return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 );
default:
return false;
}
}
链接wifi, AT+CWJAP
/*
pSSID用户名
pPassWord 密码
*/
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{
char cCmd [120];
sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );
return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );
}
连接外部服务器 AT+CIPSTART
bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
{
char cStr [100] = {
0 }, cCmd [120];
switch ( enumE )
{
case enumTCP:
sprintf ( cStr, "\"%s\",\"%s\",%s", "TCP", ip, ComNum );
break;
case enumUDP:
sprintf ( cStr, "\"%s\",\"%s\",%s", "UDP", ip, ComNum );
break;
default:
break;
}
if ( id < 5 )
sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr);
else
sprintf ( cCmd, "AT+CIPSTART=%s", cStr );
return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );
}
获取链接状态AT+CIPSTATUS
uint8_t ESP8266_Get_LinkStatus ( void )
{
if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) )
{
if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) )
return 2;
else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) )
return 3;
else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) )
return 4;
}
return 0;
}
发送数据"AT+CIPSEND=
/*
返回值
1,发送成功
0,发送失败
*/
bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{
char cStr [20];
bool bRet = false;
if ( enumEnUnvarnishTx )
{
macESP8266_Usart ( "%s", pStr );
bRet = true;
}
else
{
if ( ucId < 5 )
sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 );
else
sprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 );
ESP8266_Cmd ( cStr, "> ", 0, 1000 );
bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 );
}
return bRet;
}
主函数
void ESP8266_Init ( void )
{
ESP8266_GPIO_Config ();
ESP8266_USART_Config ();
macESP8266_RST_HIGH_LEVEL();
macESP8266_CH_DISABLE();
}
int main ( void )
{
USARTx_Config ();//串口打印函数
SysTick_Init ();//系统时钟初始化
ESP8266_Init ();//esp8266初始化
ESP8266_StaTcpClient_UnvarnishTest ();
while ( 1 );
}
实验现象
通过网络助手,收到开发版发来的数据
模块作为AP的配置
ESP8266_AT_Test ();
ESP8266_Net_Mode_Choose ( AP );
//设置模块的IP
while ( ! ESP8266_CIPAP ( macUser_ESP8266_TcpServer_IP ) );
//创建模块热点
while ( ! ESP8266_BuildAP ( macUser_ESP8266_BulitApSsid, macUser_ESP8266_BulitApPwd, macUser_ESP8266_BulitApEcn ) );
//模块启动多连接
ESP8266_Enable_MultipleId ( ENABLE );
//模块开启或关闭服务器
while ( ! ESP8266_StartOrShutServer ( ENABLE, macUser_ESP8266_TcpServer_Port, macUser_ESP8266_TcpServer_OverTime ) );
//ESP8266 获取 AP IP
ESP8266_Inquire_ApIp ( cStr, 20 );
参考
《ESP8266_用户手册_V0.3.pdf》
《ESP8266 Non-OS SDK AT 指令集.pdf》
《野火YH-ESP8266模块用户手册.pdf》
《野火提供的esp8266源码》
文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别
文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具
文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量
文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置
文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖
文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...
文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序
文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码
文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型
文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件
文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令
文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线