1、SPI协议【一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线】【频率最大为fPCLK/2】
【注】与IIC相比,没有应答确认机制,存在一定缺陷;传输数据可编程(高位在前或低位在前)
①SPI从设备及管理
SPI只包含一个主设备,而从设备则可以有多个。SPI的读写操作都是由主设备发起的,当存在多个设备时,通过片选信号进行管理(软件或硬件)。其中软件NSS脚管理为设置SPI_CR1寄存器的SSM位来使能,并通过写SPI_CR1的SSI位来驱动;硬件NSS模式,使能,并拉低NSS引脚即可。
②SPI通讯
SPI通讯时,双方必须工作在同一模式,通过对主设备SPI模式进行配置,设置时钟极性(CPOL)和时钟相位(CPHA)来控制通信模式。其中,
CPOL=0表示,空闲态下SCLK为低电平;CPHA=0表示,数据采集在第一个边沿,数据发送在第二个边沿开始。
(0,0)数据采集发生在上升沿。(0,1)数据采集发生在下降沿。(1,0)数据采集发生在下降沿。(1,1)数据采集发生在上升沿。
数据采集->MCU读;数据发送->MCU写。
③SPI时序【寄存器标志位】【读写同步】
SPI是一种环形总线结构,在SCLK的控制下,两个双向移位寄存器进行数据交换。【SPI_CR1寄存器定义数据帧格式、波特率、极性相位】
当发送完一帧数据的时候,“状态寄存器 SR”中的“TXE 标志位”会被置 1,表示传输完一帧,发送缓冲区已空;
当接收完一帧数据的时候,“ RXNE标志位”会被置 1,表示传输完一帧,接收缓冲区非空;
在发送数据时,数据字被并行地(通过内部总线)传入移位寄存器,而后串行地移出到MOSI脚上,数据从发送缓冲器传输到移位寄存器时TXE标志将被置位。
在接收数据时,移位寄存器中的数据传送到接收缓冲器,SPI_SR 寄存器中的RXNE标志被置1。当读SPI_DR寄存器时,SPI设备返回这个接收缓冲器的数值。读SPI_DR寄存器时,RXNE位被清除。
2、TCP数据帧格式
1.【四层协议模型-物理层(光电信号)/链路层(以太网帧)/网络层(IP)/传输层(TCP/UDP)/应用层(HTTP/SSH/FTP)
2.【ARP】地址解析协议,根据网络层IP数据包包头中的IP地址信息解析出目标硬件地址(MAC地址)信息,从而连接第二层和第三层。
3.TCP一种面向连接的、可靠的、基于字节流的传输层通信协议。通过三次握手和四次挥手完成客户端和服务器之间的连接。
4.区别于UDP,TCP传输的数据会在发送端进行缓冲,统一分片(分包)或者打包进行发送,再接收端也是按照字节流进行数据传输的;对于UDP来说,应用层给传输层的数据会直接形成一个UDP包进行发送。
5.【协议帧】
源端口(发送端)/目标端口(接收端)/序列号(标识了TCP报文中第一个byte在对应方向的传输中对应的字节序号-SN,单位为Byte),通过序列号可以识别出重复和乱序的数据包,进行丢包或重排序/应答号(标识了报文发送端期望接收的字节序列)【序列号为当前端成功发送的数据位数,确认号为当前端成功接收的数据位数,SYN标志位和FIN标志位也要占1位】/头长(指示TCP头的长度,即数据从何处开始)/保留段/标志位/窗口大小(表示当前接收端的接收窗还有多少剩余空间,用于TCP的流量控制)/校验位/优先指针(指示后面是优先数据的字节)/选项
【标志位】CWR/ECE/URG/ACK()/PSH/RST/SYN/FIN
3、TCP服务器和客户端的实现
【服务器】
①创建套接字(IP地址类型、使用的传输层协议 (TCP或UDP)和使用的使用的特定协议),返回套接字文件描述符,用于监听客户连接(socket)
【IP地址类型、数据传输方式、传输协议(一般默认,操作系统自动设置TCP/UDP)】
②将文件描述符、IP地址、端口绑定在一起(bind)
【文件描述符、结构体sockaddr_in指针(地址族、端口、IP地址)、结构体变量大小】
③将套接字文件描述符变为被动描述符,用于被动监听客户连接(listen)
【文件描述符、请求队列的最大长度】
④被动监听客户的握手请求,三次握手成功,然后返回一个通信的描述符(accept)
【文件描述符、结构体sockaddr_in指针(地址族、端口、IP地址)、结构体变量大小】
【客户端】
①创建套接字,返回套接字文件描述符(socket)
【IP地址类型、数据传输方式、传输协议(一般默认,操作系统自动设置TCP/UDP)】
②客户端主动向服务器发起握手,三次握手链接成功(connect)
【文件描述符、结构体sockaddr_in指针(地址族、端口、IP地址)、结构体变量大小】
【功能函数】
服务器向客户端(write/send)/服务器接收客户端(read/recv)/四次挥手断开连接(close/shutdown)
4、zigbee(低功耗、低速率[250Kbit/s]、自组网、低延迟[15~30ms]、低成本)组包
【数据处理】 参考链接ZigBee 协议栈知识详细总结 - 知乎 (zhihu.com)
消息是收到的事件和数据的一个封装,比如发生了一个事件(收到别的节点发的消息),这时就会把这个事件所对应的事件号及收到的数据封装成消息,放入消息队列中。
协议栈是由各个层组成的,每一层都要处理各种事件,所以就为每一层定义了一个事件处理函数,我们可以把这个处理函数理解为任务,任务从消息队列中提取消息,从消息中提取所发生的具体事件,调用相应的具体事件处理函数,比如按键处理函数等等。
【协议层】
物理层(PHY)利用物理传输介质为通信的两端建立链接,实现比特流的传输。
链路层(MAC)包括寻址-如何找到数据包接收方和控制-谁先发、谁后发,出现问题如何处理。
网络层(NWK)负责数据分段和封装;网络建立、地址分配、拓扑结构和路由管理。
应用层:包括应用支持子层(APS)、应用程序框架(AF)、Zigbee设备对象(ZDO)。
【数据包】
终端发送信标请求----协调器建立Zigbee无线网络,网络地址为0x0000,并尝试与终端节点建立连接----终端发送加入网络请求----协调器对终端节点的加入网络请求做出应答----终端节点收到协调器的应答后,发送数据请求(Data Request),请求协调器分配网络地址----协调器对终端节点的数据请求做出应答----协调器分配的网络地址发送给终端节点----终端节点做应答----终端节点使用短地址0xDC35与协调器进行通信----发送数据。
5、const修饰常量
【编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高】
指针常量 int * const p----指针的指向不可以修改,指针指向的内存的值可以修改;
常量指针 int const *p / const int * p---- 指针的指向可以修改,但是指针指向的值不可以修改;
指向常量的常指针const int const *p----指针的指向不可以修改,指针指向的值不可以修改。
6、STM32出现HardFault_Handler的原因有类型错误、数组越界操作、内存溢出、堆栈溢出、中断处理错误或者外设连接、资源占用、调试工具问题。
查找办法:
①在进入HardFault_Handler函数之前打断点,查看R14(LR)寄存器的值(发生异常前PC将要执行的下一条指令地址),如果为0xFFFFFFE9,则查看MSP(主堆栈指针)的值,如果为0xFFFFFFFD,则查看PSP(进程栈指针)的值【MSP用于OS内核 异常处理及系统初始化,PSP用于应用任务】
进入Memory输入MSP/PSP的值,找到对应的地址,一般为0x08开头的32位数。进入Disassembly Window,在Show Code atAdress下输入地址,查找对应的代码。
②【view】->【Call Stack Window】,选择【Show Caller Code】,右键点击对话框中的【HardFault_Handler】,就会跳到出错的函数位置。
7、PID
PWM控制电机,频率过低会产生震荡,这是由于PWM脉冲调制低电平时间过长时,高电平还没到来,电机的速度就降低,但是频率过高会产生高频噪声,通常控制频率为6~16kHz。
测量电机速度采用编码器,常用的有光电式和电磁式,编码器固定在电机转轴上,编码器的AB相随电机转动会输出一定数量相位相差90°的方波脉冲,通过判断A相超前还是B相超前来判断电机的转动方向。根据一定时间内的方波脉冲个数,对时间求导,可以得到电机的转动速度,此为编码器的正交解码。
PID分为增量式和位置式,增量式存在一定的积分时滞,但是稳态误差小,适用于电机控制这种期望值变化较小的场合。而位置式则应用于期望值变化比较大,且变化较快的场合,如小车的转向控制。