Arduino 与 SPI 结合使用 以及SPI 深层理解

本文主要讲解两部分内容,不做任何转发,仅个人学习记录:

一. Arduino 与 SPI 结合使用  :

二. SPI 深层理解

有价值的几个好的参考:

1. 中文版: https://blog.csdn.net/xxxxxx91116/article/details/42620413  这版本适合比较容易理解大概, 细节翻译还是要去英文版:https://www.arduino.cc/en/Tutorial/SPIEEPROM

2 .https://www.cnblogs.com/adylee/p/5399742.html  以及 https://blog.csdn.net/weixin_40117614/article/details/84070130(其中:2.2传输数据步骤如下 mode似乎弄混了,mode0与mode2在第一次采样之前已发送1bit 而mode1和mode3则是正常的发送再采样,有待考证)

 

 

 

 

一. Arduino 与 SPI 结合使用  :

1.串行外围设备接口入门(Introduction to the Serial Peripheral Interface)

Serial Peripheral Interface (SPI)是一种同步串行数据传输协议,用于近距离时,微控制器(Microcontrollers),如Arduino,与其他外围设备的快速通信。他也可以用于2个微控制器的通讯。
SPI通讯通常有一个主设备(通常是Microcontrollers),用于控制外围设备。通常会有3种线路通用于各类设备的方法。
-Master In Slave Out(MISO)- Slave line,用于Slave向Master发送数据
-Master Out Slave In(MOSI)- Master line,用于Master向Slave发送数据
-Serial Clock(SCK)- 时钟脉冲,主设备用于同步数据传输
-Slave Select pin- 分配给所有的设备,用于enable/disable指定的设备,同时用于避免由于线路忙导致的错误传输。
SPI最大的问题在于它的标准太不严格了,这导致各个设备在实现它的时候都有一些不同,这就意味着当我们在编写接口代码的时候必须仔细阅读设备数据参数。通常来说有编号为0-3的3种传输模式(不是4种么?)这些模式控制数据是在时钟信号的高电平还是低电平传入或传出,以及在高或低电平时时钟无效。
所有的SPI设置都由Arduino SPI控制寄存器(SPCR)来决定。这个寄存器就是微控制器内存的一个字节,它是可读写的。寄存器提供的服务通常有3类:控制、数据和状态。
控制寄存器(SPCR)编码设置控制多种微控制器的功能。通常控制寄存器中的一个位影响某个特定的设置,比如速度和极性(这个是啥?)
数据寄存器(SPDR)仅仅hold住了一个字节。比如,SPI数据寄存器hold住了要发往MOSI线的一个字节,或者这个数据是要从MISO线传入的。
状态寄存器(SPSR)根据多种微控制器的条件改变其状态。比如,SPI状态寄存器(SPSR)的第七位被设置为1表示有数据从SPI传入或传出。
SPI控制寄存器(SPCR)共有8位,每一个都控制了一种特定的SPI设置。
SPIE:置为1时,表示enable SPI的中断
SPE:置为1时,表示enable SPI
DORD:发送数据时,设置为1表示最低有效位,0表示最高有效位。请各自脑补最低有效位和最高有效位。。。
MSTR:设置为1表示Arduino为master模式,0为slave模式
CPOL:设置为1时,数据时钟在高时无效,设置为0时,在低时无效
CPHA:设置为1时,时钟低电平时是Samples data(样本数据?),0时时钟高电平是Sampledata
SPR1和SPR0:设置SPI的速度,00是最快的(4MHz),11是最慢的(250KHz)
这些意味着当对一个新的SPI设备编码的时候,我们需要注意一些事情并根据如下设置SPCR:
- 数据传入是最高有效位(MSB)还是最低有效位(LSB)?
- 数据时钟无效是在高还是低?
- samples是在时钟脉冲上升沿还是下降沿?
- SPI 运行的速度是多少?
你还要感受一下feel一下你的芯片,在你设置好之后需要暂停多久才能继续?Let‘s go !

