当前位置: 首页 > news >正文

wordpress迁站页面设计作品

wordpress迁站,页面设计作品,网站如何优化排名,湖南关键词优化推荐一、SPI基础 📢SPI是一种常见的设备通用通信协议。它有一个独特优势就是可以无中断传输数据,可以连续地发送或接收任意数量的位。而在I2C和UART中,数据以数据包的形式发送,有着限定位数。1 SPI优缺点优点 SPI 通讯无起始位和停止位…

一、SPI基础

📢SPI是一种常见的设备通用通信协议。它有一个独特优势就是可以无中断传输数据,可以连续地发送或接收任意数量的位。而在I2C和UART中,数据以数据包的形式发送,有着限定位数。

1 SPI优缺点

  • 优点

    SPI 通讯无起始位和停止位,因此数据可以连续流传输而不会中断;没有像 I2C 这样的复杂的从站寻址系统,数据传输速率比 I2C 更高(几乎快两倍)。独立的 MIS0 和 MOSI 线路,可以同时发送和接收数据。

  • 缺点

    SPI 使用四根线(I2C 和 UART 使用两根线),没有信号接收成功的确认(I2C 拥有此功能),没有任何形式的错误检查(如 UART 中的奇偶校验位等)。

2 SPI通信原理

在 SPI 设备中,设备分为主机与从机系统。

  • 主机是控制设备(通常是控制器)
  • 从机(通常是传感器或存储芯片)从主机那获取指令。

一套SPI通讯共包含四种信号线:

  • MOSI(Master 0utput/slave Input) - 信号线,主机输出,从机输入。
  • MISo(Master Input/slave output) - 信号线,主机输入,从机输出。
  • SCLK(Clock) - 时钟信号:
  • Ss/cs(5lave Select/chip select) - 片选信号。
2.1 时钟信号

每个时钟周期传输一位数据,因此数据传输的速度取决于时钟信号的频率。 时钟信号由于是主机配置生成的,因此SPI 通信始终由主机启动。

设备共享时钟信号的任何通信协议都称为同步。 SPI 是一种同步通信协议,还有一些异步通信不使用时钟信号。

例如在 UART 通信中,双方都设置为预先配置的波特率,该波特率决定了数据传输的速度和时序。

2.2 片选信号

主机通过拉低从机的 CS/SS 来使能通信。 在空闲/非传输状态下,片选线保持高电平。在主机上可以存在多个CS/SS 引脚,允许主机与多个不同的从机进行通讯。

2.3 MOSI和MISO

主机通过 MOSI 以串行方式将数据发送给从机,从机也可以通过 MISO 将数据发送给主机,两者可以同时进行。所以理论上,SPI 是一种全双工的通讯协议。

传输步骤:

以传输模式:CPOL=0、CPHA =0为例:

  1. 主设备配置SPI参数
    1. 设置时钟极性 (<font style="background-color:rgb(242,243,245);">CPOL</font>): 定义 SCK 线在空闲状态(无数据传输时)的电平(高电平 <font style="background-color:rgb(242,243,245);">1</font> 或低电平 <font style="background-color:rgb(242,243,245);">0</font>)。
    2. 设置时钟相位 (<font style="background-color:rgb(242,243,245);">CPHA</font>): 定义数据在 SCK 时钟的哪个边沿(第一个边沿或第二个边沿)进行采样(锁存)。
  2. 主机输出时钟信号

  1. 主机拉低从机SS/CS 引脚,激活从机

  1. 主机通过MOSI将数据发送给从机

  1. 如果需要响应,则从机通过MISO将数据返回给主机

  1. 主设备取消选中从设备 (结束通信):
    1. 最后一个数据位传输完成后,主设备将目标从设备的片选 (<font style="background-color:rgb(242,243,245);">CS</font> / <font style="background-color:rgb(242,243,245);">SS</font>) 引脚拉高(无效)。
    2. 这个上升沿通知从设备通信结束。从设备停止驱动 MISO 线(变为高阻态)。
    3. SCK 线恢复到 <font style="background-color:rgb(242,243,245);">CPOL</font> 定义的空闲电平。
