tag 标签: spi

相关帖子
相关博文
  • 热度 1
    2024-9-15 07:13
    159 次阅读|
    0 个评论
    SPI、I2C和I3C是三种常见的串行通信协议,广泛应用于嵌入式系统和微控制器之间的数据交换。每种协议都有其独特的特点和适用场景,以下是对这三种协议的性能比较: 1. SPI (Serial Peripheral Interface) 速度:SPI是一种高速的同步串行通信协议,通常比I2C更快,因为它没有起始位和停止位的概念,数据传输是全双工的(即可以同时发送和接收数据)。 引脚数:SPI需要至少4个引脚(MOSI, MISO, SCLK, SS/CS),这可能在某些应用中是一个限制因素。 灵活性:由于SPI是全双工通信,它可以在主机和从机之间实现真正的并行数据传输,这对于需要高吞吐量的应用非常有用。 配置:SPI支持多种模式,包括时钟极性和相位,这提供了额外的灵活性。 2. I2C (Inter-Integrated Circuit) 速度:I2C的速度通常低于SPI,但它足以满足许多低至中等速度的应用需求。 引脚数:I2C只需要两根线(SDA和SCL),这使得它非常适合于空间受限的设计。 可扩展性:I2C支持多主设备和多从设备,允许在同一总线上连接多个设备,这是其最大的优势之一。 地址分配:每个I2C设备都有一个唯一的地址,这使得总线上的设备可以轻松地被识别和寻址。 3. I3C (Improved Inter-Integrated Circuit) 速度:I3C是I2C的改进版,旨在提供更高的速度和更低的功耗。它通过引入新的功能来提高性能,如动态地址分配和更高效的电源管理。 兼容性:I3C保持了与I2C的向后兼容性,这意味着现有的I2C设备可以直接与I3C总线交互,无需修改。 引脚数:I3C通常使用与I2C相同的两根线,但在需要时可以通过增加额外的信号线来实现更多的功能。 新特性:I3C引入了一些新特性,如快速模式切换和增强的错误检测机制,这些特性使其在某些应用中比传统的I2C更具吸引力。 总结来说,SPI适合需要高速数据传输且不介意多引脚的应用;I2C适用于需要多设备通信且空间受限的设计;而I3C则结合了两者的优点,提供了更高的速度和新的功能,同时保持了与I2C的兼容性。选择哪种协议取决于具体的应用需求和设计约束。
  • 热度 5
    2024-3-15 11:22
    643 次阅读|
    0 个评论
    SPI(Serial Peripheral Interface)通信总线以其高速、全双工、同步的特性而被广泛应用,它只需要四根线就能实现数据传输,有效地节约了芯片管脚的数量,同时为PCB布局带来了空间上的优化和便捷。正因为它简单易用的特点,现在越来越多的芯片选择集成SPI通信协议。 作为TI Sitara™产品线新一代MPU产品,TI AM62x处理器特别配备了多达4路的SPI接口以及1路OSPI接口(有时也称为QSPI),丰富的SPI接口配置使得该处理器能够同时与多个设备进行通信连接,大大提高了系统的扩展性和灵活性。 在飞凌嵌入式推出的搭载了AM62x处理器的OK6254-C开发板上,NOR Flash存储器正是通过连接到处理器的OSPI总线上进行工作的。这样的设计充分利用了SPI通信协议的高速传输和全双工特性,保证了开发板在数据处理和存储方面的效率。本文就通过OK6254-C开发板为大家介绍一下AM62x的SPI。 1、SPI的工作流程和时序 我们首先需要了解一下SPI是如何工作的——通常SPI通过4个引脚与外部器件相连: (1) MISO:主设备输入/从设备输出引脚 该引脚在从模式下发送数据,在主模式下接收数据; (2) MOSI:主设备输出/从设备输入引脚 该引脚在主模式下发送数据,在从模式下接收数据; (3) CLK:串口时钟 作为主设备的输出,从设备的输入; (4) NSS:从设备选择 这是一个可选的引脚,用来选择从设备。 SPI的工作流程是这样的: (1) 主机先将NSS信号拉低,这样保证开始接收数据; (2) 当接收端检测到时钟的边沿信号时,将立即读取数据线上的信号,这样就得到了一位数据; (3) 由于时钟是随数据一起发送的,因此指定数据的传输速度并不重要,尽管设备将具有可以运行的最高速度; (4) 主机发送到从机时,主机产生相应的时钟信号,然后数据一位一位地将从MOSI信号线上进行发送到从机; (5) 主机接收从机数据时,如果从机需要将数据发送回主机,则主机将继续生成预定数量的时钟信号,并且从机会将数据通过MISO信号线发送。 SPI工作时序图如下: 2、AM62x处理器中SPI总线的特点 在AM62x这款芯片中,TI将SPI的MISO与MOSI设计为d0和d1,具体哪一个作为输入,哪一个作为输出,是由设备树中的 ti,pindir-d0-out-d1-in= 来设置的。 默认属性值为0,即d0是输入,d1是输出; 当属性值为1时,d0为输出,d1为输入。 3、AM62x的SPI应用 (1)menuconfig配置: 将该项选中,SPI驱动将编译进内核中。 makemenuconfi Usermode SPI device driver support (注:在飞凌嵌入式OK6254-C开发板中,SPI驱动编译已进去。) (2)设备树配置: 1) 选择需要使用的spi,这里我们用spi0,节点为&main_spi0; 2) 将该节点所用的引脚复用为相应的功能。 spi0_pins_default: spi0-pins-default { pinctrl-single,pins = < AM62X_IOPAD(0x1B4, PIN_OUTPUT, 0) /* (A13) SPI0_CS0 */ AM62X_IOPAD(0x1B8, PIN_OUTPUT, 0) /* (C13) SPI0_CS1 */ AM62X_IOPAD(0x1C0, PIN_INPUT, 0) /* (B13) SPI0_D0 */ AM62X_IOPAD(0x1BC, PIN_OUTPUT, 0) /* (A14) SPI0_CLK */ AM62X_IOPAD(0x1C4, PIN_INPUT, 0) /* (B14) SPI0_D1 */ ; }; 3) 描述节点的属性,具体配置项的功能见注释。 &main_spi0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = ; /* 描述引脚复用节点 */ ti,spi-num-cs = ; /* 描述片选的数量 */ ti,pindir-d0-out-d1-in = ; /* 描述输入输出分别是哪个 */ /* 描述子节点spidev0设备 */ spidev@0 { spi-max-frequency = ; /* 描述spidev0设备的最大频率 */ reg = ; /* 描述spidev0设备所用的片选,这里是第0个 */ spi-cs-high; /* 描述spidev0设备高有效 */ compatible = "rohm,dh2228fv"; /* 描述spidev0设备所用驱动 */ }; /* 描述子节点spidev1设备 */ spidev@1 { spi-max-frequency = ; reg = ; compatible = "rohm,dh2228fv"; }; }; (3)编译烧录: 在源码路径下输入以下命令: . build.sh sudo ./build.sh kernel 没有报错即为编译成功。 将源码路径下的image中的OK6254-C.dtb文件放到开发板的/boot目录中,重启开发板即可。 (4)SPI测试: 将spi0_D0和spi0_D1短接 重启开发板后,在/dev目录下看到多出两个spidev设备。 使用我们的测试程序 fltest_spidev_test -D /dev/spidev3.0 -s 42000 有如下打印信息即为成功: spimode: 0 bitsper word: 8 maxspeed: 42000 Hz (42 KHz) FFFF FF FF FF FF 4000 00 00 00 95 FFFF FF FF FF FF FFFF FF FF FF FF FFFF FF FF FF FF DEAD BE EF BA AD F00D 4、总结 TI AM62x处理器有着丰富的SPI资源,而SPI又可以作为许多设备的总线,这使得AM62x能够接入许多SPI接口的设备,因此在那些对SPI有着比较多需求的应用场景下,TI AM62x无疑是一个非常好的主控选择。
  • 热度 5
    2024-1-19 15:25
    422 次阅读|
    0 个评论
    对于做快速存储采集数据类产品的用户来说,在处理突发掉电情况时需要保存现有数据并避免数据丢失,这种情况下有很多种解决方案,铁电存储器(FRAM) 就是个很好的选择。FRAM是一种具有快速写入速度的非易失性存储器,既可以进行非易失性数据存储,又可以像RAM一样操作。 本文将借助飞凌嵌入式OK3568-C开发板来为大家介绍一种采用FRAM的方案—— 使用SPI0挂载PB85RS2MC (FRAM) 芯片 。本文所描述的驱动文件和应用文件,可联系飞凌嵌入式的技术支持获取。 修改思路—— 我们要添加一个SPI设备,需要进行如下操作:在设备树中添加描述→设备树描述中对应设备驱动→设备驱动添加到内核。 修改结果—— 修改 OK3568-linux-source/kernel/arch/arm64/boot/dts/rockchip/OK3568-C-common.dtsi 修改如下: 接下来笔者为大家介绍一下适配的过程。 1 驱动程序 我们在menuconfig中搜索fm25、pb85等比较常用的FRAM字眼,发现并没有类似的驱动程序,这时就需要手写或者移植一个驱动程序。在搜遍各大网站之后找到了一个W25Q64的驱动,对比了一下PB85RS2MC的各种操作码以后,发现两者的操作码大差不差,因此就决定将W25Q64的驱动移植过来。根据PB85RS2MC芯片手册中叙述,各种操作码为: 因此,在驱动程序中宏定义以下操作码,以便在接下来的驱动程序中使用: 首先要在驱动程序中进行初始化函数和退出函数,也就是spidev_init和spidev_exit,init函数里就是进行字符设备的初始化,注册等的操作,exit函数就是要把我们注册的东西在退出时都释放掉,再者就是驱动程序和设备树匹配,匹配是通过compatible属性值匹配的,这里我们一定要和设备树中的compatible属性值一致,否则会匹配不成功。驱动程序中.compatible值如下图所示。 驱动和设备树匹配成功以后就要执行probe函数,这里probe函数执行了一些初始化和注册主次设备号的操作。我们可以通过是否打印 spi_probe success! 来判断驱动程序,是否和设备树匹配成功。 从PB85RS2MC芯片手册中看读的条件,读取FRAM存储单元的数据,需要READ的操作码,任意24位地址输入到SI。第一个spi_transfer 结构体用于发送命令cmd 到SPI设备,在读取数据之前准备设备,第二个是发送地址到SPI设备,第三个是接收从设备读取的数据。 这段代码实现了从 SPI设备中同步读取数据,并将数据复制到用户空间的功能。 从PB85RS2MC芯片手册中看写的条件,WREN命令用于设置写使能锁存器。需要在写操作(WRITE命令) 之前使用WREN命令设置写使能锁存器,WRITE命令将数据写入 FRAM存储单元阵列。WRITE操作码、任意24位地址和8位写入数据输入到 SI。 下面这段代码实现了向SPI设备发送写入使能命令的功能。 这段代码实现了向SPI设备同步写入数据的功能。它先发送写入使能命令,然后发送地址信息和数据。 下面这段代码向 SPI设备中同步写入数据的功能,将用户空间的数据复制到设备的发送缓冲区,并调用spidev_sync_write 函数将数据写入SPI 设备。 2 应用程序 向SPI设备写数据,调用lseek来改变写入数据的位置,这样就可以在整个SPI设备里写数据,如./writeframAPP /dev/pb85rs 0 forlinx ( 0 是要写入的地址, forlinx 是要写入的内容)。 从SPI设备读数据,调用lseek来改变读取数据的位置,这样就可以在整个SPI设备里读数据,如./readframAPP /dev/pb85rs 0 ( 0 是要读取数据的地址) 3 实际测试 (1)首先将fram.ko, readframAPP, writefram APP拷贝到OK3568-C开发板的任意文件夹中。 (2)用insmod加载fram.ko模块,出现 spi_probe success! 说明驱动和设备树匹配成功。 (3)在/dev/下看有没有 pb85rs 设备。 (4)使用./writeframAPP /dev/pb85rs 1500 forlinx 向设备写数据, 1500 是地址, forlinx 是要写入的内容。 (5)使用./readframAPP /dev/pb85rs 1500 ( 1500 是要读取数据的地址) 4 断电测试 断电一天后重新读取PB85RS2MC的数据,发现数据仍然存在。验证了PB85RS2MC铁电存储芯片的断电数据保留特性。 至此,我们就完成了在OK3568-C开发板上添加一个新的SPI铁电存储芯片的操作!
  • 热度 3
    2023-9-22 14:31
    1109 次阅读|
    0 个评论
    对于做快速存储采集数据类产品的用户来说,在处理突发掉电情况时需要保存现有数据并避免数据丢失,这种情况下有很多种解决方案,铁电存储器(FRAM) 就是个很好的选择。FRAM是一种具有快速写入速度的非易失性存储器,既可以进行非易失性数据存储,又可以像RAM一样操作。 本文将借助飞凌嵌入式OK3568-C开发板来为大家介绍一种采用FRAM的方案—— 使用SPI0挂载PB85RS2MC (FRAM) 芯片 。本文所描述的驱动文件和应用文件,可联系飞凌嵌入式的技术支持获取。 修改思路—— 我们要添加一个SPI设备,需要进行如下操作:在设备树中添加描述→设备树描述中对应设备驱动→设备驱动添加到内核。 修改结果—— 修改 OK3568-linux-source/kernel/arch/arm64/boot/dts/rockchip/OK3568-C-common.dtsi 修改如下: 接下来笔者为大家介绍一下适配的过程。 1 驱动程序 我们在menuconfig中搜索fm25、pb85等比较常用的FRAM字眼,发现并没有类似的驱动程序,这时就需要手写或者移植一个驱动程序。在搜遍各大网站之后找到了一个W25Q64的驱动,对比了一下PB85RS2MC的各种操作码以后,发现两者的操作码大差不差,因此就决定将W25Q64的驱动移植过来。根据PB85RS2MC芯片手册中叙述,各种操作码为: 因此,在驱动程序中宏定义以下操作码,以便在接下来的驱动程序中使用: 首先要在驱动程序中进行初始化函数和退出函数,也就是spidev_init和spidev_exit,init函数里就是进行字符设备的初始化,注册等的操作,exit函数就是要把我们注册的东西在退出时都释放掉,再者就是驱动程序和设备树匹配,匹配是通过compatible属性值匹配的,这里我们一定要和设备树中的compatible属性值一致,否则会匹配不成功。驱动程序中.compatible值如下图所示。 驱动和设备树匹配成功以后就要执行probe函数,这里probe函数执行了一些初始化和注册主次设备号的操作。我们可以通过是否打印 spi_probe success! 来判断驱动程序,是否和设备树匹配成功。 从PB85RS2MC芯片手册中看读的条件,读取FRAM存储单元的数据,需要READ的操作码,任意24位地址输入到SI。第一个spi_transfer 结构体用于发送命令cmd 到SPI设备,在读取数据之前准备设备,第二个是发送地址到SPI设备,第三个是接收从设备读取的数据。 这段代码实现了从 SPI设备中同步读取数据,并将数据复制到用户空间的功能。 从PB85RS2MC芯片手册中看写的条件,WREN命令用于设置写使能锁存器。需要在写操作(WRITE命令) 之前使用WREN命令设置写使能锁存器,WRITE命令将数据写入 FRAM存储单元阵列。WRITE操作码、任意24位地址和8位写入数据输入到 SI。 下面这段代码实现了向SPI设备发送写入使能命令的功能。 这段代码实现了向SPI设备同步写入数据的功能。它先发送写入使能命令,然后发送地址信息和数据。 下面这段代码向 SPI设备中同步写入数据的功能,将用户空间的数据复制到设备的发送缓冲区,并调用spidev_sync_write 函数将数据写入SPI 设备。 2 应用程序 向SPI设备写数据,调用lseek来改变写入数据的位置,这样就可以在整个SPI设备里写数据,如./writeframAPP /dev/pb85rs 0 forlinx ( 0 是要写入的地址, forlinx 是要写入的内容)。 从SPI设备读数据,调用lseek来改变读取数据的位置,这样就可以在整个SPI设备里读数据,如./readframAPP /dev/pb85rs 0 ( 0 是要读取数据的地址) 3 实际测试 (1)首先将fram.ko, readframAPP, writefram APP拷贝到OK3568-C开发板的任意文件夹中。 (2)用insmod加载fram.ko模块,出现 spi_probe success! 说明驱动和设备树匹配成功。 (3)在/dev/下看有没有 pb85rs 设备。 (4)使用./writeframAPP /dev/pb85rs 1500 forlinx 向设备写数据, 1500 是地址, forlinx 是要写入的内容。 (5)使用./readframAPP /dev/pb85rs 1500 ( 1500 是要读取数据的地址) 4 断电测试 断电一天后重新读取PB85RS2MC的数据,发现数据仍然存在。验证了PB85RS2MC铁电存储芯片的断电数据保留特性。 至此,我们就完成了在OK3568-C开发板上添加一个新的SPI铁电存储芯片的操作!
  • 热度 4
    2023-8-30 15:39
    933 次阅读|
    0 个评论
    SPI主机为Only Transmit 从机为Only Receive SPI主机配置如下: 代码如下 : 如果不进行SPI DISABLE 片选的引脚会一直存在,这个在HAL_SPI_Transmit 函数里面并没有对SPI进行关使能,只能在外面添加,具体为什么没有添加关闭SPI不清楚原因 HAL_SPI_Transmit(&hspi1, tx_buf, sizeof(tx_buf),1000); __HAL_SPI_DISABLE(&hspi1); HAL_Delay(5); SPI 从机配置如下: 代码如下: HAL_SPI_Receive(&hspi1, rx_buf, sizeof(tx_buf),1000); HAL_Delay(5); memset(rx_buf,0,sizeof(rx_buf)); 收发的buf数据如下: 从逻辑分析仪查看数据: 可以看到最后一个字节是CRC校验码 从逻辑分析仪波形观察SPI模块运行逻辑 : 对于主机发送数据情况下: 一旦CR1寄存器的SPE位置1,主机将CS片选引脚拉低,去选择从机,TXE起来后,一旦对DR写数据,时钟和MOSI引脚出来波形数据。 从机接收数据的情况: 等待SR寄存器的RXNE位为1的情况后,对读走DR寄存器的值,对于存在CRC校验的在倒数第二个字节后,对CR1寄存器的CRC_NEXT位写1来开始计算CRC校验 最后等待BUSY位变低,退出接收函数
相关资源