Linux系统驱动(十八)SPI总线(未整理)

文章目录

  • 一、SPI总线协议简介
  • 二、SPI子系统驱动
    • (二)SPI子系统API
    • (三)SPI设备树节点
  • 三、代码示例

一、SPI总线协议简介

高速、同步、全双工、非差分、总线式
传输速度在几十M

差分总线和非差分总线
非差分总线:受压降影响,通信距离短,IIC、SPI、UART
差分总线:抗干扰能力较强,传输距离相对较远,

485总线理论上可以传输1200m

DB9就是串口,有9个引脚,

四根线

四种工作模式,
MODE0和MODE3常用,

spi总线特点

SPI 是串行外设接口(Serial Peripheral Interface)的缩写。它

是 Motorola 公司推出的一种同步串行接口技术,是一种高

速的,全双工,同步的通信总线。

SPI优点:

支持全双工通信,通信简单,数据传输速率快

1):高速、同步、全双工、非差分、总线式

2):主从机通信模式

缺点:

没有指定的流控制,没有应答机制确认是否接收到数据,

所以跟IIC总线协议比较在数据的可靠性上有一定的缺陷。

spi管脚及模式

可以一主机多从机,具体和那个从机通讯通过cs片选决定。

MISO :主机输入,从机输出

MOSI :主机输出,从机输入

SCK :时钟线(只能主机控制)

CS :片选线

数据传输的四种方式:

CPOL(时钟极性) : 0:时钟起始位低电平,1:时钟起始为高电平

CPHA(时钟相位) :0:第一个时钟周期采样,1:第二个时钟周期采样

spi协议解析
在这里插入图片描述
CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据

采样是在第1个边沿,也就是 SCLK由低电平到高电平的跳变,

所以数据采样是在上升沿,数据发送是在下降沿。

CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据

发送是在第1个边沿,也就是 SCLK由低电平到高电平的跳变,

所以数据采样是在下降沿,数据发送是在上升沿。

CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据

采集是在第1个边沿,也就是 SCLK由高电平到低电平的跳变,

所以数据采集是在下降沿,数据发送是在上升沿。

CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据

发送是在第1个边沿,也就是 SCLK由高电平到低电平的跳变,

所以数据采集是在上升沿,数据发送是在下降沿。

二、SPI子系统驱动

在这里插入图片描述

锁存器芯片:IO口扩展,可以锁存,稳定输出

(二)SPI子系统API


(三)SPI设备树节点