2.4 数据传输

为了开始通信,总线上的主设备需要使用从设备支持的频率来配置时钟,这个频率最高为几兆赫兹左右。然后主设备将某个从设备的SS线置为低电平,来选中这个从设备。如果等待时间是必要的话(例如进行模数转换),主设备必须在这段时间结束后,才可以发出时钟周期信号。

在每个SPI时钟周期内,都会发生全双工数据传输。主设备在MOSI线上发送一个位,从设备读取它,同时从机在MISO线上发送一位数据,主机读取它。即使只有单向数据传输的目的,主从机之间的通信工作方式仍然是双工内。

传输通常会使用给定字长的两个移位寄存器,一个在主设备中,一个在从设备中,这两个寄存器连接成一个虚拟的环形缓冲器。数据通常先从最高位移出。在时钟信号边沿,主机和从机均移出一位,然后在传输线上输出给对方。在下一个时钟沿,每个接收器都从传输线接受对方发出的数据位,并且从移位寄存器的最低位推入。每完成这样-个移出–推入的周期后,主机和从机就交换寄存器中的一位数据。当所有数据位都经过了这样的移出–推入过程后,主机和从机就完成了寄存器上的数据交换。如果需要交换的数据比寄存器的位数还要长的话,则需要重新加载移位寄存器并重复该过程。传输可能会持续任意数量的时钟周期。完成后,主设备会停止发送时钟信号,并通常会取消选择从设备。

传输寄存器通常包含8位。但是其他字长也很常见,例如触摸屏控制器或音频编解码器通常采用 16 位字长(如德州仪器的 TSC2101 ),许多数模转换或者模数转换的设备则会采用 12 位字长。所有在总线上的没有被片选线激活的从设备必须忽略输入时钟和 MOSI 信号,并且不得从 MISO 发送数据。

2.5 模式

分别是 CPOL(Clock POlarity)和 CPHA (Clock PHAse)

  • CPOL配置SPI总线的极性
  • CPHA配置SPI总线的相位

SPI总线的极性

极性,会直接影响SPI总线空闲时的时钟信号是高电平还是低电平

  • CPOL=1:表示空闲时是高电平
  • CPOL=0:表示空闲时是低电平

SPI总线的相位

一个时钟周期会有2个跳变沿。而相位,直接决定SPI总线从那个跳变沿开始采样数据。

  • CPHA =0:表示从第一个跳变沿开始采样
  • CPHA =1:表示从第二个跳变沿开始采样

4种模式

modeCPOLCPHA
mode 000
mode 101
mode 210
mode 311

模式0(CPOL=0; CPHA=0)

特性:

CPOL = 0: 空闲时是低电平,第1个跳变沿是上升沿,第2个跳变沿是下降沿
CPHA = 0: 数据在第1个跳变沿(上升沿)采样

模式1(CPOL=0; CPHA=1)

特性:

CPOL =0 : 空闲时是低电平,第1个跳变沿是上升沿,第2个跳变沿是下降沿
CPHA =1 : 数据在第2个跳变沿(下降沿)采样

模式2(CPOL=1;CPHA=0)

CPOL = 1:空闲时是高电平,第1个跳变沿是下降沿,第2个跳变沿是上升沿
CPHA = 0:数据在第1个跳变沿(下降沿)采样

模式3(CPOL=1; CPHA=1)

CPOL = 1:空闲时是高电平,第1个跳变沿是下降沿,第2个跳变沿是上升沿
CPHA = 1:数据在第2个跳变沿(上升沿)采样

2.6 DSPI 和 QSPI

SPI 协议其实是包括:Standard SPI、Dual SPI 和 Queued SPI 三种协议接口。

  • Dual SPI还是四线制,只是传输线可以变为同方向,速度是 Standard SPI 的两倍。
  • Queued SPI 是六线制,多了两根数据线,传输速度是 Standard SPI的四倍,

