Zedboard中的SPI通信记录文档(已实现)

SPI记录文档备份

CSDN博客的bug就是传图片太麻烦,所以我把文档上传了,点击下载地址,即可下载。

以下只是文字版的,没有图片,看起来有点乱,建议去下载。

概念

SPI是串行外设接口(SerialPeripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线。SPI是利用4根信号线进行通信的串行接口协议,4个接口信号为:串行数据输入(MISO,主设备输入、从设备输出)、串行数据输出(MOSI,主设备输出、从设备输入)、移位时钟(SCK)低电平有效的从设备使能信号(cs)

zedboard有两个独立的SPI,可以工作在主/从模式或者多主机模式下,

主模式:

数据传输和片选 都可以手工或者自动(需要配置)

发送数据、接收数据、片选从设备(直接连接上即可)

 

相关寄存器

 

1.       Config_reg0(0xE0006000): SPI配置寄存器

2.       Intr_status_reg0(0xE0006004:中断状态寄存器,wtc。

3.       Intrpt_en_reg0(0xE0006008):中断使能寄存器,这里面有多个中断

4.       Intrpt_dis_reg0(0xE000600C):中断不使能寄存器,只写

5.       Intrpt_mask_reg0(0xE0006010):中断屏蔽寄存器,只读

6.       En_reg0(0xE0006014):SPI使能寄存器

7.       Delay_reg0(0xE0006018):延时寄存器

8.       Tx_data_reg0(0xE000601C):发送数据寄存器,只写。Data toTX FIFO. Valid data bits are [7:0].

9.       Rx_data_reg0(0xE0006020):接收数据寄存器,只读。Datafrom RX FIFO. Valid data bits are [7:0]

10.   Slave_Idle_count_reg0(0xE0006024):从空闲计数寄存器

11.   TX_thres_reg0(0xE0006028):发送阈值寄存器。TX_FIFOThreshold Register

Defines the level at which the TX FIFOnot full interrupt is generated

12.   RX_thres_reg0(0xE000602C):接收阈值寄存器。RX FIFOThreshold Register

Defines the level at which the RX FIFO not emptyinterruptis generated

13.   Mod_id_reg0(0xE00060FC):模块ID寄存器。Module ID register

 

 

 

中断号:SPI1是81号中断,SPI0是58号中断

中断寄存器的几个相关值

0x14: rx fifo not empty  tx fifo not full

0x10: rx fifo not empty

 

特点

1. 采用主-从模式(Master-Slave) 的控制方式

SPI 规定了两个 SPI 设备之间通信必须由主设备(Master) 来控制次设备 (Slave). 一个 Master 设备可以通过提供 Clock 以及对 Slave 设备进行片选 (Slave Select) 来控制多个 Slave 设备, SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作.

 

2. 采用同步方式(Synchronous)传输数据

Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse), 时钟脉冲组成了时钟信号(Clock Signal) ,时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样, 来保证数据在两个设备之间是同步传输的.

 

3. 数据交换(DataExchanges)

SPI 设备间的数据传输之所以又被称为数据交换, 是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 "发送者(Transmitter)" 或者 "接收者(Receiver)". 在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据, 相当于该设备有一个 bit 大小的数据被交换了.

 

一个 Slave 设备要想能够接收到Master 发过来的控制信号, 必须在此之前能够被 Master 设备进行访问 (Access). 所以, Master设备必须首先通过 SS/CS pin Slave 设备进行片选, 把想要访问的 Slave 设备选上.

 

在数据传输的过程中,  每次接收到的数据必须在下一次数据传输之前被采样. 如果之前接收到的数据没有被读取, 那么这些已经接收完成的数据将有可能会被丢弃,  导致 SPI 物理模块最终失效. 因此, 在程序中一般都会在 SPI传输完数据后, 去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的.

  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在STM32,可以使用HAL库提供的SPI库函数来实现SPI通信。以下是实现SPI通信的基本步骤: 1. 初始化SPI控制器:使用HAL_SPI_Init()函数初始化SPI控制器,设置SPI模式、数据位数、时钟极性、时钟相位等参数。 2. 配置SPI从设备:使用HAL_SPI_SetSlaveSelect()函数设置SPI从设备的选择线,也可以使用HAL_SPI_Transmit()或HAL_SPI_Receive()函数直接传输数据。 3. 发送和接收数据:使用HAL_SPI_TransmitReceive()函数发送和接收数据。该函数将要发送的数据和接收到的数据作为参数传递,并使用指定的超时时间等待操作完成。 4. 关闭SPI控制器:使用HAL_SPI_DeInit()函数关闭SPI控制器。 以下是一个简单的例子,演示如何使用SPI库函数在STM32实现SPI通信: ``` #include "stm32f4xx_hal.h" /* SPI设备句柄 */ SPI_HandleTypeDef hspi; /* SPI初始化函数 */ void SPI_Init(void) { /* SPI控制器初始化结构体 */ hspi.Instance = SPI1; hspi.Init.Mode = SPI_MODE_MASTER; hspi.Init.Direction = SPI_DIRECTION_2LINES; hspi.Init.DataSize = SPI_DATASIZE_8BIT; hspi.Init.CLKPolarity = SPI_POLARITY_LOW; hspi.Init.CLKPhase = SPI_PHASE_1EDGE; hspi.Init.NSS = SPI_NSS_SOFT; hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi.Init.TIMode = SPI_TIMODE_DISABLE; hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi.Init.CRCPolynomial = 7; HAL_SPI_Init(&hspi); } /* SPI发送和接收函数 */ void SPI_TransmitReceive(uint8_t* txData, uint8_t* rxData, uint16_t dataSize) { HAL_SPI_TransmitReceive(&hspi, txData, rxData, dataSize, 1000); } int main(void) { /* 初始化HAL库 */ HAL_Init(); /* 初始化SPI控制器 */ SPI_Init(); /* 发送和接收数据 */ uint8_t txData[2] = {0x01, 0x02}; uint8_t rxData[2]; SPI_TransmitReceive(txData, rxData, 2); /* 关闭SPI控制器 */ HAL_SPI_DeInit(&hspi); return 0; } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值