硬件平台:微雪nRF51822开发板

软件平台:MDK522

SDK版本:SDK5

nRF51822的任意管脚可以配置成SPI的管脚,其官方给的代码有一个SPI_master,里面只有两个函数:spi_master_init 和 spi_master_tx_rx,前面一个是初始化函数,后面一个是双向传输函数。

1. nRF51822 SPI的使用

在spi_master_config.h 文件里面配置管脚信息

// SPI0.
#define SPI_PSELSCK0            25u                                     /**< SPI clock GPIO pin number. */
#define SPI_PSELMOSI0           24u                                     /**< SPI Master Out Slave In GPIO pin number. */
#define SPI_PSELMISO0           23u                                     /**< SPI Master In Slave Out GPIO pin number. */
#define SPI_PSELSS0             30u                                                 /**< SPI Slave Select GPIO pin number. */// SPI1.
#define SPI_PSELSCK1            19u                                     /**< SPI clock GPIO pin number. */
#define SPI_PSELMOSI1           20u                                     /**< SPI Master Out Slave In GPIO pin number. */
#define SPI_PSELMISO1           22u                                     /**< SPI Master In Slave Out GPIO pin number. */
#define SPI_PSELSS1             21u                                     /**< SPI Slave Select GPIO pin number. */

此处的SPI0为我们需要使用的,与ADXL8632进行连接

初始化函数

spi_base_address = spi_master_init(SPI0,SPI_MODE0,false);   //选择SPI0,mode0,lsb false

传输函数:选择为SPI0,传输的size,然后是两个数据线的buff

bool spi_master_tx_rx(uint32_t *spi_base_address, uint16_t transfer_size, const uint8_t *tx_data, uint8_t *rx_data)

2. adxl362的驱动编写

在官网(http://www.analog.com/cn/products/mems/accelerometers/adxl362.html#product-documentation)上有驱动的上层代码,主要是初始化和寄存器的一些操作。需要我们自己编写底层的SPI的操作,而且driver里面SPI是有write和read函数的,我们需要使用spi_master_tx_rx这个函数来完成操作。

2.1 读一个寄存器的数据

首先需要读取ID值,我们改进的函数为:

bool ADXL362_ReadOneReg(u8_t Reg, u8_t* Data)
{/* Write transaction */uint8_t transfer_size = 3;               //先是read命令,然后是寄存器地址,最后是数据SPIMasterBuffer[0] = ADXL362_READ_REG;   //read命令  SPIMasterBuffer[1] = Reg;                 //寄存器地址spi_master_tx_rx((uint32_t *)NRF_SPI0,transfer_size,SPIMasterBuffer,SPISlaveBuffer);    //进行数据双向传输/* Send received value back to the caller */*Data = SPISlaveBuffer[2];               //在MISO线上第三个数据则是ID数据return true;
}

2.2 写一个寄存器的数据

bool ADXL362_WriteOneReg(u8_t WriteAddr, u8_t Data)
{SPIWriteLength = 3;    //write命令+寄存器地址+写入的数据SPIReadLength = 0;SPIMasterBuffer[0] = ADXL362_WRITE_REG;SPIMasterBuffer[1] = WriteAddr;SPIMasterBuffer[2] = (Data);/* Check if we got an ACK or TIMEOUT error */spi_master_tx_rx((uint32_t *)NRF_SPI0,SPIWriteLength,SPIMasterBuffer,SPISlaveBuffer);return true;
}

2.3 改进官方的读取多个寄存器的函数

void ADXL362_GetRegisterValue(unsigned char* pReadData,unsigned char  registerAddress,unsigned char  bytesNumber)
{unsigned char M_buffer[32];     //MOSI的数据unsigned char S_buffer[32];     //MISO的数据unsigned char index = 0;/* Write transaction */uint8_t transfer_size = bytesNumber + 2;    //读取多个数据,再加上读取命令和开始地址M_buffer[0] = ADXL362_READ_REG;             //读取命令M_buffer[1] = registerAddress;              //开始地址spi_master_tx_rx((uint32_t *)NRF_SPI0,transfer_size,M_buffer,S_buffer);  //传输了读取命令,然后开始读取/* Send received value back to the caller */for(index = 0; index < bytesNumber; index++){pReadData[index] = S_buffer[index + 2];    //除去前面两个之后,后面的都是MISO上读取到的寄存器数据}}

2.4 改进官方的写两个寄存器的函数

void ADXL362_SetRegisterValue(unsigned short registerValue,unsigned char  registerAddress,unsigned char  bytesNumber)
{SPIWriteLength = bytesNumber+2;SPIReadLength = 0;SPIMasterBuffer[0] = ADXL362_WRITE_REG;SPIMasterBuffer[1] = registerAddress;SPIMasterBuffer[2] = (registerValue & 0x00FF);     //we can get the last 8 bitSPIMasterBuffer[3] = (registerValue >> 8);           //we can get the first 8 bit/* Check if we got an ACK or TIMEOUT error */spi_master_tx_rx((uint32_t *)NRF_SPI0,SPIWriteLength,SPIMasterBuffer,SPISlaveBuffer);
}

至此,底层的接口基本上适配完毕了,这样的话其他的函数可以直接基于这些函数来调用了。

2.5 初始化函数

bool ADXL362_Init(void)
{unsigned char regValue = 0;spi_base_address = spi_master_init(SPI0,SPI_MODE0,false);if (spi_base_address == 0) {printf("the spi is not  ok\r\n");}spi_master_enable(SPI0);ADXL362_GetRegisterValue(&regValue, ADXL362_REG_PARTID, 1);if((regValue == ADXL362_PART_ID)){
//          printf("the acc is on, and the geten id is %d\r\n",regValue);ADXL362_WriteOneReg(ADXL362_REG_FILTER_CTL, 0x10);ADXL362_WriteOneReg(ADXL362_REG_INTMAP2, 0x01);ADXL362_WriteOneReg(ADXL362_REG_POWER_CTL, 0x02);return true;}else{return false;}
}

初始化之后可以在寄存器里面拿到数据了。

3. debug的状态

SPI出了问题,使用示波器发现SPI的时钟产生一两个之后就停了,完整的时钟信号都没有。

在确定各种初始化都没问题之后,发现产生的时钟的频率也不对,在调低了时钟速率之后,这个问题得到了解决,从1M变成125K之后变好了,再调上1M也是好的,所以最终是啥问题不可得知,但是如果遇到时钟信号都没有的情况,先把速率调至最低试试。

nRF51822 SPI 驱动 ADXL362相关推荐

  1. Linux驱动修炼之道-SPI驱动框架源码分析(上)

    Linux驱动修炼之道-SPI驱动框架源码分析(上)   SPI协议是一种同步的串行数据连接标准,由摩托罗拉公司命名,可工作于全双工模式.相关通讯设备可工作于m/s模式.主设备发起数据帧,允许多个从设 ...

  2. NanoPi NEO Air使用十一:编写SPI驱动点亮TFT屏幕,ST7789V

    NanoPi NEO Air使用一:介绍 NanoPi NEO Air使用二:固件烧录 NanoPi NEO Air使用三:OverlayFS.CPU温度和频率.wifi.蓝牙.npi-config ...

  3. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】PowerPC + Linux2.6.25平台下的SPI驱动架构分析

    PowerPC + Linux2.6.25平台下的SPI驱动架构分析 Sailor_forever  sailing_9806#163.com (本原创文章发表于Sailor_forever 的个人b ...

  4. 转载:Linux kernel SPI驱动解释

    From: http://www.cnblogs.com/liugf05/archive/2012/12/03/2800457.html 下面有两个大的模块: 一个是SPI总线驱动的分析        ...

  5. PX4原生固件SPI驱动动编写与IMU传感器替换

    适用于PX4原生固件 核心目标:完成XSENS的MTI3,IMU替换.MTI3是一款航姿参考系统,可以独立的输出四元数,加速度,磁力计等,角速度等航姿信息.里面有完整的卡尔曼滤波,可以替换飞控本身里面 ...

  6. S3C2440 SPI驱动框架

    S3C2440 SPI驱动代码详细解读: https://www.linuxidc.com/Linux/2012-08/68402p4.htm 一.platform device and board_ ...

  7. MSP430F5529 DriverLib 库函数学习笔记(十)SPI驱动墨水屏

    目录 上机实战 SPI 驱动 墨水屏 墨水屏介绍 电子纸的分类 电泳型电子纸技术详解 原理 结构 优势与不足 实验电路介绍 程序分析 引脚初始化 SPI模块初始化 发送和接收 全部源代码 main.c ...

  8. OpenWrt 之 MT7628 移植第三方SPI驱动

    1.在OpenWrt系统上移植SPI驱动前,首先要确保SPI相关引脚未被复用为其他功能,比如GPIO:以下操作已假定该条件成立,否则请修改相关dts和c文件中复用配置: 2.打开dts配置文件进行修改 ...

  9. V210 SPI驱动分析

    对于总线设备驱动,是需要分别创建设备和驱动两个结构体,然后根据name,互相匹配,匹配成功后,调用 驱动的probe函数,然后创建设备文件,实现驱动的业务逻辑. 因此,我们就以设备和驱动的注册,以及匹 ...

  10. linux spi不使用框架,Linux spi驱动框架之执行流程

    Linux spi驱动架构由三部分构成:SPI核心层.SPI控制器驱动层.和SPI设备驱动程序. 1.SPI核心层: SPI核心层是Linux的SPI核心部分,提供了核心数据结构的定义.SPI控制器驱 ...

最新文章

  1. spring mvc xml格式输入输出
  2. Cacti auth.php,Cacti微信企业号图文报警
  3. 怎么查询局域网内全部电脑IP和mac地址..
  4. IGMP协议——IP组播之组管理协议
  5. JavaWeb——新建项目与新建servlet
  6. 【C语言】指向一维数组元素的指针
  7. mysql常用数据操作之增、删、改
  8. 黑苹果(1)为什么是黑苹果PPT?
  9. 完成基于ICX285和ICX205两种CCD的兼容性电路设计
  10. Vue.js尚硅谷视频学习笔记(第一章:Vue 核心)
  11. 微信小程序集成融云 SDK (即时通讯) 集成必备条件
  12. 微信小程序wx.setClipboardData复制文本
  13. 基于C++实现考试报名系统
  14. NLP入门干货:手把手教你3种中文规则分词方法
  15. WIN10系统ThinkPad S5 3D摄像头终极解决方案(实感深度摄像头)
  16. 字节跳动全链路压测(Rhino)的实践
  17. SpringBoot 集成FluentMyBatis 框架之集成分页功能
  18. 新浪微博分布式爬虫分享
  19. u深度做linux启动盘,u深度u盘启动盘制作教程
  20. 罗技鼠标正在连接服务器失败,说好的真爱,怎么就翻车了!失败的罗技M720入手记...

热门文章

  1. Ubuntu18.04下的模拟神器RetroArch
  2. 完整版通达OA2015-2017版本1day漏洞利用
  3. 傅里叶分析斯坦恩中文版pdf_傅里叶分析
  4. 怎么使用java初始化链表_Java链表基本操作和Java.util.ArrayList
  5. 安装linux取消硬盘密码设置,Linux Deepin安装到硬盘图文过程
  6. 【测试能力提升】Jira 和禅道数据库分析,方便你写周报、写总结、出报告
  7. java 中facade_Java设计模式之Facade模式
  8. 呼叫中心系统建设方案
  9. 你熟悉的新华书店,已经变样了 | 数字化案例
  10. matlab 二元函数 定义,实验五用matlab求二元函数及极值.doc