armsom-W3单板计算机之小白学习笔记(三)

前言 

这次我们使用W3开发板来学习i2c接口 由于笔者是嵌入式小白 下文若有错误和偏差 希望大家指出 不吝赐教。


一,i2c接口是什么?

I²C(Inter-Integrated Circuit)是一种广泛使用的串行通信总线协议,用于在低速外围设备和微控制器之间进行数据传输。它由飞利浦公司在1982年开发,常用于连接集成电路,尤其是在嵌入式系统中。以下是I²C的一些关键特点和工作原理:

1. 基本概念

  • 主设备(Master):控制通信的设备,通常是微控制器或处理器。
  • 从设备(Slave):被主设备控制的设备,可以是传感器、存储设备等。
  • 数据线(SDA - Serial Data Line):用于传输数据的双向线路。
  • 时钟线(SCL - Serial Clock Line):由主设备生成的时钟信号线,用于同步数据传输。

2. 通信原理

I²C通信基于主从架构,使用两个主要信号线SDA和SCL进行数据传输。通信过程包括以下几个步骤:

  • 起始条件(Start Condition):主设备将SDA线拉低,同时保持SCL线为高电平,表示通信开始。
  • 地址传输(Address Transmission):主设备发送7位或10位从设备地址和一个读/写位,以确定通信方向(读或写)。
  • 应答(Acknowledge):从设备收到地址后,如果存在,拉低SDA线表示应答(ACK)。
  • 数据传输(Data Transmission):数据以字节为单位在SDA线上传输,每传输一个字节后,从设备发送一个应答位。
  • 停止条件(Stop Condition):主设备将SDA线拉高,同时保持SCL线为高电平,表示通信结束。

3. I²C特点

  • 多主多从:I²C总线支持多个主设备和多个从设备,但一次通信中只能有一个主设备。
  • 半双工:数据传输在一个方向进行,即同一时间内只能进行读操作或写操作。
  • 速度:I²C总线的标准速率有100 kbps(标准模式)、400 kbps(快速模式)和3.4 Mbps(高速模式)。
  • 地址:I²C设备有7位和10位两种地址格式,7位地址最多支持128个设备,10位地址支持更多设备。
  • 总结:i2c总线是同步,串行,半双工通信总线,支持多设备连接,允许多主机存在,但是同一时刻只允许一台主机。

二,i2c接口通信概述

1.设备地址

每一个i2c外设都有一个唯一的地址,主机可以通过地址来确定主机要和那个设备通信

2.数据传输

i2c以字节为单位进行数据传输,i2c分为硬件i2c和软件i2c,硬件i2c就是外设实物,通过各种线相连,软件就是写一个程序模拟i2c通信

3.i2c为什么要上拉电阻?

  1. 总线空闲时,必须是高电平
  2. 连接到总线上的设备必须是漏极开路或者集电路开路,从而执行线与功能
Vcc
 |
 R (上拉电阻)
 |
SDA ------+-------+-------+ ... (连接到各个设备的 SDA 引脚)
          |       |
        Device1 Device2 ...

Vcc
 |
 R (上拉电阻)
 |
SCL ------+-------+-------+ ... (连接到各个设备的 SCL 引脚)
          |       |
        Device1 Device2 ...

3.通信时序

SDA从高电平到到低电平时为起始信号,低到高时为终止信号,空闲时为高电平

4.常见的 I²C 外设

4.1传感器(Sensors)

  • 温度传感器(Temperature Sensors):如 DS18B20、TMP102 等,用于测量温度。
  • 压力传感器(Pressure Sensors):如 BMP280、MS5611 等,用于测量气压和高度。
  • 加速度计和陀螺仪(Accelerometers and Gyroscopes):如 MPU6050、ADXL345 等,用于测量加速度和旋转角速度。

4.2存储器(Memory)

  • EEPROM:如 AT24Cxx 系列,用于存储少量数据,断电后数据不会丢失。
  • SRAM:如 23K256,用于存储数据,但断电后数据会丢失。

4.3显示器(Displays)

  • 字符 LCD 显示器(Character LCD Displays):如 PCF8574 驱动的 LCD 显示器,用于显示字符。
  • OLED 显示器(OLED Displays):如 SSD1306 驱动的 OLED 显示器,用于显示图形和文本。

4.4接口扩展器(Interface Expanders)

  • GPIO 扩展器(GPIO Expanders):如 PCF8574、MCP23017,用于扩展微控制器的 GPIO 引脚。
  • ADC 和 DAC(Analog-to-Digital Converters and Digital-to-Analog Converters):如 ADS1115、MCP4725,用于模拟信号和数字信号的转换。

