最近正在调试一个芯片的评估板,其中配置寄存器使用的是SPI通信协议。其实很多芯片寄存器的配置都用到了SPI通信协议,我们今天就需要实现这个SPI通信协议。
首先,我们需要了解SPI协议的基本内容,SPI主要有四根传输线,分别为SPI_CLK, SPI_EN, SPI_DI, SPI_DO。
主设备会将数据时钟通过SPI_CLK传送给从设备,从设备根据SPI_CLK进行接收发送工作;SPI需要注意的是极性CPOL和相位CPHA;CPOL指的是时钟极性,CPHA指的是时钟相位。一个时钟周期内,会有两个跳变沿,它既有可能是上升沿也有可能是下降沿;CPOL的值决定了SPI数据时钟在空闲状态下保持为高电平(CPOL=1)还是低电平(CPOL=0),CPHA的值决定了SPI的采样边沿是第一个边沿(CPHA=0)还是第二个边沿(CPHA=1)。
举个例子,从某芯片手册上看,该芯片手册SPI的时序图如下:
芯片SPI写时序
可以看到,SPI_CLK在开始和结束时都保持了低电平状态,所以CPOL=0,而每次SPI_DI在SPI_CLK的上升沿改变电平值,在SPI_CLK的下降沿保持电平不变,所以可以推断,SPI的采样边沿是第二个边沿,CPHA=1;
从图中我们还可以知道,SPI需要工作的时候,SPI_ENB需要拉低,这就是SPI的片选信号,由于SPI没有寻址机制,所以需要使用片选信号选择总线上不同的设备。
所以说,SPI_EN的工作最为轻松,在需要发送数据的时候将SPI_EN反相,在发送结束后再反相回来;SPI_CLK就是在不断地发送周期性方波;SPI_DI则是在恰当的时机根据要发送的数据进行高低电平转换,然后保持不变。
芯片SPI读时序
这里简单说一下这个芯片SPI的协议内容,发送的第一位(MSB)决定了SPI读写操作,为1是写入,为0是读取;接下来发送5位0,接着发送10位的寄存器地址;如果SPI是写操作,继续写入8位数据,否则开始接收SPI_DO上的数据。
指令解释
这里我列出了状态机跳转的状态:
首先状态机不管在任何状态都会回到IDLE空闲状态,在IDLE空闲状态下,接收到发送数据的命令就会跳转到WRITE_ADDR写地址状态,在写完前16位数据后,根据第一位的值决定是跳转到WRITE_DATA状态接着向芯片寄存器写入数据还是转向READ状态读取寄存器的值;操作结束后最终状态机回到IDLE空闲状态。
其实只需要理解芯片手册上SPI的时序图,并用verilog将其描述出来,就已经成功了一大半。这里我们实操前的准备工作都做完了,接下来就是开始码verilog代码并进行仿真,上板测试等等。待我整理出来之后,再与大家一同讨论吧。
全部0条评论
快来发表一下你的评论吧 !