2.串行EEPROM简介

AT25HP512是一个65536字节串行EEPROM。它支持SPI的模式0-3,在10MHz,5V的环境下运行,同时也可以在1.8v的低速下运行。他的内存被组织成512个页,每个页有128字节。他每次只能写入128字节,但是可以同时读出1-128字节的数据,这个设备同时提供了多种程度的写保护,但这里不涉及这个部分。
enable这个设备只需要让片选信号CS为低即可。指令使用8位的opcodes来发送,同时在时钟上升沿传入数据,大概使用10微秒写入1个页的数据,所以在每个EEPROM的的写程序后面都应该等待10ms。

3.面包板的准备

将AT25HP512芯片插入面包板,EEPROM的3,7,8引脚接到5V,引脚4接地。
红色的线接+5V,GND线是黑色
EERPOM的引脚1连接Arduino的引脚10(Slave 片选),EEPROM的引脚2连接Arduino的引脚12(Master In Slave Out - MISO),EEPROM的引脚5连接Arduino的引脚11(Master Out Slave In - MOSI),同时EEPROM的引脚6连接Arduino的引脚13(串口时钟 SCK)。

4.Arduino SPI 编程

现在我们要编写能让Arduino和EEPROM进行SPI通信的代码了。在启动代码中,这个程序填充128字节,或者一个EEPROM页。在main loop中他将数据读出来,每次读一个字节并通过串口打印出来。我们下面用一小节来过一下代码。
第一步是启动我们的预处理指令(其实就是#define啦),预处理指令是在真正的编译开始前处理的。他们以#开头并且不以分号(;)结尾。反正前面一段就是说,我们接下来要开始使用#define了。
下面定义在我们的SPI通讯中要用到的pins引脚,DATAOUT, DATAIN, SPICLOCK和SLAVESELECT。然后定义EEPROM的控制指令(opcodes):
接下来分配程序会用到的全局变量。我们将用char buffer[128]来保存要传输到EEPROM的数据:
首先我们初始化我们的串口连接,设置我们的input和output模式并设置SLAVESELECT线为高时开始。这个设置可以使设备暂时失效,这样可以防止由于线路噪声引起的传输错误。
现在我们设置SPI控制寄存器(SPCR)为二进制数据01010000.在控制寄存器中,每一位的设置都表示不同的功能。第8位关闭SPI中断,第七位enable SPI,第六位选择数据传输是最高有效位有线,第五位设置Arduino为master模式,第四位设置数据时钟低时无效,第三位代表SPI在数据时钟的上升沿阶段抽样数据,第二位和第一位设置SPI和系统的通讯速度,/4有4个级别。当设置了控制寄存后,我们接下来从垃圾回收变量中读取SPI的状态寄存器(SPSR)和数据寄存器(SPDR),以清除以前运行的脏数据:
这里我们用数字来填充要发送的数组,并向EEPROM写入一个enable指令。这个enable指令必须在任何一个写指令之前完成。为了发送这个指令,我们将SLAVESELECT线置为低,enable这个设备后,使用spi_transfer函数发送指令。注意到我们使用了程序开始定义的WREN opcode。最后我们设置SLAVESELECT线为高来释放它。
在短暂的delay(10)之后,我们将SLAVESELECT线置为低再次选中EEPROM设备。我们发送一个写指令来告诉EEPROM我们将发送数据到内存中。首先发送16位,也就是2个字节地址来开始,最高有效位。接下来发送buffer中的128字节数据,一个字节接着一个字节,不需要pause暂停。最后我们设置SLAVESELECT引脚为高来释放设备,同时等待一段时间以保证EEPROM写入数据:
我们在setup函数结束时,通过串口发送hi来表示setup结束。
在我们的主函数loop中我们每次从EEPROM中读取一个字节并通过串口将它打印出来。为了可读性我们增加一个打印以及等待。每一次loop我们都增加EEPROM的一个地址去读,当地址增加到128后,我们重新回到0开始读,原因很简单,因为开始我们只写入了128字节数据:
fill_buffer函数仅仅将我们的数组用0-127这128个数字来填充。这个函数很容易就可以改写为你应用程序需要的数据:

spi_transfer函数将要传出的数据放入数据传输寄存器,然后就开始SPI传输了哈。可以通过SPI状态寄存器(SPSR)的某个位(SPIF)来查看数据传输是否结束了。关于位掩码(bit mask)可以参考这里:http://www.arduino.cc/en/Tutorial/。最后返回写入EEPROM的数据。

 

read_eeprom函数允许我们从EEPROM中读入数据,首先设置SLAVESELECT为低来enable设备。接下来送入一个读指定,接下来送入要读的16位地址,最高有效位有限。接下来我们发送一个假数据到EEPROM中以将数据传出。最后我们在读入一个字节后,再次设置SLAVESELECT线为高来释放设备,并返回数据,如果我们想要一次读入多个数据,那么当我们重复data=spi_transfer(0XFF)时,需要将SLAVESELECT一直设置为低,这样来回128次后读出整个页的数据:

 

 

为了方便大家CTRL+c、  CTRL+v,下面是整个手册的源码:

 

#define DATAOUT 11//MOSI
#define DATAIN 12//MISO #define SPICLOCK 13//sck #define SLAVESELECT 10//ss //opcodes #define WREN 6 #define WRDI 4 #define RDSR 5 #define WRSR 1 #define READ 3 #define WRITE 2 byte eeprom_output_data; byte eeprom_input_data=0; byte clr; int address=0; //data buffer char buffer [128]; void fill_buffer() { for (int I=0;I<128;I++) { buffer[I]=I; } } char spi_transfer(volatile char data) { SPDR = data; // Start the transmission while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission { }; return SPDR; // return the received byte } void setup() { Serial.begin(9600); pinMode(DATAOUT, OUTPUT); pinMode(DATAIN, INPUT); pinMode(SPICLOCK,OUTPUT); pinMode(SLAVESELECT,OUTPUT); digitalWrite(SLAVESELECT,HIGH); //disable device // SPCR = 01010000 //interrupt disabled,spi enabled,msb 1st,master,clk low when idle, //sample on leading edge of clk,system clock/4 rate (fastest) SPCR = (1<<SPE)|(1<<MSTR); clr=SPSR; clr=SPDR; delay(10); //fill buffer with data fill_buffer(); //fill eeprom w/ buffer digitalWrite(SLAVESELECT,LOW); spi_transfer(WREN); //write enable digitalWrite(SLAVESELECT,HIGH); delay(10); digitalWrite(SLAVESELECT,LOW); spi_transfer(WRITE); //write instruction address=0; spi_transfer((char)(address>>8)); //send MSByte address first spi_transfer((char)(address)); //send LSByte address //write 128 bytes for (int I=0;I<128;I++) { spi_transfer(buffer[I]); //write data byte } digitalWrite(SLAVESELECT,HIGH); //release chip //wait for eeprom to finish writing delay(3000); Serial.print('h',BYTE); Serial.print('i',BYTE); Serial.print('\n',BYTE);//debug delay(1000); } byte read_eeprom(int EEPROM_address) { //READ EEPROM int data; digitalWrite(SLAVESELECT,LOW); spi_transfer(READ); //transmit read opcode spi_transfer((char)(EEPROM_address>>8)); //send MSByte address first spi_transfer((char)(EEPROM_address)); //send LSByte address data = spi_transfer(0xFF); //get data byte digitalWrite(SLAVESELECT,HIGH); //release chip, signal end transfer return data; } void loop() { eeprom_output_data = read_eeprom(address); Serial.print(eeprom_output_data,DEC); Serial.print('\n',BYTE); address++; if (address == 128) address = 0; delay(500); //pause for readability }

 总结:

1.这里主要以内存器EEPROM为主, 而且个人感觉这里的SPI控制进入到Arduino的开发版, 大体的方向对很多Arduino——SPI控制实用,但毕竟只是一个例子,下面一节将讲述SPI最底层的东西。

2.如果只是简单的读写,Arduino 中是有SPI.h头文件和cpp 也是大家可以研究的一个方向,现在记忆留心还是spi.transfer用法。

 

二. SPI 深层理解

SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。 SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。

上升沿发送、下降沿接收、高位先发送。 上升沿到来的时候,sdo上的电平将被发送到从设备的寄存器中。 下降沿到来的时候,sdi上的电平将被接收到主设备的寄存器中。
假设主机和从机初始化就绪:并且主机的sbuff=0xaa (10101010),从机的sbuff=0x55 (01010101),下面将分步对spi的8个时钟周期的数据情况演示一遍(假设上升沿发送数据)。
---------------------------------------------------
脉冲      主机sbuff 从机sbuff sdi sdo
---------------------------------------------------
0 00-0   10101010 01010101 0 0
---------------------------------------------------
1 0--1   0101010x 10101011 0 1
1 1--0   01010100 10101011 0 1
---------------------------------------------------
2 0--1   1010100x 01010110 1 0
2 1--0   10101001 01010110 1 0
---------------------------------------------------
3 0--1   0101001x 10101101 0 1
3 1--0   01010010 10101101 0 1
---------------------------------------------------
4 0--1   1010010x 01011010 1 0
4 1--0   10100101 01011010 1 0
---------------------------------------------------
5 0--1   0100101x 10110101 0 1
5 1--0   01001010 10110101 0 1
---------------------------------------------------
6 0--1   1001010x 01101010 1 0
6 1--0   10010101 01101010 1 0
---------------------------------------------------
7 0--1   0010101x 11010101 0 1
7 1--0   00101010 11010101 0 1
---------------------------------------------------
8 0--1   0101010x 10101010 1 0
8 1--0   01010101 10101010 1 0
---------------------------------------------------
这样就完成了两个寄存器8位的交换,上面的0--1表示上升沿、1--0表示下降沿,sdi、 sdo相对于主机而言的。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的名准备数据,主机在下一个8位时钟周期才把数据读回来。  SPI总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。
SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。
SPI总线有四种工作方式(SP0, SP1, SP2, SP3),其中使用的最为广泛的是SPI0和SPI3方式。 SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输。如果 CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。 SPI主模块和与之通信的外设音时钟相位和极性应该一致。

 

 

SPI时序图详解-SPI接口在模式0下输出第一位数据的时刻

SPI接口在模式0下输出第一位数据的时刻
SPI接口有四种不同的数据传输时序,取决于CPOL和CPHL这两位的组合。图1中表现了这四种时序, 时序与CPOL、CPHL的关系也可以从图中看出。

CPOL(时钟极性)和CPHA(时钟相位)意义

CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时

CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时

CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿  

CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿

通过CPOL和CPHA来控制我们主设备的通信模式
发送和接收设备需要根据实际情况分析 (发送设备 ≠ 主设备
Mode0:CPOL=0,CPHA=0
SCLK(0)空闲;
当SCLK由低到高跳变(上升沿),(接收设备)进行数据的读取;
当SCLK由高到低跳变(下降沿),(发送设备)进行数据的发送;
Mode1:CPOL=0,CPHA=1
SCLK(0)空闲;
当SCLK由高到低跳变(下降沿),(接收设备)进行数据的读取;
当SCLK由低到高跳变(上升沿),(发送设备)进行数据的发送;
Mode2:CPOL=1,CPHA=0
SCLK(1)空闲;
当SCLK由高到低跳变(下降沿),(接收设备)进行数据的读取;
当SCLK由低到高跳变(上升沿),(发送设备)进行数据的发送;
Mode3:CPOL=1,CPHA=1
SCLK(1)空闲;
当SCLK由低到高跳变(上升沿),(接收设备)进行数据的读取;
当SCLK由高到低跳变(下降沿),(发送设备)进行数据的发送;
---------------------

 

 

图1

 

 

CPOL是用来决定SCK时钟信号空闲时的电平,CPOL=0,空闲电平为低电平,CPOL=1时,

空闲电平为高电平。CPHA是用来决定采样时刻的,CPHA=0,在每个周期的第一个时钟沿采样,

CPHA=1,在每个周期的第二个时钟沿采样。

 

由于我使用的器件工作在模式0这种时序(CPOL=0,CPHA=0),所以将图1简化为图2, 只关注模式0的时序。
图2
我们来关注SCK的第一个时钟周期,在时钟的前沿采样数据(上升沿,第一个时钟沿), 在时钟的后沿输出数据(下降沿,第二个时钟沿)。首先来看主器件,主器件的输出口(MOSI)输出的数据bit1, 在时钟的前沿被从器件采样,那主器件是在何时刻输出bit1的呢?bit1的输出时刻实际上在SCK信号有效以前, 比 SCK的上升沿还要早半个时钟周期。bit1的输出时刻与SSEL信号没有关系。再来看从器件, 主器件的输入口MISO同样是在时钟的前沿采样从器件输出的bit1的,那从器件又是在何时刻输出bit1的呢。 从器件是在SSEL信号有效后,立即输出bit1,尽管此时SCK信号还没有起效。关于上面的主器件 和从器件输出bit1位的时刻,可以从图3、4中得到验证。
图3
注意图3中,CS信号有效后(低电平有效,注意CS下降沿后发生的情况),故意用延时程序 延时了一段时间,之后再向数据寄存器写入了要发送的数据,来观察主器件输出bit1的情况(MOSI)。 可以看出,bit1(值为1)是在SCK信号有效之前的半个时钟周期的时刻开始输出的(与CS信号无关), 到了SCK的第一个时钟周期的上升沿正好被从器件采样。
图4

图4中,注意看CS和MISO信号。我们可以看出,CS信号有效后,从器件立刻输出了bit1(值为1)。

 

通常我们进行的spi操作都是16位的。图5记录了第一个字节和第二个字节间的相互衔接的过程。 第一个字节的最后一位在SCK的上升沿被采样,随后的SCK下降沿,从器件就输出了第二个字节的第一位。

 

 

 

 

SPI总线协议介绍(接口定义,传输时序)

 

一、技术性能 SPI接口是Motorola 首先提出的全双工三线同步串行外围接口,采用主从模式(Master Slave)架构;支持多slave模式应用,一般仅支持单Master。 时钟由Master控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSB first);SPI接口有2根单向数据线,为全双工通信,目前应用中的数据速率可达几Mbps的水平。
------------------------------------------------------- 二、接口定义 SPI接口共有4根信号线,分别是:设备选择线、时钟线、串行输出数据线、串行输入数据线。

 

(1)MOSI:主器件数据输出,从器件数据输入 (2)MISO:主器件数据输入,从器件数据输出 (3)SCLK :时钟信号,由主器件产生 (4)/SS:从器件使能信号,由主器件控制
------------------------------------------------------- 三、内部结构
 四、传输时序
SPI接口在内部硬件实际上是两个简单的移位寄存器,传输的数据为8位,在主器件产生的从器件使能信号和移位脉冲下,按位传输,高位在前,低位在后。如下图所示,在SCLK的下降沿上数据改变,上升沿一位数据被存入移位寄存器。
SPI接口没有指定的流控制,没有应答机制确认是否接收到数据。
谢谢!

 

 

 

转载于:https://www.cnblogs.com/MCSFX/p/10805878.html

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

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

相关文章

VGG

VGG16网络&#xff0c;卷积核3*3&#xff0c;步长为1&#xff0c;填充&#xff08;padding&#xff09;为1&#xff1b; 池化2*2&#xff0c;步长为2 全连接层 卷积核1*1 Input Layer&#xff1a;224*224*3图像 Conv1-1 Layer&#xff1a;包含64个卷积核&#xff0c;kernal s…

guava 并发同步_Google Guava –与Monitor同步

guava 并发同步Google Guava项目是每个Java开发人员都应该熟悉的库的集合。 Guava库涵盖了I / O&#xff0c;集合&#xff0c;字符串操作和并发性。 在这篇文章中&#xff0c;我将介绍Monitor类。 Monitor是一种同步构造&#xff0c;可以在使用ReentrantLock的任何地方使用。 随…

qt 定时器_Qt开源作品23-颜色拾取器

## 一、前言在做很多项目的UI界面的时候&#xff0c;相信绝大部分人都有过抄袭别人的UI界面尤其是颜色的时候&#xff0c;毕竟十个程序员九个没有审美&#xff0c;或者说审美跟一坨屎一样&#xff0c;大家主要的精力以及擅长点都是在写功能实现具体功能上面&#xff0c;这个事情…

第5章学习小结

第五章主要学习了树的知识&#xff0c;以前一直很好奇&#xff0c;为什么电脑能存储像树一样的数据结构&#xff0c;学完才发现&#xff0c;ADT加数组或者ADT加链表真的可以衍生出多种多样的数据类型&#xff0c;以下做出本章小结&#xff1a; 1.利用ASCII码实现不同类型的数据…

tf.transpose

tf.transpose(input, [dimension_1,dimenaion_2,..,dimension_n]) 这个函数主要适用于交换输入张量的不同维度用的&#xff0c;如果输入张量是二维&#xff0c;就相当是转置。dimension_n是整数&#xff0c;如果张量是三维&#xff0c;就是用0,1,2来表示。这个列表里的每个数对…

【20171025中】alert(1) to win 脚本渲染自建

游戏误人生&#xff0c;一下午玩了将近四个小时的三国杀&#xff0c;后悔不已&#xff0c;然后重新拾起xss challenge&#xff0c;突发奇想&#xff0c;自己构建渲染后的html。 从最简单的开始。 自动检测html: <!DOCTYPE html> <html> <head><meta http-…

使用JPA和@NamedQueries的Spring数据

如果在JPA实体上使用Spring Data和NamedQuery批注&#xff0c;则可以使用spring数据存储库以更方便的方式轻松使用它们。 在先前的博客中&#xff0c;我们使用spring boot和docker 创建了spring数据项目。 我们将使用相同的项目并增强存储库的功能。 我们将实现一个命名查询&…

vs无法写入量的大数据_一个每天服务数万人的企业食堂:自助餐按重计价,大数据支持食材预备量...

钱江晚报小时新闻记者 祝瑶 昨天下午6点多&#xff0c;钱报记者来到杭州阿里巴巴总部。这里共有5个员工食堂&#xff0c;几乎覆盖了全国各地的口味&#xff0c;每天为数万阿里人服务。其中&#xff0c;最当红的是2号食堂&#xff0c;除了有丰俭由人的自助餐区&#xff0c;还有十…

6号板编译失败找不到arm-none-linux-gnueabi-gcc

明明已经添加到/etc/environment 安装sudo apt-get install lib32z1 lib32ncurses5转载于:https://www.cnblogs.com/xpylovely/p/10817240.html

tf.train.Saver

将训练好的模型参数保存起来&#xff0c;以便以后进行验证或测试&#xff0c;这是我们经常要做的事情。tf里面提供模型保存的是tf.train.Saver()模块。 模型保存&#xff0c;先要创建一个Saver对象&#xff1a;如 savertf.train.Saver() 在创建这个Saver对象的时候&#xff…

Neo4j:空值如何工作?

我时不时地发现自己想将CSV文件导入Neo4j&#xff0c;而我总是对如何处理可能潜伏在其中的各种空值感到困惑。 让我们从一个没有CSV文件的示例开始。 考虑以下列表&#xff0c;以及我尝试仅返回空值的尝试&#xff1a; WITH [null, "null", "", "Ma…

楼层钢筋验收会议纪要_钢筋施工质量通病防治

一、钢筋原材1、钢筋表面出现黄色浮锈&#xff0c;严重转为红色&#xff0c;日久后变成暗褐色&#xff0c;甚至发生鱼鳞片剥落现象。图片原因保管不良&#xff0c;受到雨雪侵蚀&#xff0c;存放期长&#xff0c;仓库环境潮湿&#xff0c;通风不良。防 治 措 施1、钢筋原料应存放…

simulink代码生成(一)——环境搭建

一、安装C2000的嵌入式环境&#xff1b; 点击matlab附加功能&#xff0c; 然后搜索C2000&#xff0c;安装嵌入式硬件支持包&#xff1b;点击安装即可&#xff1b;&#xff08;目前还不知道破解版的怎么操作&#xff0c;目前我用的是正版的这样&#xff0c;完全破解的可能操作…

五步法颈椎病自我按摩图解

​​1.揉捏颈、肩、臂 操作&#xff1a;自我按摩时取坐位。拇指张开&#xff0c;其余四指并拢&#xff0c;虎口相对用力&#xff0c;自枕部开始沿颈椎棘突两旁的肌肉向下揉捏&#xff0c;至上背部手能摸到之处为止。反复揉捏3分钟&#xff0c;然后以相同手法揉捏患侧上肢和颈部…

tf.one_hot

tf.one_hot(indices,#输入&#xff0c;这里是一维的depth,# one hotdimension.on_valueNone,#output 默认1off_valueNone,#output 默认0axisNone,#根据我的实验&#xff0c;默认为1dtypeNone,nameNone) 测试程序&#xff0c;一般说&#xff0c;有几类&#xff0c;depth等于分类…

使用get set方法添减属性_头皮银屑病“克星”使用方法,你GET了吗?

相信小伙伴们最近都了解了治疗头皮银屑病需要使用专业剂型。但...方法不对&#xff0c;心血白费。头皮银屑病专用剂型的正确使用方法&#xff0c;你真的知道吗&#xff1f;快来和利奥娜一起&#xff0c;Get√正确的使用方法吧&#xff01;适合头皮银屑病的专用药剂1.复方制剂卡…

spring hsqldb_在Spring中嵌入HSQLDB服务器实例

spring hsqldb我一直在愉快地使用XAMPP进行开发&#xff0c;直到不得不将其托管在可通过Internet访问的某个地方&#xff0c;供客户端进行测试和使用。 我有一个仅具有384 RAM的VPS&#xff0c;并且需要快速找到方法&#xff0c;因此决定将XAMPP安装到VPS中。 由于内存较低&…

线性回归,logistic回归和一般回归

http://www.cnblogs.com/riskyer/p/3217601.html转载于:https://www.cnblogs.com/focus-z/p/10822757.html

double小数点后最多几位_基金理财买入后,不断亏损,是最多本金亏光,还是会出现负值...

投资基金不会把本金亏光&#xff0c;更不会倒贴钱&#xff0c;基金是一篮子股票&#xff0c;个别股票或许有黑天鹅事件&#xff0c;不可能全部同时出现&#xff0c;持续亏损的话&#xff0c;可能最后面临清盘&#xff0c;有结算流程&#xff0c;会将剩下的份额折算到投资者的账…

tf.layers.flatten

flatten( inputs, nameNone) 参数说明如下&#xff1a; inputs&#xff1a;必需&#xff0c;即输入数据。name&#xff1a;可选&#xff0c;默认为 None&#xff0c;即该层的名称。