当前位置:首页 > 公众号精选 > 嵌入式大杂烩
[导读]关注「嵌入式大杂烩」,选择「星标公众号」一起进步!作者 |  Acuity1.写在前面spi(SerialPeripheralInterface)即串行外设接口。与i2c一样,spi也常用外设设备通信的总线,从事嵌入式开发必不可少的掌握。根据本人以往的经历,对spi进行总结(主要...

关注「嵌入式大杂烩」,选择「星标公众号」一起进步!



作者 |  Acuity


1.写在前面

spi(Serial Peripheral Interface)即串行外设接口。与i2c一样,spi也常用外设设备通信的总线,从事嵌入式开发必不可少的掌握。


根据本人以往的经历,对spi进行总结(主要是MCU范畴,Linux已有成熟的驱动设备),主要目的及实现:


1)spi总线与spi设备分离;


2)快速使用新的硬件spi或者模拟spi;


3)方便移植spi总线设备及spi外设程序到不同mcu平台。


2.spi总线抽象

此部分实现源码为:spi_core.c spi_core.h


2.1 spi总线模型对外接口(API)

/*extern function*/
extern int spi_send_then_recv(struct spi_dev_device *spi_dev,const void *send_buff,
unsigned short send_size,void *recv_buff,unsigned short recv_size)
;
extern int spi_send_then_send(struct spi_dev_device *spi_dev,const void *send_buff1,
unsigned short send_size1,const void *send_buff2,unsigned short send_size2)
;
extern int spi_send_recv(struct spi_dev_device *spi_dev,const void *send_buff,void *recv_buff,unsigned short data_size);
extern int spi_send(struct spi_dev_device *spi_dev,const void *send_buff,unsigned short send_size);
1)spi_send_then_recv,标准spi,常规操作,发送完一帧再接收,如读取某芯片寄存器的值;


2)spi_send_then_send,标准spi,常规操作,发送完一帧再发送,如向某芯片寄存器(地址)写入数据;


3)spi_send_recv,非标spi,具体看芯片时序图,产生时钟信号,发送完成的同时,也接收完成;第二种情况是,只接收,发送动作只是用来产生时钟信号,如一些AD芯片;


4)spi_send,标准或非标spi都使用,只发送无返回值或者无须理会返回值,如spi LCD屏。


2.2 spi总线抽象API实现

以“spi_send_then_recv”函数为例:


1)spi_dev:spi设备指针,类型为“struct spi_dev_device”,驱动一个spi外设时,首先需要对此指针进行初始化;


2)send_buff:待发送数据(缓存);


3)send_size:发送数据量大小(单位字节);


4):recv_buff:存放返回值数据缓存(地址);


5):recv_size:返回数据量大小。


另外3个函数,第一个参数都为spi设备指针,其他参数为发送/接收缓冲区,收发数据量等,通过变量名即可看出。


2.3 struct spi_de_device

该结构体为关键,调用API驱动一个外设时,需要先初始化(类似Linux的注册设备驱动)。一个完整的spi外设,包括片选和总线量部分,一个总线可和多个片选组成,驱动多个外设,因此struct spi_dev_device设计原型为:


struct spi_dev_device
{

void (*spi_cs)(unsigned char state);
struct spi_bus_device *spi_bus;
};
1)第一个参数为函数指针,主要功能的实现spi外设片选的选择(拉低/拉高)功能;


2)第二个参数为spi总线相关的结构体指针,主要是底层相关收据收发的的功能,具体继续往下看改结构体。


2.4 struct spi_bus_device *spi_bus

该结构体为底层硬件相关的spi总线实现,具体由实际需求实现,如用硬件spi还是用模拟spi。struct spi_bus_device*spi_bus原型为:


struct spi_bus_device
{

int (*spi_bus_xfer)(struct spi_dev_device *spi_bus,struct spi_dev_message *msg);
void *spi_phy;
unsigned char data_width;
};
1)第一个参数是函数指针,为spi总线收发函数,这部分就是我们平常写裸机代码时候写到的,只是这里把它放在一个结构体里面,以函数指针的方式实现;这样的好处是,上层接口不变,更好其他MCU或者使用模拟spi时,只需修改此部分的函数实体,上层代码不需变动。


2)第二个参数,一个指针,表示具体物理spi,如stm32的SPI1、SPI2,或者模拟spi;


3)第三参数,数据宽度,一般是8bit或者16bit。


其他参数,如数据速率、spi模式等,其实也可以放在此处,只是个人觉得此类参数不常变动,为了节约内存,故不加入此结构体配置中。下面中断分析函数指针


int (*spi_bus_xfer) (struct spi_dev_device *spi_bus,struct spi_dev_message *msg)”的实现。

2.5 spi_bus_xfer

该函数指针入口参数为spi设备指针(struct spi_dev_device )、spi设备信息帧指针(struct spi_dev_message)。struct spi_dev_device与前面提及的为同一类参数,struct spi_dev_message为收发数据信息帧,其原型如下:


struct spi_dev_message
{

const void *send_buf;
void *recv_buf;
int length;
unsigned char cs_take    : 1;
unsigned char cs_release : 1;
};
1)send_buf:待发送数据(缓存);


2)recv_buf:存放返回值数据缓存(地址);


3)length:发送/接收数据长度;


4)cs_take:使能片选;


5)cs_release:释放片选。


3. spi总线抽象实现

此部分实现源码为:spi_hw.c spi_hw.h


3.1 spi总线抽象API实现

第一步:“spi_send_then_recv”,实现代码如下:


int spi_send_then_recv(struct spi_dev_device *spi_dev,const void *send_buff,unsigned short send_size,void *recv_buff,unsigned short recv_size)
{
struct spi_dev_message message;

message.length     = send_size;
message.send_buf   = send_buff;
message.recv_buf   = 0;
message.cs_take    = 1;
message.cs_release = 0;
spi_dev->spi_bus->spi_bus_xfer(spi_dev,
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

为增进大家对电脑硬件的认识,本文将介绍如何维护电脑硬件。

关键字: 硬件 指数 电脑硬件

为增进大家对电脑硬件的认识,本文将对电脑硬件故障的检修方法以及排除步骤予以介绍。

关键字: 硬件 指数 电脑硬件

为增进大家对电脑硬件的认识,本文将对电脑硬件予以介绍。

关键字: 硬件 指数 电脑硬件

近日,国内高端存储品牌——佰维存储正式官宣与TES英雄联盟战队达成深度合作,成为TES官方唯一指定存储品牌。佰维存储与TES战队将携手共同助力中国电竞产业蓬勃发展,为电竞行业注入更多硬核科技元素,让更多的玩家感受专业电竞...

关键字: 硬件 存储

2023年10月18日,中国在第三届“一带一路”国际合作高峰论坛期间发布《全球人工智能治理倡议》,围绕人工智能发展、安全、治理三方面系统阐述了人工智能治理中国方案。

关键字: 人工智能 大模型 代码

全新的卡片式设计:整个控制中心以卡片形式展现第三方连接状态,对应设备的相关功能以及其它硬件的终端设置,可在控制中心中进行统一管理。

关键字: 硬件 设备 终端

华为开发者大会是华为公司举办的年度盛会,旨在汇聚全球的开发者、合作伙伴和业界专家,共同探讨和分享最新的技术趋势、开发工具和实践经验。华为开发者大会不仅是华为对外展示技术实力和创新成果的重要平台,也是推动全球开发者生态发展...

关键字: 开发工具 华为 硬件

鸿蒙系统开发者需要学习哪些编程语言以及有哪些推荐,是一个复杂而多元的问题。鸿蒙系统,作为华为推出的面向物联网时代的操作系统,其开发者需要具备跨平台的开发能力、对硬件和软件的深入理解以及创新思维。

关键字: 鸿蒙系统 华为 硬件

我们看到这么多的安全问题,部分原因在于我们对待安全的方式:安全性通常被认为是事后考虑的问题,是在开发结束时才添加到设备上的东西。然而,复杂的系统,尤其是嵌入式系统,有一个很大的攻击面,这让攻击者有机可乘,能够在“盔甲”上...

关键字: 代码 嵌入式系统 软件漏洞

嵌入式软件测试是针对嵌入式系统中的软件进行验证和验证的过程。嵌入式系统是集成在其他设备或系统中的计算机系统,例如汽车、医疗设备、家电等。为确保嵌入式软件的质量和可靠性,进行适当的测试是至关重要的。嵌入式软件测试是确保嵌入...

关键字: 嵌入式软件 计算机 硬件
关闭
关闭