spi4: spi@44005000 {#address-cells = <1>; //对子节点描述#size-cells = <0>;compatible = "st,stm32h7-spi";reg = <0x44005000 0x400>;interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;clocks = <&rcc SPI4_K>;resets = <&rcc SPI4_R>;dmas = <&dmamux1 83 0x400 0x01>,<&dmamux1 84 0x400 0x01>;dma-names = "rx", "tx";power-domains = <&pd_core>;status = "disabled"; //1.是否使能};

问:如何将控制器驱动和核心层选配到内核中?

将stm32mp157a中spi控制器设备树和核心层选配到内核中

spi控制器驱动配置:(make menuconfig)
Device Drivers —>
[] SPI support —>
<
> STMicroelectronics STM32 SPI controller

spi核心层配置:
Device Drivers —>
[*] SPI support —>

重新编译内核
make uImage LOADADDR=0xc2000000

将编译好的内核拷贝到tftpboot目录下
cp arch/arm/boot/uImage ~/tftpboot/
2.2spi子系统API
1.分配并初始化对象
struct spi_driver {
int (*probe)(struct spi_device *spi);
//匹配成功执行的函数
int (*remove)(struct spi_device *spi);
//分离的时候执行的函数
struct device_driver driver;
//父类
const struct spi_device_id *id_table;
//idtable匹配方式
};
struct device_driver {
const char *name;
const struct of_device_id of_match_table;
}
2.注册
#define spi_register_driver(driver)
__spi_register_driver(THIS_MODULE, driver)
3.注销
void spi_unregister_driver(struct spi_driver sdrv)
4.一键注册注销的宏
module_spi_driver(变量名)
2.3spi子系统驱动实例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
int m74hc595_probe(struct spi_device
spi)
{
printk(“%s:%s:%d\n”, FILE, func, LINE);
return 0;
}
int m74hc595_remove(struct spi_device
spi)
{
printk(“%s:%s:%d\n”, FILE, func, LINE);
return 0;
}
struct of_device_id oftable[] = {
{.compatible = “hqyj,m74hc595”,},
{}
};
struct spi_driver m74hc595 = {
.probe = m74hc595_probe,
.remove = m74hc595_remove,
.driver = {
.name = “m74hc595”,
.of_match_table = oftable,
}
};
module_spi_driver(m74hc595);
MODULE_LICENSE(“GPL”);

在这里插入图片描述

spi收发数据的接口
int spi_write(struct spi_device *spi, const void *buf, size_t len)
//发数据
int spi_read(struct spi_device *spi, void *buf, size_t len)       
//接收数据
int spi_write_then_read(struct spi_device *spi,                  const void *txbuf, unsigned n_tx,void *rxbuf, unsigned n_rx);
//同时收发
&spi4{pinctrl-names  = "default","sleep";pinctrl-0   = <&spi4_pins_b>;      //工作状态管脚复用pinctrl-1   = <&spi4_sleep_pins_b>;//休眠状态管脚复用cs-gpios = <&gpioe 11 0>;  //设置片选status = "okay";           //使能控制器m74hc595@0{compatible = "hqyj,m74hc595";reg = <0x0>;           //片选的下标spi-max-frequency = <10000000>; //10MHz//spi-cpol;  //mode0模式//spi-cpha;};
};

三、代码示例

数码管驱动

#include <linux/module.h>
#include <linux/init.h>
#include <linux/spi/spi.h>
#include <linux/fs.h>
#include "m74hc595.h"#define CHRNAME "m74hc595"int major;
struct class *cls;
struct device *dev;
struct spi_device * spidriver;int code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71
};int m74hc595_open(struct inode *inode, struct file *file){printk("%s:%d\n",__func__,__LINE__);return 0;
}int m74hc595_close(struct inode *inode, struct file *file){printk("%s:%d\n",__func__,__LINE__);return 0;
}long m74hc595_ioctl(struct file *file, unsigned int cmd, unsigned long arg){u8 data[2]={0};int ret;switch (cmd){case SET_LIGHT_ONE:data[0]=0x01;data[1]=code[arg];ret = spi_write(spidriver,data,2);if(ret){pr_err("spi_write error:%d\n",__LINE__);return -ENAVAIL;}break;case SET_LIGHT_TWO:data[0]=0x2;data[1]=code[arg]|0x80;ret = spi_write(spidriver,data,2);if(ret){pr_err("spi_write error:%d\n",__LINE__);return -ENAVAIL;}break;case SET_LIGHT_THREE:data[0]=0x4;data[1]=code[arg];ret = spi_write(spidriver,data,2);if(ret){pr_err("spi_write error:%d\n",__LINE__);return -ENAVAIL;}break;case SET_LIGHT_FOUR:data[0]=0x8;data[1]=code[arg];ret = spi_write(spidriver,data,2);if(ret){pr_err("spi_write error:%d\n",__LINE__);return -ENAVAIL;}break;default:pr_err("cmd error\n");return -ENAVAIL;}return 0;
}
struct file_operations fops = {.open=m74hc595_open,.release=m74hc595_close,.unlocked_ioctl=m74hc595_ioctl,
};int m74hc595_probe(struct spi_device *spi){printk("%s:%d\n",__func__,__LINE__);spidriver = spi;// 1.注册字符设备驱动major = register_chrdev(0, CHRNAME, &fops);if (major < 0){pr_err("register_chrdev error\n");return major;}// 2.自动创建设备节点cls = class_create(THIS_MODULE, CHRNAME);if (IS_ERR(cls)){pr_err("class_create error\n");unregister_chrdev(major, CHRNAME);return PTR_ERR(cls);}dev = device_create(cls, NULL, MKDEV(major, 0), NULL, CHRNAME);if (IS_ERR(dev)){pr_err("device_create error\n");class_destroy(cls);unregister_chrdev(major, CHRNAME);return PTR_ERR(dev);}return 0;
}
int m74hc595_remove(struct spi_device *spi){printk("%s:%d\n",__func__,__LINE__);device_destroy(cls,MKDEV(major,0));class_destroy(cls);unregister_chrdev(major, CHRNAME);return 0;
}struct of_device_id m74hc595_of_match_table[]={{ .compatible="hqyj,m74hc595" },{},
};
struct spi_driver m74hc595_driver={.probe=m74hc595_probe,.remove=m74hc595_remove,.driver={.name="m74hc595",.of_match_table=m74hc595_of_match_table,}
};
module_spi_driver(m74hc595_driver);
MODULE_LICENSE("GPL");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/401367.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