4.5实时时钟(RTC,Real-Time Clocks)

  • RTC 模块:如 DS3231,用于提供精确的时间和日期。

4.6电源管理(Power Management)

  • 电源管理 IC(Power Management ICs):如 BQ27541,用于电池管理和电源监控。

三,i2c子系统框架

这小节是非常重要的,我们用框架学习法来系统的了解i2c的代码编写和使用规则,分三个部分,可以借助下面的框架图来学习。

1.用户空间

2.驱动程序(i2c设备驱动层,i2c核心层,i2c适配器驱动层)

3.硬件层(分为硬件和软件(通过控制GPIO的高低电平来模拟i2c信号)

1.用户层

用户空间就是我们需要编写一些我们使用的测试程序,即业务逻辑代码,我们在i2c的这些规则内可以做些什么 都可以写进程序,按照我们的意愿去编写。那么有多个应用程序要操控同一个硬件设备时是不是要考虑谁先谁后的问题?这个解决办法是每一个应用程序在使用驱动响应到核心层时,核心层自己会处理先后问题,不需要用户层去处理,也就是我们说的核心层是一个“大管家”。

这一层 我们要学习如何在应用程序中使用i2c进行编程。

2.驱动层

2.1设备驱动层

第一个作用:编写设备树的i2c通信的驱动程序,让它可以工作起来,即驱使设备工作。编写具体的硬件的i2c驱动程序。每一个不同的硬件都需要单独为它编写使用程序 。

第二个作用:创建设备节点,因为上一层是用户层的一些应用程序,应用程序如果想操控外设,就需要通过设备节点,若应用程序对设备节点进行读和写的操作,那么就可以对我们的外设进行读和写,所以在i2c的驱动层中需要我们创建设备节点。

这一层需要我们学习编写i2c的驱动,且平台总线被分成了两个部分,device部分(放的都是和硬件相关的代码,描述这个硬件用的资源有哪些,比如这个外设的地址是多少,这个外设的引脚是哪些)和driver部分(放的都是让这个外设工作起来的代码)

2.1.1i2c_client (相当于设备树节点)

比如kernel/arch/arm64/boot/dts/rockchip/rk3588-armsom-w3.dts这个设备树文件 我们需要把设备节点加进去,一个节点可以挂载多个设备。

这部分可以用设备树来替代,我是使用的开发板是W3,官方学习资料是会提供这些设备树的 ,所以我们只需要编写设备节点就可以了,设备树文件包括dts和dtsi,区别就是,dtsi描述的是更通用的节点代码,一般都是像rk3588.dtsi这样的处理器上的各种功能的设备树 。

2.1.2i2c _driver(设备驱动)

我们在前面说了 每一个不同的硬件都需要我们单独写一个驱动程序,但是有些芯片是自带一些通用驱动的,所以就不用编写,直接编译进内核烧到开发板就可以了。比如drivers/misc/eeprom我用的eeprom的驱动就在这个文件里。

2.2.核心层

核心层的作用就是承上启下,把驱动层的数据传递到适配层,同时担任一个”大管家“的作用 ,上面传下来的数据都需要经过核心层来处理。具体流程就是核心层拿到用户层的发送数据 然后传给i2c适配器 去驱动i2c控制器产生相匹配的波形到硬件就可以实现通信。

这一层的代码不需要我们编写,Linux已经帮我们封装好了,

2.3适配器驱动层

适配器驱动层直接和硬件打交道,通信时序相关的代码文件都是在这一层,它的作用是让i2c控制器工作起来(控制器被封装在芯片内),产生i2c通信所需要的波形。不同品牌的芯片的驱动层的代码是不一样的,但是这些不同的代码块都被移植出去了,剩下的是共通的代码,我们使用时就不需要考虑品牌不一样的问题,

这一层的驱动程序也不需要我们来编写,由原厂工程师编写好了。

3.硬件层

硬件层比较简单,我们需要知道我们使用的型号以及使用方法即可

四,i2c波形

写操作:

1.主机发送一个起始信号

2.主机发送一个i2c外设的地址和写操作,等待应答信号

3.从机发送应答信号

4.主机要发送一个寄存器的地址,等待应答信号

5.主机发送应信号

6.主机发送要写入的寄存器的数据,等待应答信号

7.从机发送应答信号

8.主机要发送的终止信号,如果写多个寄存器,重复6,7步骤。

读操作:

1.主机发送一个起始信号

2.主机要发送i2c的外设地址和写操作,等待应答信号

3.从机发送应答信号

4.主机要发送要读取的寄存器地址,等待应答信号

5.从机发送应答信号

6.主机发送起始信号

7.主机发送要读取的i2c外设的地址和操作,等待应答信号

8.从机发送应答信号

9.从机发送数据,也就是读取的寄存器的数据,等待应答或者非应答信号。

10.如果主机不在读取数据,就要发送非应答信号,如果继续读取,就发送应答信号。

五,i2c检查

1.IIC 第三方工具


I2C tool 是一个开源工具,需自行下载进行交叉编译,代码下载地址:
https://www.kernel.org/pub/software/utils/i2c-tools/

或者<git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git>

编译后会生成 i2cdetect,i2cdump,i2cset,i2cget 等工具,可以直接在命令行上调试使用,I2C tool 是开源的,编译与使用参考里面的 README 与帮助说明。

 ArmSoM-W3板子对应的出厂固件已经在系统下集成了这个工具,可以直接使用,比如扫描I2C总线上的RTC设备:

root@linaro-alip:~# i2cdetect -y 6
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
root@linaro-alip:~# 

 扫描到对应的RTC芯片的I2C地址为0X51

 六,测试实验

这个实验通过IIC接口读写eeprom(AT24C08)的数据。 本次实验会以i2c-7做为示例,接其他i2c引脚操作也是一样的 当然,并不是只能用这个eeprom这个模组,这只是做个简单的示例,如果您没有这个模块,可以通过学习操作eeprom的方式操作您想要操作的i2c设备。

1.物理连接

1.1连接eeprom存储器

把eeprom模块存储器按照40pin针脚图中的i2c7针脚连接。

板子eeprom
3.3V(1)VCC
GND(39)GND
SCL(5)SCL
SDA(3)SCA

 1.2连接开发板

连接好之后 需要用12v的电压供电。·

1.2.1串口连接

我们可以选择使用串口连接板子,usb口插到电脑上,连接成功后,会显示一个端口,可以使用这个端口进行通信,传输数据。下面有图,可以照着做就行。 

1.2.2type c连接

type c接口连接,使用win+R 快捷键 ,然后输入cmd 进入命令终端 输入adb shell连接开发板

 2.软件配置

2.1驱动配置

我们在前面讲过 在用户层 我们需要编写应用程序以及驱动层要编写驱动程序和设备树节点

我们使用eeprom存储器的话 可以使用现有的驱动,不用去编写驱动了,eeprom驱动在drivers/misc/eeprom/下面,如果是其他i2c接口芯片在kernel目录下没有驱动,可以去对找对应芯片厂商提供驱动文件,下面是打开eeprom文件夹的驱动文件

2.2设备树节点代码

我们使用的设备树是kernel\arch\arm64\boot\dts\rockchip文件里的rk3588-armsom-w3.dts设备树文件,我们要使用eeprom存储器的话需要编写一个设备树节点

&i2c7 {  // 定义i2c7节点
    pinctrl-names = "default";  // 指定引脚控制器配置的名字
    pinctrl-0 = <&i2c7m3_xfer>;  // 指定默认的引脚控制器配置,用于I2C7的传输
    clock-frequency = <100000>;  // 设置I2C时钟频率为100kHz
    status = "okay";  // 启用此I2C节点

    eeprom@50 {  // 定义位于I2C总线地址0x50的EEPROM设备
        status = "okay";  // 启用此EEPROM设备
        compatible = "at,24c08";  // 定义与此EEPROM设备兼容的设备类型,此处为Atmel AT24C08
        reg = <0x11>;  // 指定EEPROM设备的I2C地址为0x11
    };
};

由于eeprom实验相对简单 所以不用编写测试程序,我们需要把 整个内核重新编译(因为我们添加了新的设备树节点),然后烧录进板子里。

3.烧录

我们要在w3板子里测试eeprom的话 需要把我们编译好的内核烧录进板子里,我们编译好内核之后,系统会自动生成一个boot文件,路径一般是这样的armsom-w3-bsp\rockdev\boot.img

我们只需要勾选boot部分就可以 。 

把boot烧录板子里之后可以 对板子进行操作了!

4.使用mobaxterm终端连接开发板

我这里显示的是COM3 上点之后等待编译完成 就可以进行操作

找一下我们设置的i2c7是否打开,使用i2cdetect -y 7命令。我们发现和我们设备树节点设置的0X11是一样的

 

 那么既然打开了我们就可以使用这个串口进行试验了。

使用find  /  -name "eeprom" 查找eeprom存储器的位置

读数据:使用cat命令

写数据:可以先把数据清空 然后写数据进去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轻谈半窗月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值