二、SPI硬件分析

三、SPI设备树设置

main_spi0: spi@2100000 {compatible = "ti,am654-mcspi","ti,omap4-mcspi";//与驱动对应的名字reg = <0x00 0x02100000 0x00 0x400>;interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;#address-cells = <1>;#size-cells = <0>;power-domains = <&k3_pds 339 TI_SCI_PD_EXCLUSIVE>;clocks = <&k3_clks 339 1>;status = "disabled";};&main_spi0{status = "okay";# assigned-clock-rates = <200000000>; //默认不用配置,SPI 设备工作时钟值,io 时钟由工作时钟分频获取pinctrl-names = "default";pinctrl-0 = <&myspi0_pins_default>;dmas = <&main_udmap 0xc600>, <&main_udmap 0x4600>;dma-names = "tx0", "rx0"; //使能DMA模式,通讯长度少于32字节不建议用,置空赋值去掉使能,如"dma-names;";# rx-sample-delay-ns = <10>; //默认不用配置,读采样延时/*default: ti,pindir-d0-in-d1-out *//*ti,pindir-d0-out-d1-in; */spidev@0{compatible = "rohm,dh2228fv";reg = <0>;//0-spidev1.0,3-spidev1.3spi-max-frequency = <24000000>;//spi clk输出的时钟频率,不超过50Mspi-cpol = <0>; //1-89501,0-89541spi-cpha = <0>; //1-89501,0-89541};
};

spiclk assigned-clock-ratesspi-max-frequency 的配置说明:

  • spi-max-frequency 是 SPI 的输出时钟,由 SPI 工作时钟 spiclk assigned-clock-rates内部分频后输出,由于内部至少 2 分频,所以关系是 spiclk assigned-clock-rates >= 2*spi-max-frequency
  • 假定需要 50MHz 的 SPI IO 速率,可以考虑配置(记住内部分频为偶数分频)spi_clk assigned-clock-rates = <100000000>spi-max-frequency =<50000000>,即工作时钟 100 MHz(PLL 分频到一个不大于 100MHz 但最接近的值),然后内部二分频最终 IO 接近 50 MHz;
  • spiclk assigned-clock-rates 不要低于 24M,否则可能有问题;
  • 如果需要配置 spi-cpha 的话, 要求 spiclk assigned-clock-rates <= 6M, 1M <=spi-max-frequency >=3M

四、spi使用方法

1 spi_test 使用

在 Linux 系统上,“spidev_test” 是一个用于测试和配置 SPI(Serial Peripheral Interface)设备的命令行工具。SPI是一种串行通信协议,通常用于连接微控制器、传感器和其他外部设备。“spidev_test” 工具通常在Linux系统上使用,用于检查SPI接口的正确性以及与SPI设备的通信是否正常工作。

  • 代码位置:kernel/tools/spi
  • 使用帮助:
./spidev_test  -h
./spidev_test: invalid option -- 'h'
Usage: ./spidev_test [-2348CDFHILMNORSZbdilopsv]
general device settings:-D --device         device to use (default /dev/spidev1.1)-s --speed          max speed (Hz)-d --delay          delay (usec)-l --loop           loopback
spi mode:-H --cpha           clock phase-O --cpol           clock polarity-F --rx-cpha-flip   flip CPHA on Rx only xfer
number of wires for transmission:-2 --dual           dual transfer-4 --quad           quad transfer-8 --octal          octal transfer-3 --3wire          SI/SO signals shared-Z --3wire-hiz      high impedance turnaround
data:-i --input          input data from a file (e.g. "test.bin")-o --output         output data to a file (e.g. "results.bin")-p                  Send data (e.g. "1234\xde\xad")-S --size           transfer size-I --iter           iterations
additional parameters:-b --bpw            bits per word-L --lsb            least significant bit first-C --cs-high        chip select active high-N --no-cs          no chip select-R --ready          slave pulls low to pause-M --mosi-idle-low  leave mosi line low when idle
misc:-v --verbose        Verbose (show tx buffer)

