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

嵌入式第六十七天(SPI子系统架构)

SPI子系统架构

SPI硬件构成

SPI(Serial Peripheral Interface)是一种同步串行通信接口,硬件上由以下信号线构成:

  • SCLK(Serial Clock):主设备产生的时钟信号,用于同步数据传输。
  • MOSI(Master Out Slave In):主设备输出、从设备输入的数据线。
  • MISO(Master In Slave Out):从设备输出、主设备输入的数据线。
  • CS(Chip Select):片选信号,由主设备控制,用于选择从设备。
  • GND(Ground):共地参考,确保电平一致。
时钟极性与相位

SPI的通信模式由时钟极性(CPOL)和时钟相位(CPHA)共同决定,组合出四种工作模式:

  • CPOL(Clock Polarity):定义SCLK空闲时的电平状态。

    • CPOL=0:SCLK空闲时为低电平,有效时从低到高跳变。
    • CPOL=1:SCLK空闲时为高电平,有效时从高到低跳变。
  • CPHA(Clock Phase):定义数据采样的边沿。

    • CPHA=0:数据在SCLK的第一个边沿(上升或下降)采样。
    • CPHA=1:数据在SCLK的第二个边沿采样。
四种SPI模式
  1. Mode 0CPOL=0CPHA=0

    • SCLK空闲为低电平,数据在上升沿采样。
  2. Mode 1CPOL=0CPHA=1

    • SCLK空闲为低电平,数据在下降沿采样。
  3. Mode 2CPOL=1CPHA=0

    • SCLK空闲为高电平,数据在下降沿采样。
  4. Mode 3CPOL=1CPHA=1

    • SCLK空闲为高电平,数据在上升沿采样。

adxl345_drv.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>
#include <linux/spi/spi.h>static struct spi_device *spi_device = NULL;static int init_adxl345(void)
{int ret = 0;unsigned char txbuf[2] = {0};unsigned char rxbuf[2] = {0};txbuf[0] = 0x31 | 0x80;ret = spi_write_then_read(spi_device, txbuf, 2, rxbuf, 2);if (ret) {pr_info("spi_write_then_read failed\n");return -1;}txbuf[0] = 0x31;txbuf[1] = rxbuf[1] | 0x3;ret = spi_write_then_read(spi_device, txbuf, 2, NULL, 0);if (ret) {pr_info("spi_write_then_read failed\n");return -1;}txbuf[0] = 0x2D;txbuf[1] = 0x0B;ret = spi_write_then_read(spi_device, txbuf, 2, NULL, 0);if (ret) {pr_info("spi_write_then_read failed\n");return -1;}return 0;
}static int read_adxl345_xyz(short *pdata, int num)
{int ret = 0;unsigned char rxbuf[7];unsigned char txbuf[7];struct spi_message sendmessage;struct spi_transfer transfer = {.tx_buf = txbuf,.rx_buf = rxbuf,.len = 7,.delay_usecs = 20,};spi_message_init(&sendmessage);txbuf[0] = 0x32 | 0x80 | 0x40;  spi_message_add_tail(&transfer, &sendmessage);ret = spi_sync(spi_device, &sendmessage);if (ret) {pr_info("spi_async failed\n");return -1;}pdata[0] = ((rxbuf[1] << 8) | (rxbuf[2]));pdata[1] = ((rxbuf[3] << 8) | (rxbuf[4]));pdata[2] = ((rxbuf[5] << 8) | (rxbuf[6]));return 0;
}static ssize_t adxl345_read(struct file *fp, char __user *puser, size_t n, loff_t *off)
{int ret = 0;short data[3] = {0};unsigned long nret = 0;ret = init_adxl345();if (ret) {pr_info("init_adxl345 failed\n");return -1;}ret = read_adxl345_xyz(data, 3);if (ret) {pr_info("read_adxl345_xyz failed\n");return -1;}nret = copy_to_user(puser, data, sizeof(data));if (nret) {pr_info("copy_to_user failed\n");return -1;}return 0;
}static struct file_operations fops = {.owner = THIS_MODULE,.read = adxl345_read,
};static struct miscdevice misc_adxl345 = {.minor = MISC_DYNAMIC_MINOR,.name = "misc_adxl345",.fops = &fops,
};static int adxl345_probe(struct spi_device *spi)
{int ret = 0;spi_device = spi;ret = misc_register(&misc_adxl345);if (ret) {pr_info("misc_register failed\n");return -1;}pr_info("probe ok\n");return 0;
}static int adxl345_remove(struct spi_device *spi)
{int ret = 0;ret = misc_deregister(&misc_adxl345);if (ret) {pr_info("misc_deregister failed\n");return -1;}pr_info("remove ok\n");return 0;
}static struct spi_device_id adxl345_id_table[] = {{.name = "puteadxl345"},{},
};static struct of_device_id adxl345_of_match_table[] = {{.compatible = "pute,puteadxl345"},{},
};static struct spi_driver adxl345_drv = {.probe = adxl345_probe,.remove = adxl345_remove,.driver = {.name = "puteadxl345",.owner = THIS_MODULE,.of_match_table = adxl345_of_match_table,},.id_table = adxl345_id_table,
};module_spi_driver(adxl345_drv);MODULE_LICENSE("GPL");
MODULE_AUTHOR("pute");