江协科技STM32学习笔记(第13章 WDG看门狗)

第13章 WDG看门狗 13.1 WDG看门狗 13.1.1 WDG简介 看门狗就是程序运行的一个保障措施&#xff0c;我们得在程序中定期地喂狗&#xff0c;如果程序卡死了&#xff0c;没有在规定的时间里喂狗&#xff0c;那么看门狗硬件电路就会自动帮我们复位一下&#xff0c;防止程序长时间…

最新爆火文生图模型FLUX

在AI图片生成领域&#xff0c;Flux模型的推出引起了广泛关注。随着AI技术的不断进步&#xff0c;新的模型层出不穷&#xff0c;而Flux正是其中的一颗新星。 Flux&#xff1a;一款迅速走红的AI图片生成模型 8月初&#xff0c;初创公司Black Forest Labs推出了文本生成图像模型…

米联客-FPGA程序设计Verilog语法入门篇连载-10 Verilog语法_一般设计规范

软件版本&#xff1a;无 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用所有系列FPGA 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑&#xff01; 1概述 本小节讲解Verilog语法的一般…

合并两个有序数组(LeetCode)

题目 给你两个按 非递减顺序 排列的整数数组 和 &#xff0c;另有两个整数 和 &#xff0c;分别表示 和 中的元素数目。请你 合并 到 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并后数组不应由函数返回&#xff0c;而是…

Docker最佳实践进阶(一):Dockerfile介绍使用

大家好&#xff0c;上一个系列我们使用docker安装了一系列的基础服务&#xff0c;但在实际开发过程中这样一个个的安装以及繁杂命令不仅仅浪费时间&#xff0c;更是容易遗忘&#xff0c;下面我们进行Docker的进阶教程&#xff0c;帮助我们更快速的部署和演示项目。 一、什么是…

【初阶数据结构】通讯录项目(可用作课程设计)

文章目录 概述1. 通讯录的效果2. SeqList.h3. Contact.h4. SeqList.c5. Contact.c6. test.c 概述 通讯录项目是基于顺序表这个数据结构来实现的。如果说数组是苍蝇小馆&#xff0c;顺序表是米其林的话&#xff0c;那么通讯录就是国宴。 换句话说&#xff0c;通讯录就是顺序表…

个人可识别信息(PII) AI 去除 API 数据接口

个人可识别信息(PII) AI 去除 API 数据接口 ai / 隐私保护 基于 AI 模型自动去除个人识别信息&#xff08;PII&#xff09; 个人信息保护 / AI 模型 。 1. 产品功能 基于自有专业模型进行 PII 自动去除高效处理敏感信息全接口支持 HTTPS&#xff08;TLS v1.0 / v1.1 / v1.2 /…

【剑指 offer】镜像二叉树

目 录 描述&#xff1a; 操作给定的二叉树&#xff0c;将其变换为源二叉树的镜像 思路&#xff1a; 仔细观察可以发现&#xff0c;所谓的二叉树镜像本质是自顶向下(or自底向上)进行左右子树交换的过程 public class Solution {public void Mirror(TreeNode root) {if(root nu…

音视频开发继续学习

RGA模块 RGA模块定义 RGA模块是RV1126用于2D图像的裁剪、缩放、旋转、镜像、图片叠加等格式转换的模块。比方说&#xff1a;要把一个原分辨率1920 * 1080的视频压缩成1280 * 720的视频&#xff0c;此时就要用到RGA模块了。 RGA模块结构体定义 RGA区域属性结构体 imgType&am…

LeetCode-3148. 矩阵中的最大得分

本人算法萌新,为秋招找工作开始磨炼算法,算法题均用python实现,如果我有哪些地方做的有问题的,还请大家不吝赐教. 1.题干 给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格&#xff08;不必相邻&…

提高办公效率,四款语音转文字工具推荐!

无论是在会议记录、采访速记还是日常笔记中&#xff0c;语音转文字技术都展现出了其独特的价值。接下来是就为大家推荐几款市面上广受好评的语音转文字工具&#xff01; 365在线转文字 链接&#xff1a;https://www.pdf365.cn/ 365在线转文字是一款非常实用的在线语音转文字…

【Unity/网络】Unity和内网穿透的网络测试 —— 以聊天室为例

这两天在做那个CodeMonky的胡闹厨房的案例&#xff0c;一直困扰我的是关于Lobby和Relay的相关网络服务&#xff0c;需要挂加速器并且延迟不低&#xff0c;所以我一直在寻找一些其他替代方案&#xff0c;想起来之前做一个UEC的网络枪战时做过一个内网穿透的方法&#xff0c;所以…

机械行业数字化生产供应链产品解决方案(十二)

我们为机械行业提供的数字化生产供应链解决方案通过集成物联网、人工智能和大数据技术&#xff0c;打造了一套智能化的生产和供应链管理系统&#xff0c;实现了从设计、生产到物流的全程数字化、智能化。该系统通过实时数据采集与分析&#xff0c;优化生产计划和资源配置&#…

前后端分离项目实战-通用管理系统搭建(前端Vue3+ElementPlus,后端Springboot+Mysql+Redis)第二篇:项目登录功能的实现

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

怎么等比例调整图片尺寸大小?调整图片尺寸的8个方法

在数字时代&#xff0c;图片已成为我们日常生活与工作中不可或缺的一部分。从社交媒体分享到专业设计项目&#xff0c;图片的质量和外观直接影响着信息的传达与接收。因此&#xff0c;在处理图片时&#xff0c;保持其原始的纵横比&#xff0c;即等比例调整图片尺寸&#xff0c;…

梅丽尔·斯特里普表演艺术家中心对外开放并恢复线下活动 体现了她的“卓越”

梅丽尔斯特里普表演艺术家中心对外开放并恢复线下活动 体现了她的“卓越” 2024-08-14 20:38 发布于&#xff1a;河北省 该中心将为美国演员工会和美国电视广播艺人协会的艺术家提供资源和机会&#xff0c;而且全部免费 同时命名的还有汤姆汉克斯和丽塔威尔逊放映室、妮可…

PHP 无参数RCE总结

在这篇文章中&#xff0c;我总结了在参与CTF比赛过程中积累的关于PHP无参数远程代码执行&#xff08;RCE&#xff09;的经验。由于一直以来时间有限&#xff0c;今天终于有机会整理这些知识点。 可能用到的函数&#xff08;PHP的内置函数&#xff09; localeconv() 函数返回一…

安美数字酒店宽带运营系统 weather.php 任意文件读取漏洞复现

0x01 产品简介 HiBOS酒店宽带运营系统是由安美世纪(北京)科技有限公司开发的一套专为酒店设计的宽带管理系统。该系统旨在提升酒店宽带服务的运营效率和安全性&#xff0c;为酒店客人提供稳定、高速、便捷的上网体验。 0x02 漏洞概述 安美数字酒店宽带运营系统 weather.php …

Ansible自动化运维中剧本角色(roles)来完成apache服务操作

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; Ansible…

Kafka服务端日志详解

文章目录 服务端日志Topic消息存储方式主体介绍log文件追加记录消息index和timeindex索引文件 日志文件清理Kafka的文件高效读写机制Kafka的文件结构顺序写磁盘零拷贝 合理配置刷盘频率客户端消费进度管理 服务端日志 Kafka的日志信息是通过conf/server.properties文件中的log…