以下是一些常见的 “spidev_test” 命令行选项和说明:

  • -D 或 --device:用于指定SPI设备的路径。通常,SPI设备的路径类似于 “/dev/spidevX.Y”,其中X是SPI控制器的编号,Y是SPI设备的编号。
  • -s 或 --speed:用于设置SPI通信的时钟速度,以Hz为单位。例如,-s 1000000 将设置SPI时钟速度为1 MHz。
  • -b 或 --bits:用于设置每个字节的位数。SPI通信通常使用8位,但可以根据需要进行配置。
  • -v 或 --verbose:用于启用详细的输出,以便查看SPI通信的细节。
  • -w 或 --write:用于发送数据到SPI设备。可以使用此选项将数据发送到设备。
  • -r 或 --read:用于从SPI设备读取数据。可以使用此选项读取来自设备的数据。
  • -p 或 --loop:用于设置循环模式。如果启用了循环模式,“spidev_test” 将持续运行,不断发送和接收数据。
  • -h 或 --help:用于显示帮助信息,列出可用的命令行选项和其说明。
spidev_test -D /dev/spidev0.0 -s 15000000 -p "bbbbbbbbbbbbbbbb" -vspidev_test -D /dev/spidev2.0 -s 15000000 -p "bbbbbbbbbbbbbbbb" -v

2 应用编程

#include <sys/ioctl.h>int ioctl(int fd, unsigned long request, ...);

当使用ioctl函数进行SPI通信时,常用的request参数主要有以下几种:

  • SPI_IOC_RD_MODE:用于读取当前SPI通信的模式设置。这个请求参数将模式信息读取到一个整数变量中,以便检查当前SPI通信的极性和相位设置。
  • SPI_IOC_WR_MODE:用于设置SPI通信的模式。您需要提供一个整数值,该值通常由两位二进制数字组成,表示SPI通信的极性和相位。
  • SPI_IOC_RD_BITS_PER_WORD:用于读取每个数据字的位数。这个请求参数将位数信息读取到一个整数变量中。
  • SPI_IOC_WR_BITS_PER_WORD:用于设置每个数据字的位数。您需要提供一个整数值,以指定要发送和接收的每个数据字的位数。
  • SPI_IOC_RD_MAX_SPEED_HZ:用于读取SPI总线的最大速度。这个请求参数将速度信息读取到一个整数变量中,以便检查当前SPI总线的最大传输速度。
  • SPI_IOC_WR_MAX_SPEED_HZ:用于设置SPI总线的最大速度。您需要提供一个整数值,以指定要使用的最大传输速度。
  • SPI_IOC_MESSAGE(N):用于执行SPI传输的读写操作。这个请求参数需要一个指向 struct spi_ioc_transfer 数组的指针,每个元素描述了一个SPI传输操作,可以执行多个操作。
  • SPI_IOC_RD_LSB_FIRST:用于读取LSB(Least Significant Bit)优先设置。这个请求参数将LSB优先信息读取到一个整数变量中。
  • SPI_IOC_WR_LSB_FIRST:用于设置LSB优先设置。您需要提供一个整数值,以指定是否要使用LSB优先模式。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>static volatile int keep_running = 1;void int_handler(int dummy)
{keep_running = 0;
}int main(int argc, char *argv[])
{int fd;int ret;uint32_t target_speed, actual_speed;uint8_t mode = SPI_MODE_0;uint8_t bits = 8;size_t packet_len;if (argc < 4) {fprintf(stderr, "Usage: %s <device> <speed> <len>\n", argv[0]);fprintf(stderr, "Example: %s /dev/spidev0.0 15000000 256\n", argv[0]);return EXIT_FAILURE;}const char *device = argv[1];target_speed = strtoul(argv[2], NULL, 10);packet_len = strtoul(argv[3], NULL, 10);if (packet_len == 0) {fprintf(stderr, "Error: len must be > 0\n");return EXIT_FAILURE;}fd = open(device, O_RDWR);if (fd < 0) {perror("can't open device");return EXIT_FAILURE;}// 设置 SPI 模式ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);if (ret == -1) {perror("can't set spi mode");close(fd);return EXIT_FAILURE;}// 设置字长ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);if (ret == -1) {perror("can't set bits per word");close(fd);return EXIT_FAILURE;}// 申请速率ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &target_speed);if (ret == -1) {perror("can't set max speed hz");close(fd);return EXIT_FAILURE;}// 读取内核实际使用的速率ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &actual_speed);if (ret == -1) {perror("can't get max speed hz");close(fd);return EXIT_FAILURE;}printf("SPI device: %s\n", device);printf("Target speed: %u Hz (%.2f MHz)\n", target_speed, target_speed / 1e6);printf("Actual speed: %u Hz (%.2f MHz)\n", actual_speed, actual_speed / 1e6);printf("Packet length: %zu bytes\n", packet_len);// -------------------// 持续发送测试数据// -------------------uint8_t *tx_buf = malloc(packet_len);uint8_t *rx_buf = malloc(packet_len);if (!tx_buf || !rx_buf) {perror("malloc failed");close(fd);return EXIT_FAILURE;}for (size_t i = 0; i < packet_len; i++) {tx_buf[i] = (uint8_t)(i & 0xFF);rx_buf[i] = 0;}struct spi_ioc_transfer tr = {.tx_buf = (unsigned long)tx_buf,.rx_buf = (unsigned long)rx_buf,.len = packet_len,.speed_hz = actual_speed,.bits_per_word = bits,.cs_change = 0,   // 每次传输结束释放 CS};signal(SIGINT, int_handler);printf("Start continuous transfer, press Ctrl+C to stop...\n");while (keep_running) {ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);if (ret < 1) {perror("can't send spi message");break;}}printf("Transfer stopped.\n");free(tx_buf);free(rx_buf);close(fd);return EXIT_SUCCESS;
}
http://www.dtcms.com/a/417037.html

相关文章:

  • 品牌网站建设设计免费ppt课件模板大全
  • 南昌做网站的公司公司找人做网站
  • 中国建设银行龙卡信用卡网站码迷seo
  • 免费学软件的自学网站做网站的一个月能赚多少钱
  • 宁夏建设厅网站首页软件开发的公司
  • 建立了网站后如何发贴我们网站百度快照显示违规内容
  • 哪里有做网站定制衣服的厂家
  • 暴利产品竞价单页网站弄个直播平台大概要多少钱
  • 网站建设策划框架如何在360网站网页上做笔记
  • 公司网站做优化网站建设费用的会计核算
  • 网站怎么添加百度地图做网站用asp还是php
  • 广州网站建设年底促销网站如何做seo的
  • 微网站绑定域名书店建设网站
  • 廊坊网站制作潍坊公司电话使用织梦系统建设网站教程
  • 软件工程师是做什么的镇海seo关键词优化费用
  • 做intor的网站电信外包有必要去吗
  • 后台与网站北京网站建设公司艺唯思
  • 大连网站专业制作镇江企业网站制作
  • 深圳哪里有做网站的公司做定制的网站
  • 楼盘销售管理网站开发资源插画设计
  • 成都做营销型网站推广网站流量分布
  • 个性化网站建设公司网站建设简洁
  • 网站制作要用哪些软件有哪些网上书店网站前端搜索条怎么做
  • 广东省省建设厅网站零库存品牌童装杭州网站建设
  • 南通网站建设教程上海市企业
  • 关键词做网站标题是什么意思凡科做网站给后台的吗
  • QEvent和它的涉及类继承体系和设计思想
  • 上海的加盟网站建设wordpress表单生成
  • 网站开发 业务流程图国外做家装的网站有哪些
  • 上海知名的网站建设公司网站开发商怎么关闭图片显示