nRF52832之硬件I2C

这几天一直在折腾nRF52832的硬件I2C,到了今天最终出现了成果,在此也印证了那句话:“耕耘就有收获”

52832的硬件I2C尽管官方提供了demo,可是自己对I2C通信理解的不够深入,再一个52832的代码也封装的太深了。可是对接口函数没有一个明白的解释(也能够说是我英文太渣,别人写了可是我没看懂。

。),这样对于首次接触nRF产品的人就造成了一定的难度

依据我的开发过程,还是先说明一下I2C的一些相关知识,由于我是先调硬件I2C搞了半天不正确头,然后再开发模拟I2C,模拟的成功了再来调试的硬件TWI(也就是52832的硬件I2C,全称预计是two wire interface)

I2C通信须要两条线:SDA,SCL。

I2C通信设备有两种角色:master和slave。一般用户开发程序都是开发master端,然后去读写作为slave的外设,比方:eeprom,flash,sensor,display device。

在通信过程中,有两组特殊控制信号:

start :scl为高电平时,sda由高电平变为低电平。

stop: scl为高电平时,sda由低电平变为高电平。

(注意在通信过程中。SCL始终由master控制。这句话在做模拟I2C的时候就显得意义非凡了)

master做写数据操作时。先是SCL和SDA都处于空暇状态(两者都是高电平),然后SDA由高变低(start信号);变低后SCL拉低,这个时候SDA就能够变成想要的电平。高电平代表bit为1,低电平代表bit为0。电平稳定后拉高时钟(拉高的目的是为了让slave读取数据,SCL为高时,SDA要保持不变。slave读取SDA的电平)。传输数据完了后要结束:先拉高SCL。然后拉高SDA。然后拉低SDA,一个完整的stop信号完毕了。

读数据操作时,start和stop这些时序一样,可是主机要去解析slave传来的数据(电平信号), 拉低SCL,然后释放SDA(即拉高SDA),一段延时之后拉高SCL再去读取SDA电平信号(既然是读取电平。这里必要设置为输入引脚啦),假设是高电平则记下是一个H_bit,否则是L_bit,读取到8位数据后假设还要继续读取则回复ACK,否则回复NCK。

ACK信号是SCL拉低后给SDA一个低电平,然后拉高SCL;

ANK信号是SCL拉低和给SDA一个高电平。然后拉高SCL。

以下以解说下master 和 slave传输时整体操作:

master向slave写数据,一般slave端写数据都要一个确定的寄存器地址。即你要往这个外设的哪个位置传数据

以eeprom为例,先发送器件地址0xAE(8位数据。高7位是地址。LSB是传输数据方向:0;0代表写。1代表读,能够当做out。in来理解这样easy记住)。

然后发送寄存器地址,然后发送数据。

时序上面能够是

start–slave_address_write–register_address–N*Send_data–stop

Send_data每发一个字节,slave会回应一个“CK信号”。假设是ACK则发送数据成功了。否则失败

由于是连续的写数据,因此中间能够没有stop,start

读数据操作。要先写进一个寄存器地址,再传递一个读命令

start–slave_address_write–register_address–start–slave_address_Read–N*Receive_data–stop

发送slave_address_Read前要先re_start,跟start信号一样

Receive_data 是接收数据,这时要去识别SDA电平而且解析数据,作出ACK回应。最后一个字节接收完毕回复NCK信号;然后stop。

以下说明nRF52832的硬件I2C代码问题

nRF留出的API接口是

ret_code_t app_twi_perform(app_twi_t *  \              p_app_twi,app_twi_transfer_t const * p_transfers,uint8_t         number_of_transfers,void (* user_function)(void))

这个函数调用了app_twi_schedule函数,以此来导入到队列

ret_code_t app_twi_schedule(app_twi_t *                   p_app_twi,
                            app_twi_transaction_t const * p_transaction)

想要调用app_twi_perform函数那么得准备好參数

1、p_app_twi。这是在TWI传输队列里申请一个位置

英文原话是creating an instance of the TWI transaction manager.

2、p_transfers,这是包括了要传输的数组块的一个数组

3、number_of_transfers,这个是你传输数据块的个数

4、user_function,一个用户的回调函数的函数指针,数据块传输完了API内部会调用这个user_function

解释:上面说的数据块的意思就是一个完整的I2C操作须要用到的信息:包括了slave地址。数据传递方向(读或者写),传输的数据data_buffer,数据长度length,有无结束标志(意思就是这团传输数据完了后是否结束通信了)

在官方SDK里面文件夹

examples\peripheral\twi_master_using_app_twi里打开project

首先初始化TWI

传输数据

传输的内容

注意AT24C02_init_transfers是一个全局变量数组

也就是它的地址是在堆里面的,不会自己主动释放。这么做的原因是这个数组的地址可能会被多次调用,而放在某个函数里面会造成地址不同造成错误