adxl345_app.c

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>int main(void)
{int fd = 0;short data[3] = {0};fd = open("/dev/misc_adxl345", O_RDWR);if (-1 == fd){perror("fail to open");return -1;}while (1){read(fd, data, sizeof(data));printf("x = %010d,y = %010d,z = %010d\r", data[0]);fflush(stdout);usleep(10000);}close(fd);return 0;
}

http://www.dtcms.com/a/446035.html

相关文章:

  • MVC 视图
  • 公司网站运营方案东莞市建设工程检测中心网站
  • 从 C 到 C++:用 C 语言思维理解面向对象四大特性
  • SOFA 架构--02--核心中间件与工具
  • 如何利用淘宝建设网站挣钱在线注册个体工商户
  • 近世代数(抽象代数)详细笔记--域
  • 计算机网络第四章(5)——网络层《路由协议+路由协议》
  • KingbaseES在Alibaba Cloud Linux 3 的深度体验,从部署到性能实战
  • Oracle OCP认证考试题目详解082系列第50题
  • 网站建设流程百科wordpress响应式博客主题模版
  • Leetcode 3704. Count No-Zero Pairs That Sum to N
  • 微信小程序入门学习教程,从入门到精通,WXSS样式处理语法基础(9)
  • 网站开发技术 文库国外医院网站设计
  • 旅游网站建设的总结深圳市勘察设计
  • 企业网站建设费用的预算西安seo网站关键词
  • jvm垃圾回收算法和垃圾收集器(Serial、Parallel、Parnew、CMS)
  • R 绘图 - 条形图
  • 基于GitHub Copilot的自动化测试流水线
  • MacOS 下 Warp ping 局域网设备报错 ping: sendto: No route to host 的解决方法
  • 网站建设服务标语湖北网站建设搭建
  • reset arp all 概念及题目
  • 如何在 IDEA 中使用 Proguard 自动混淆 Gradle 编译的Java 项目
  • 吉林沈阳网站建设河南互联网公司
  • [人工智能-综述-19]:现在所有使用计算机软件、硬件等技术栈的地方,都将被AI智能体所颠覆和替代
  • 生产架构nginx+spring cloud+redis+mysql+ELFK部署(草稿)
  • 备案网站多少钱镇江市住房与城乡建设部网站
  • 符号运算(华为OD)
  • C++微基础备战蓝桥杯之数组篇10.1
  • 美发店会员管理系统更新
  • HTB Attacking GraphQL Skills Assessment