S5PV210体系结构与接口12:I2C编程
目录
1. I2C总线工作原理
1.1 概述
1.2 总线寻址
1.2.1 7位地址模式
1.2.2 从设备地址的确定
1.2.3 10位地址模式
1.3 总线时序
1.3.1 空闲态 & start信号 & stop信号
1.3.2 数据传输格式
1.3.3 ACK信号
1.3.4 拉低SCL线
2. S5PV210 I2C模块解析
2.1 特点概述
2.2 结构解析
2.2.1 I2C总线控制逻辑
2.2.2 I2C时钟模块
2.2.3 移位寄存器
2.2.4 地址寄存器 & 比较器
2.3 核心寄存器解析
2.3.1 I2CCON
2.3.2 I2CSTAT
2.3.3 I2CADD
2.3.4 I2CDS
2.4 I2C controller通信时序
2.4.1 主机发送器
2.4.2 主机接收器
2.4.3 从机发送器
2.4.4 从机接收器
3. gsensor通信时序
4. S5PV210 I2C程序设计
4.1 i2c_init函数
4.2 i2c_start_transfer函数
4.3 i2c_restart_transfer函数
4.4 i2c_stop_transfer函数
4.5 i2c_write_byte
4.6 i2c_read_byte
4.7 i2c_read_last_byte
4.8 测试用例
4.8.1 gsensor_read_ct_resp函数
4.8.2 gsensor_read_write_ctrl_reg函数
4.9 验证结果
1. I2C总线工作原理
1.1 概述
I2C(Inter Integrated Circuit)总线是Philips公司开发的两线式串行总线,一般用于连接SoC及其外围设备
I2C总线只有两根信号线,
SCL(serial clock):时钟线,用于master向slave提供时钟信号
SDA(serial data):数据线,用于master & slave双向传输数据
注意:I2C总线上的各器件都采用漏极开路结构与总线相连,所以SCL & SDA均需接上拉电阻,使得总线在空闲状态下均保持高电平
说明1:I2C总线传输特点
串行:按字节组织从MSB开始传输
同步:由master提供时钟信号
支持速率:标准模式下可达100 kbps / 快速模式下可达400 kbps / 高速模式下可达3.4 mbps
注意:在编程时需要同时考虑SoC I2C controller & 外设芯片的通信速率上限确定实际速率
说明2:通信角色
主机:产生时钟信号并发出start & stop信号的设备(控制整个传输流程)
从机:被主机寻址的设备
发送器:发送数据到总线的设备
接收器:从总线接收数据的设备
根据上面两组分类可知在I2C通信过程中有4种通信角色:
主机发送器 / 主机接收器 / 从机发送器 / 从机接收器
在实际使用中,SoC的I2C controller一般作为主机使用
说明3:主从模式
主从模式是I2C总线最常见的工作模式,此时系统由1个主机 + n个(n >= 1)从机组成,此时需要注意2个问题,
① 主机通过总线上唯一的从设备地址寻址不同从机
② 连接到一条I2C总线上的设备数量只受到总线最大电容400pF的限制
说明4:多主模式与总线仲裁
多主模式就是在一条I2C总线上有多个主机,但是任一时刻总线上只能有一台主机,所以为支持多主模式,I2C总线具备总线仲裁能力,具体有如下2种情况:
① 2个主机并非同时拉低SDA线
由于SDA闲时为高电平,因此如果一个高电平SDA主机检测到一个低电平SDA主机,则该主机不会发送数据,因为当前的总线状态与自己的不匹配。该仲裁过程会一直延续到SDA转换为高电平。
② 2个主机同时拉低SDA线
如果2个主机同时将SDA线置为低电平,每个主机都会判断是非是自己占据总线,因此每个主机会检测发出的从设备地址。由于每个主机在发送比特位的同时也在检测总线电平(这点和CAN总线类似),所以主机要通信的从设备地址中先出现低电平的将优先获得总线控制权。而由于一条I2C总线上的从设备地址是唯一的,所以这种方案始终有效,即可以在地址位结束前判定总线的归属权。
个人存疑:如果2个主机与同一个从机通信,则在地址位阶段无法判断总线归属权
1.2 总线寻址
1.2.1 7位地址模式
I2C通信中最常用的是7位地址模式,其中,
D7 ~ D1为从设备地址
D0为数据传送方向,其中
0:master --> slave(transmit)
1:slave --> master(receive)
当主机发送从机地址时,总线上的每个从机都将这7位地址与自己的地址进行比较,以确定是否被寻址;然后根据D0位将自己确认为发送器或接收器
1.2.2 从设备地址的确定
I2C总线采用了从设备地址的硬件设置方法,通过软件寻址完全避免了期间的片选线寻址方法(与其对应,SPI总线就采用片选信号寻址)
在具体实现中,一般分为如下2种形式,
1.2.1.1 芯片完全固定
以X210开发板的gsensor为例,该芯片I2C从设备地址完全由芯片内部确定为0b0001111,芯片外部并无可配置地址信息的引脚
需要注意的是,这类芯片在一条I2C总线上只能使用一片,使用多片时会导致地址冲突,所以这种地址确定策略适用于每个系统只需要使用一片该类芯片的场合。
1.2.1.2 固定部分 + 用户自定义部分
以mini2440开发板的EEPROM为例,该芯片的从设备地址由固定部分和用户自定义部分组成。其中D7 ~ D4由芯片生产商指定,D3 ~ D1对应设备的3个引脚(A2 ~ A0),把这3个引脚接到不同的电平上就可以形成一个3位的数值
这种地址确定策略适用于每个系统中,可能使用多片该类芯片的场合
1.2.3 10位地址模式
10位地址模式是对7位地址模式的扩充,在7位地址模式中,start信号之后的1个字节被认为是寻址信息;在10位地址模式中,start信号之后的2个字节被认为是寻址信息,具体每位含义如下,
说明:10位寻址和7位寻址是兼容的,所谓兼容,就是在一条I2C总线上,可以同时使用7 bit地址的设备和10 bit地址的设备,I2C从协议规范的角度进行了保证
下表为I2C设备的保留地址
可见10-bit slave addressing模式是保留地址的一部分
1.3 总线时序
1.3.1 空闲态 & start信号 & stop信号
① I2C总线处于空闲态时,SCL & SDA均处于高电平
② start信号是一个时间段,在这段时间内总线状态为:
SCL维持高电平 && SDA发生从高到低的下降沿
主机发出start信号后,I2C总线被占据
③ stop信号也是一个时间段,在这段时间内总线状态为:
SCL维持高电平 && SDA发生从低到高的上升沿
主机发出stop信号后,I2C总线被释放,SCL & SDA回到高电平状态
1.3.2 数据传输格式
① 主机在发出start信号后,发送寻址 + 读写方向信息
② 发送器在每发送一个字节后,接收器必须回复一个ACK信号,标识该字节发送成功。注意此处回复ACK信号的角色,只要是处于接收状态,无论主从均要回复ACK信号
③ 发送到SDA线上的每个字节必须是8位,但是在start & stop信号之间可传输的字节数不受限制
④ 传输从MSB开始
1.3.3 ACK信号
下面就来分析下回复ACK信号的具体时序,
需要注意的是,通信所用的SCL信号始终是由主机产生的。发送器在发送完一个字节后,会在第9个CLK释放SDA线,此时接收器需要在该CLK将SDA线拉低,这就是所谓的ACK信号
如果接收端没有回复ACK信号(协议中称为NACK)会怎样呢 ?
结合上文分析,在I2C通信中有2种处于接收状态的角色,即主机接收器和从机接收器,这二者产生NACK的含义是不同的,
① 从机接收器
如果从机接收器未能回复ACK信号,则表示该字节传输失败,此时主机需要发出stop信号终止此次传输
② 主机接收器
主机接收器不回复ACK信号是一种主动行为,用以终止此次传输。当主机接收器接收完最后一个字节后,可设置寄存器不产生ACK信号,此时从机发送器会释放SDA线供主机产生stop信号
补充:数据状态改变
SDA线上的数据在时钟高电平期间必须稳定,只有当SCL线上的时钟信号为低电平时,SDA线的状态才可以改变(这样也就能识别出start & stop信号)
1.3.4 拉低SCL线
在I2C总线的传输过程中,发送器 和/或 接收器可以拉低SCL暂停传输,下面就分析一下拉低SCL线的场景:
首先需要注意的是,SoC内部均采用并行传输,比如CPU和I2C controller寄存器之间的交互。但是I2C作为一种串行总线,需要移位器实现串并转换。
① 发送器
在数据写入数据寄存器(S5PV210中为I2CDS)之前拉低SCL线
② 接收器
在数据寄存器(S5PV210中为I2CDS)中的数据被读取之前拉低SCL线
需要注意的是,不只是主机可以拉低SCL线暂停传输,从机也可以拉低SCL线。这种情况主要发生在从机希望主机降低传输速度,由于SCL线被从机拉低,当主机要接着发送数据时则必须等待SCL线被释放,这就是I2C的时钟同步
2. S5PV210 I2C模块解析
2.1 特点概述
① 提供四通道多主 / 从I2C接口,其中一路内部连接HDMI PHY,其余三路通用
② 7位地址模式
③ 串行8位双向数据传输
④ 标准模式下支持最高100kbps传输速率
⑤ 高速模式下支持最高400kpbs传输速率
⑥ 支持所有通信角色:主机发送 / 主机接收 / 从机发送 / 从机接收
⑦ 支持中断或轮询访问模式
2.2 结构解析
2.2.1 I2C总线控制逻辑
操作接口为I2CCON & I2CSTAT寄存器,主要负责产生I2C通信时序。实际编程中要发送start信号、stop信号、设置ACK响应均通过这2个寄存器实现
2.2.2 I2C时钟模块
I2C模块时钟源为PCLK_PSYS,经过内部两级分频最终得到I2C控制器的CLK,通信中这个CLK会通过SCL线传送给从设备(如果SoC的I2C controller做主机)
2.2.3 移位寄存器
SoC内部数据总线为并行传输,而I2C总线上为串行传输。如果有数据要发送,首先将数据写入I2CDS,在移位寄存器的作用下,会从MSB开始传输I2CDS中的数据;如果有数据要接收,从SDA线接收到的比特位也是在移位寄存器的作用下组装为字节数据,CPU只需读取I2CDS寄存器即可
2.2.4 地址寄存器 & 比较器
如果SoC的I2C controller做从机,需要将从设备地址写入地址寄存器,而地址比较器则是负责对比SDA线上传输的从机地址与本机地址,如果一致则会产生相应中断提示I2C controller
2.3 核心寄存器解析
2.3.1 I2CCON
说明1:ACK响应设置
注意发送模式和接收模式下设置ACK响应位的作用不同,但目的都是为了符合I2C通信协议
发送模式:在第9个CLK释放SDA线
接收模式:在第9个CLK拉低SDA线
说明2:I2C通信速率设置
I2C通信速率由两级分频构成,其中第一级为固定系数分频,第二级为4bit分配器。在设置I2C通信速率时要同时参考SoC的I2C controller属性和I2C从设备芯片属性
以X210开发板配备的gsensor为例,该芯片支持的最高通信速率为400kHz
说明3:I2C中断产生时机
S5PV210的I2C controller在3种情况下会产生中断,
① 一个字节的数据收发结束,即ACK周期结束(注意,这里是ACK周期结束,而不一定要收到ACK响应,是否收到ACK响应可以通过I2CSTAT寄存器判断)
② 当I2C controller作为从机时,接收到general call或从设备地址匹配成功
③ 总线仲裁失败
这里需要补充说明下I2C的general call是啥~
在I2C通信协议中有一种称为general call的广播方式,即主机发出的从设备地址为0b0000000,此时I2C总线上的所有从机均要对此作出响应
还有一点需要注意,此处是写0清pend~
说明4:中断源端使能的重要性
当使用轮询访问模式时,轮询的就是I2CCON寄存器的bit 4,即中断挂起位。但是如果不使能I2C中断(即不设置I2CCON寄存器的bit 5),中断挂起位无法正常工作。所以在S5PV210的I2C controller工作流程中,中断源端使能中断是必须步骤
经过验证,确实只要中断源端使能中断即可,VIC端可以不使能
2.3.2 I2CSTAT
说明1:通信角色选择
在发出start信号前或同时需要设置I2C controller在此次通信中的角色
说明2:只要设置I2CSTAT就会发出信号(主机模式下)
根据bit 5的定义,当I2C controller作为主机时,向该位写0会发出stop信号;向该位写1会发出start信号
说明3:四种中断状态
I2CSTAT寄存器的bit [3:0]用于标识不同的中断状态,具体如下,
Arbitration status:发生总线仲裁失败
Address-as-slave status:从设备地址匹配
Address zero status:接收到general call
Last-received bit status:
当I2C controller的通信角色为从机发送器时,当发生NACK时,说明主机接收器已接收最后一个字节,通过NACK终止传输
当I2C controller的通信角色为主机发送器时,当发生NACK时,说明该字节传输失败,此时主机发送器要发出stop信号终止传输
2.3.3 I2CADD
当I2C controller作为从机时,从设备地址需要写入I2CADD寄存器的bit [7:1]。需要注意的是,只有I2CSTAT寄存器的serial output位为0时才可写入从设备地址
2.3.4 I2CDS
I2C通信中的数据读写就是对I2CDS寄存器的操作,但是只有I2CSTAT寄存器的serial output位为1时,I2CDS寄存器才可写
2.4 I2C controller通信时序
在说明I2C controller通信时序之前,需要明确2个问题,
① 在编程通过I2C总线读写数据时,需要同时参考I2C controller & 从设备芯片的通信时序
② 无论I2C controller的通信角色,如下步骤是必须执行的
step 1:如果I2C controller作为从设备,将从设备地址写入I2CADD寄存器(该寄存器必须在disable serial output的情况下写入)
step 2:设置I2CCON寄存器,使能中断 + 设置通信速率
step 3:设置I2CSTAT寄存器,enable serial output(只有enable serial output才能写I2CDS寄存器)。由于只要设置I2CSTAT寄存器就会发出start或stop信号,此处要确保发出的是stop信号
2.4.1 主机发送器
说明1:start & stop信号的发出
根据上文分析,每次设置I2CSTAT寄存器时都会导致发出start或stop信号,需要注意的是,在实际开启发送前,在设置主机发送器的通信角色时要确保发出的是stop信号
说明2:操作先后顺序
将要发送的数据写入I2CDS寄存器和清pend之间是有明确先后关系的,因为清pend会开启下一个字节的移位发送,所以必须在此之前将要发送的数据写入I2CDS寄存器
2.4.2 主机接收器
此处的注意事项与主机发送器一致,只是在清pend前是读I2CDS寄存器(这个理解其实是有问题的,后续代码实例中将说明)
至此,我们就可以拆分一下主机模式下的相关操作,并以伪代码实现
void i2c_init(void)
{GPIO设置I2CCON设置(使能中断 + 时钟设置)I2CSTAT设置(enable serial output,注意是发出stop信号)
}void i2c_start_transfer(int direction)
{I2CCON设置(使能ACK响应)if (direction == 0) {I2CSTAT设置(设置主机发送通信角色,注意是发出stop信号)I2CDS = 从设备地址 + 发送位I2CSTAT设置(写入0xF0,开启发送)}else {I2CSTAT设置(设置主机接收通信角色,注意是发出stop信号)I2CDS = 从设备地址 + 接收位I2CSTAT设置(写入0xB0,开启发送)}轮询中断挂起
}void i2c_write_byte(nsigned char data)
{I2CDS = data清中断挂起(恢复发送)轮询中断挂起
}unsigned char i2c_read_byte(void)
{unsigned char ret = I2CDS (操作顺序有问题)清中断挂起(恢复传输)轮询中断挂起
}unsigned char i2c_read_last_byte(void)
{I2CCON设置(禁用ACK响应)unsigned char ret = I2CDS(操作顺序有问题)清中断挂起(恢复传输)轮询中断挂起
}void i2c_stop_transfer(int direction)
{if (direction == 0)I2CSTAT = 0xD0elseI2CSTAT = 0x90清中断挂起(恢复发送)等待stop信号生效(可用延时实现)
}
2.4.3 从机发送器
说明1:从设备地址匹配
当I2C controller作为从设备时,在初始化阶段会将从设备地址写入I2CADD寄存器,然后将通信角色设置为从机发送器。此时I2C controller会监听总线,并对比自身从设备地址与start信号后主机发送的寻址信息
说明2:从机发送器如何判断何时stop?
这就需要借助NACK机制,当主机接收器接收最后一个字节时,会设置不回复ACK信号。从机发送器在轮询中断挂起后,可以根据I2CSTAT寄存器判断是否收到ACK响应,如果没有收到则说明数据交互stop
2.4.4 从机接收器
作为从机接收器,何时stop就是由主机发送器决定了,从机接收器只要按协议回复ACK即可。
这里值得说明的是从机如何拉低SCL线,在清中断挂起之前,实际从机是将SCL拉低的,以阻止主机发送数据(主机接收器实际也有这个过程)
所以和SPI总线相比,I2C的SCL & SDA线均为双向的,I2C总线上的设备无论主从均可以拉低SCL来暂停传输;但是SPI总线的时钟只是master发送给slave,其间并无时钟同步机制
3. gsensor通信时序
如前文所述,在编程通过I2C总线读写数据时,需要同时参考I2C controller & 从设备芯片的通信时序,下面就来说明下gsensor芯片的读写时序
此处向gsensor芯片内部寄存器写入数据的流程比较简单,从gsensor芯片内部寄存器读取数据时需要注意如下3点:
① 首先要向gsensor芯片写入要读取的内部寄存器地址
② 在I2C controller的通信角色从主机发送器转换到主机接收器时,需要发送repeated start信号
③ 在读取最后一个字节时不回复ACK信号(即NACK)
4. S5PV210 I2C程序设计
X210配套的gsensor芯片可供读取的寄存器列表如下,
我们首先尝试读取CT_RESP寄存器的值,然后尝试读-修改-读CTRL_REG2寄存器的值,下面我们来分析下这2个寄存器的状态
① CT_RESP寄存器
该寄存器为只读寄存器,读取时应返回0x55
② CTRL_REG2寄存器
该寄存器为读写寄存器,读取时应返回0x3F,之后我们向其中写入0xAA,由于该寄存器的bit [7:6]强制为零,再次读取时应返回0x2A
4.1 i2c_init函数
i2c_init函数的实现与之前伪代码中描述的一致,需要注意的是在使能serial output时实际上会发出stop信号
4.2 i2c_start_transfer函数
经过上机验证,可以省略单独设置I2C controller通信角色的步骤,而且该步骤的副作用是会发出stop信号
4.3 i2c_restart_transfer函数
根据上文介绍的gsensor通信时序,I2C controller在读取gsensor内部寄存器时需要发出repeated start信号进行通信角色的转换。与i2c_start_transfer函数相比,i2c_restart_transfer函数有2点不同:
① 无需设置I2CCON寄存器的ACK响应位
② 设置I2CSTAT寄存器后需要清中断挂起以恢复发送(其实就相当于一次写字节流程)
4.4 i2c_stop_transfer函数
i2c_stop_transfer函数在设置完I2CSTAT寄存器后也需要清中断挂起以恢复发送,最后通过延时等待stop信号生效(当然,此处也可以轮询中断挂起状态)
经过上机验证,此处认为在发出stop信号后可以轮询中断挂起状态的想法是错误的,轮询的结果就是一直死循环,也就是一旦发出stop信号后整个I2C总线就回到空闲状态了
后续又进行相关验证,即使不调用sleep_loop函数进行延时,发出stop信号后整个I2C总线行为仍然正常
4.5 i2c_write_byte
i2c_write_byte函数的重点就是写I2CDS寄存器与清中断挂起的顺序,由于清中断挂起会开启新一轮的移位输出,所以在此之前需要将要发送的数据写入I2CDS寄存器
4.6 i2c_read_byte
i2c_read_byte函数就精彩了,根据S5PV210芯片手册,需要先读I2CDS寄存器再清中断挂起,国嵌课程中也是按此顺序操作,但是提到读取的第一个字节是错误的需要丢弃
其实如果能理解清中断挂起的作用就是开启一次传输,那么很明显在读取一个字节时,应该先清中断挂起以开启传输,然后轮询中断挂起等待一个字节的传输完成,最后才是读取I2CDS寄存器
4.7 i2c_read_last_byte
当I2C controller作为主机接收器时,i2c_read_last_byte函数用于读取最后一个字节,实现的关键就是读取最后一个字节时不回复ACK信号
而且在此函数中还实际验证了先读取I2CDS寄存器,后清中断挂起的操作顺序是错误的
4.8 测试用例
4.8.1 gsensor_read_ct_resp函数
注意其中调用i2c_restart_transfer函数实现通信角色从主机发送器到主机接收器的转换
4.8.2 gsensor_read_write_ctrl_reg函数
有了上面的分析,这个函数的理解就so easy了~
4.9 验证结果
根据串口打印,可见程序运行结果与上述分析一致~
S5PV210体系结构与接口12:I2C编程相关推荐
- S5PV210体系结构与接口11:NandFlash SD卡编程
目录 1. Flash ROM简介 1.1 概述 1.2 Nor & Nand Flash比较 1.2.1 接口对比 1.2.2 容量和成本对比 1.2.3 可靠性对比 1.2.4 使用寿命对 ...
- S5PV210体系结构与接口06:串口编程
目录 1. 串口通信基本概念 1.1 通信基础概念 1.1.1 电平信号 & 差分信号 1.1.2 串行通信 & 并行通信 1.1.3 异步串行通信 & 同步串行通信 1.2 ...
- S5PV210体系结构与接口08:定时器 计数器编程
目录 1. S5PV210 PWM模块解析 1.1 结构概述 1.1.1 时钟选择 1.1.2 两级分频 1.1.3 输出特征 1.2 工作模式 1.2.1 工作流程 1.2.2 TCNT & ...
- S5PV210体系结构与接口07:中断系统编程
目录 1. 什么是按键 1.1 按键原理与连接 1.2 按键的2种响应方式 1.2.1 轮询方式 1.2.2 中断方式 1.3 轮询方式处理按键解析 1.4 按键消抖 1.4.1 按键抖动 1.4.2 ...
- S5PV210体系结构与接口05:时钟系统编程
目录 1. 时钟概念解析 1.1 什么是时钟? 1.2 为什么需要时钟? 1.3 如何获得时钟? 1.3.1 外部晶振 1.3.2 外部晶振 + SoC内部CMU(Clock Management U ...
- S5PV210体系结构与接口03:GPIO编程
目录 1. GPIO功能简介 1.1 什么是GPIO? 1.2 GPIO作用 1.3 GPIO的构成(data sheet层面) 2. S5PV210芯片GPIO控制器简介 2.1 总额及分类 2.2 ...
- S5PV210体系结构与接口02:ARM编程模型 汇编指令
目录 1. ARM的基本设定 1.1 ARM数据类型 1.1.1 基本数据类型 1.1.2 浮点数据类型 1.1.3 存储器大小端 1.2 支持的指令集 2. Cortex-A8编程模型 2.1 处理 ...
- S5PV210体系结构与接口10:MMU编程
目录 1. MMU概述 1.1 VMSA概述 1.2 MMU作用 2. MMU地址转换详解 2.1 总体流程图示 2.1.1 概述 2.1.2 设置TTB相关寄存器 2.2 一级页表解析 2.2.1 ...
- S5PV210体系结构与接口09:SD卡启动详解
目录 1. MMC技术演进 1.1 NandFlash & NorFlash芯片 1.2 MMC卡 & SD卡 & MicroSD卡(TF卡) 1.2.1 代际关系 1.2.2 ...
最新文章
- 代码详解:Numpy——通往人工智能的大门
- CLR Via C# 3rd 阅读摘要 -- Chapter 24 – Runtime Serialization
- android drawpath大小,Android Path和PathMeasure
- QT的QStateMachine类的使用
- PHP经典文:服务容器
- H5各种头部meta标签的功能
- CRM呼叫中心里的Java stack
- P10全彩屏C语言编程,STC90C52RC驱动P10LED屏的程序
- 自己动手实现STL:前言
- 洛谷P1414 又是毕业季II 数论
- SQL中 拆解函数 之 strsplit()
- raid5用户mbr还是gpt_系统硬盘gpt转换的操作方法
- 中华传统美德故事(五)
- python爬微信公众号视频_python爬虫公众号所有信息,并批量下载公众号视频
- Rokid Pebble若琪月石AI音响支持root
- NYOJ1238 最小换乘
- 基于51单片机的火灾报警器
- SwiftUI中如何使用App Tracking Transparency Framework
- Poc/Exp漏洞验证利用脚本编写
- ITE EC代码解析1
热门文章
- 圆弧裁剪算法c++_箍筋算法之争:按外皮长度计算与按中心线长度计算究竟相差多少?...
- Java学习之字符与ASCII码相互转换的面板设计
- http 1.php,php – Nginx忽略客户端的HTTP 1.0请求并通过HTTP 1.1响应
- java中的getnumber怎么用_java安全编码指南之:Number操作
- 判断字符串格式_Python基础教程,第四讲,字符串详解
- Python标准库中os模块的environ获取系统的环境变量
- TaskService API
- 光引发剂主要用途_食品级uv油墨光引发剂的安全使用
- 【编程科普】服务器的软件和硬件
- Oracle dbms_job管理