demo里面有解释

  // [these structures have to be "static" - they cannot be placed on stack
    //  since the transaction is scheduled and these structures most likely
    //  will be referred after this function returns]
      static app_twi_transfer_t const transfers[] =
    {
         AT24C02_READ(&AT24C02_first_page_addr,AT_buffer,5)

    };

注意这里的AT_WRITE_NUMBER数组能够理解为一个数据缓冲区,能够通过改变这个数组的内容然后调用app_twi_perform来发数据出去(把const去掉)

读数据相似,demo用的自己定义传输函数

仿写一个

没想到这篇博客会有这么多人看。写的挺乱的。可是也不想再做改动了~~~写博客真的耗费时间啊~

建议大家去看twi_sensor这个project

路径:NORDIC官方SDK\nRF52_SDK_11.0.0\examples\peripheral\twi_sensor

时间: 2024-08-05 00:44:14

nRF52832之硬件I2C的相关文章

STM32F10x_模拟I2C读写_硬件I2C读写

STM32F10x_模拟I2C读写EEPROM STM32F10x_硬件I2C读写EEPROM(标准外设库版本) STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

MSP430G2553 Launchpad 硬件I2C驱动

一.USCI I2C 驱动介绍 对于MSP430G2553,硬件I2C由外设USCI(Universal Serial Communication Interface)提供.USCI又分为USCI_A和USCI_B,其中USCI_A支持UART/IrDA/LIN/SPI通讯,USCI_B支持I2C/SPI通讯.MSP430G2553带有一个USCI_A和一个USCI_B,硬件I2C对应的管脚为P1.6(UCB0SCL)和P1.7(UCB0SDA). 由于Launchpad上P1.6连接到了LED

关于MSP硬件I2C讲解

0.前言 对于大多数单片机来说,I2C成了一个老大难问题.从51时代开始,软件模拟I2C成了主流,甚至到ARMCortex M3大行其道的今天,软件模拟I2C依然是使用最广的方法.虽然软件模拟可以解决所有的问题,但是总感觉没有充分发挥MCU内部的硬件资源.查阅了所有关于MSP430F5系列的图书,没有关于硬件I2C的应用代码,自己通过调试摸索,把经验总结之后和大家分享,希望大家喜欢.同时,I2C的使用可以分为等待法和中断法,从理解的角度来说等待法思路清晰易于上手,从功耗的角度出发,中断法可以灵活

EFM32 硬件I2C操作

有关的例程,请参考如下: #include "efm32.h" #include "em_chip.h" #include "em_cmu.h" #include "em_emu.h" #include "em_gpio.h" #include "em_i2c.h" #include "I2C_hw.h" unsigned long i2c_error = 0; vo

STM32F10x_硬件I2C主从通信(轮询发送,中断接收)

Ⅰ.写在前面 关注我分享文章的朋友应该知道我在前面讲述过(软件.硬件)I2C主机控制从机EEPROM的例子.在I2C通信主机控制程序是比较常见的一种,可以说在实际项目中,很多应用都会使用到I2C通信.但在实际项目中作为I2C从机的应用相对要少的多,本文主要讲述关于[STM32F10x_硬件I2C主从通信]中STM32作为从机的例子. 在学习本问内容之前,如果对I2C协议还不太了解的朋友请先去了解一下I2C协议,或看我之前关于I2C通信的文章(我微信公众号和博客都有). 关于STM32硬件I2C作

STM32 硬件I2C 到底是不是个坑?

/** ****************************************************************************** * @author    Maoxiao Hu * @version   V1.0.0 * @date       May-2015 ****************************************************************************** * < COPYRIGHT 2015 IS

I2C硬件与模拟的区别

硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C:一般也较为稳定,但是程序较为繁琐. 硬件(固件)I2C是直接调用内部寄存器进行配置:而软件I2C是没有寄存器这个概念的. 软件I2C一般是使用GPIO管脚,用软件控制SCL,SDA线输出高低电平,模拟i2c协议的时序. 主要对比: 1.硬件IIC用法比较复杂,模拟IIC的流程更清楚一些. 2.硬件IIC速度比模拟快,并且可以用DMA 3.模拟IIC可以在任何管脚上,而硬件只能

STM32F4XX高效驱动篇2 I2C

说到I2C很多用过STMF10X硬件I2C方式的工程师,都感觉有点头痛.大部分还是使用软件模拟的方式,I2C由于一般的工作频率是400,100KHz.所以在平凡读取,或所读数据量大时,使用这模拟的方式,还是比较浪费CPU有效工作时间的. 在之前的使用I2C的经历中,主要是I2C死锁问题让我也困扰了一段时间.不过后来经过多方资料,最后还是把这个问题解决了.以下驱动程序已集成了此功能. 什么是死锁,在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为

[I2C]pca9555应用层测试代码

驱动方面: 首先配置I2C内核驱动,将pca9555的源码built-in进入(这里根据需要可能要配thermal的驱动),然后在devicetree中根据pca9555硬件I2C地址配置节点. 测试源码: // I2C test program for a PCA9555 #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <l