分类目录归档:单片机技术

SPI协议及其工作原理浅析

一、概述.

SPI, Serial Perripheral Interface, 串行外围设备接口, 是 Motorola 公司推出的一种同步串行接口技术. SPI 总线在物理上是通过接在外围设备微控制器(PICmicro) 上面的微处理控制单元 (MCU) 上叫作同步串行端口(Synchronous Serial Port) 的模块(Module)来实现的, 它允许 MCU 以全双工的同步串行方式, 与各种外围设备进行高速数据通信.

SPI主要应用在 EEPROM, Flash, 实时时钟(RTC), 数模转换器(ADC), 数字信号处理器(DSP) 以及数字信号解码器之间. 它在芯片中只占用四根管脚 (Pin) 用来控制以及数据传输, 节约了芯片的 pin 数目, 同时为 PCB 在布局上节省了空间. 正是出于这种简单易用的特性, 现在越来越多的芯片上都集成了 SPI技术.

二、 特点

1. 采用主-从模式(Master-Slave) 的控制方式

SPI规定了两个SPI设备之间通信必须由主设备 (Master) 来控制次设备 (Slave). 一个Master 设备可以通过提供Clock以及对Slave设备进行片选(Slave Select)来控制多个Slave设备,SPI协议还规定Slave设备的Clock由Master设备通过SCK管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作.

2. 采用同步方式(Synchronous)传输数据

Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse), 时钟脉冲组成了时钟信号(Clock Signal) , 时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样, 来保证数据在两个设备之间是同步传输的.

3. 数据交换(Data Exchanges)

SPI 设备间的数据传输之所以又被称为数据交换, 是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 "发送者(Transmitter)" 或者 "接收者(Receiver)". 在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据, 相当于该设备有一个 bit 大小的数据被交换了.

一个 Slave 设备要想能够接收到 Master 发过来的控制信号, 必须在此之前能够被 Master 设备进行访问 (Access). 所以, Master 设备必须首先通过 SS/CS pin 对 Slave 设备进行片选, 把想要访问的 Slave 设备选上.

在数据传输的过程中,  每次接收到的数据必须在下一次数据传输之前被采样. 如果之前接收到的数据没有被读取, 那么这些已经接收完成的数据将有可能会被丢弃,  导致 SPI 物理模块最终失效. 因此, 在程序中一般都会在 SPI 传输完数据后, 去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的.

三、 工作机制

 1. 概述

上图只是对 SPI 设备间通信的一个简单的描述, 下面就来解释一下图中所示的几个组件(Module):

SSPBUF, Synchronous Serial Port Buffer, 泛指 SPI 设备里面的内部缓冲区, 一般在物理上是以 FIFO 的形式, 保存传输过程中的临时数据;

SSPSR, Synchronous Serial Port Register, 泛指 SPI 设备里面的移位寄存器(Shift Regitser), 它的作用是根据设置好的数据位宽(bit-width) 把数据移入或者移出 SSPBUF;

Controller, 泛指 SPI 设备里面的控制寄存器, 可以通过配置它们来设置 SPI 总线的传输模式.

通常情况下, 我们只需要对上图所描述的四个管脚(pin) 进行编程即可控制整个 SPI 设备之间的数据通信:

SCK, Serial Clock, 主要的作用是 Master 设备往 Slave 设备传输时钟信号, 控制数据交换的时机以及速率;

SS/CS, Slave Select/Chip Select, 用于 Master 设备片选 Slave 设备, 使被选中的 Slave 设备能够被 Master 设备所访问;

SDO/MOSI, Serial Data Output/Master Out Slave In, 在 Master 上面也被称为 Tx-Channel, 作为数据的出口, 主要用于 SPI 设备发送数据;

SDI/MISO, Serial Data Input/Master In Slave Out, 在 Master 上面也被称为 Rx-Channel, 作为数据的入口, 主要用于SPI 设备接收数据;

SPI 设备在进行通信的过程中, Master 设备和 Slave 设备之间会产生一个数据链路回环(Data Loop), 就像上图所画的那样, 通过 SDO 和 SDI 管脚, SSPSR 控制数据移入移出 SSPBUF, Controller 确定 SPI 总线的通信模式, SCK 传输时钟信号.


2. Timing.

上图通过 Master 设备与 Slave 设备之间交换1 Byte 数据来说明 SPI 协议的工作机制.

首先,  在这里解释一下两个概念:

CPOL: 时钟极性, 表示 SPI 在空闲时, 时钟信号是高电平还是低电平. 若 CPOL 被设为 1, 那么该设备在空闲时 SCK 管脚下的时钟信号为高电平. 当 CPOL 被设为 0 时则正好相反.

CPOL = 0: SCK idle phase is low; 

CPOL = 1: SCK idle phase is high;

CPHA: 时钟相位, 表示 SPI 设备是在 SCK 管脚上的时钟信号变为上升沿时触发数据采样, 还是在时钟信号变为下降沿时触发数据采样. 若 CPHA 被设置为 1, 则 SPI 设备在时钟信号变为下降沿时触发数据采样, 在上升沿时发送数据. 当 CPHA 被设为 0 时也正好相反.

CPHA = 0: Output data at negedge of clock while receiving data at posedge of clock;

CPHA = 1: Output data at posedge of clock while receiving data at negedge of clock;

上图里的 "Mode 1, 1" 说明了本例所使用的 SPI 数据传输模式被设置成 CPOL = 1, CPHA = 1. 这样, 在一个 Clock 周期内, 每个单独的 SPI 设备都能以全双工(Full-Duplex) 的方式, 同时发送和接收 1 bit 数据, 即相当于交换了 1 bit 大小的数据. 如果 SPI 总线的 Channel-Width 被设置成 Byte, 表示 SPI 总线上每次数据传输的最小单位为 Byte, 那么挂载在该 SPI 总线的设备每次数据传输的过程至少需要 8 个 Clock 周期(忽略设备的物理延迟). 因此, SPI 总线的频率越快, Clock 周期越短, 则 SPI 设备间数据交换的速率就越快.

3.SSPSR.

SSPSR 是 SPI 设备内部的移位寄存器(Shift Register). 它的主要作用是根据 SPI 时钟信号状态, 往 SSPBUF 里移入或者移出数据, 每次移动的数据大小由 Bus-Width 以及 Channel-Width 所决定.

Bus-Width 的作用是指定地址总线到 Master 设备之间数据传输的单位.

例如, 我们想要往 Master 设备里面的 SSPBUF 写入 16 Byte 大小的数据: 首先, 给 Master 设备的配置寄存器设置 Bus-Width 为 Byte; 然后往 Master 设备的 Tx-Data 移位寄存器在地址总线的入口写入数据, 每次写入 1 Byte 大小的数据(使用 writeb 函数); 写完 1 Byte 数据之后, Master 设备里面的 Tx-Data 移位寄存器会自动把从地址总线传来的1 Byte 数据移入 SSPBUF 里; 上述动作一共需要重复执行 16 次.

Channel-Width 的作用是指定 Master 设备与 Slave 设备之间数据传输的单位. 与 Bus-Width 相似,  Master 设备内部的移位寄存器会依据 Channel-Width 自动地把数据从 Master-SSPBUF 里通过 Master-SDO 管脚搬运到 Slave 设备里的 Slave-SDI 引脚, Slave-SSPSR 再把每次接收的数据移入 Slave-SSPBUF里.

通常情况下, Bus-Width 总是会大于或等于 Channel-Width, 这样能保证不会出现因 Master 与 Slave 之间数据交换的频率比地址总线与 Master 之间的数据交换频率要快, 导致 SSPBUF 里面存放的数据为无效数据这样的情况.


4. SSPBUF.

我们知道, 在每个时钟周期内, Master 与 Slave 之间交换的数据其实都是 SPI 内部移位寄存器从 SSPBUF 里面拷贝的. 我们可以通过往 SSPBUF 对应的寄存器 (Tx-Data / Rx-Data register) 里读写数据, 间接地操控 SPI 设备内部的 SSPBUF.

例如, 在发送数据之前, 我们应该先往 Master 的 Tx-Data 寄存器写入将要发送出去的数据, 这些数据会被 Master-SSPSR 移位寄存器根据 Bus-Width 自动移入 Master-SSPBUF 里, 然后这些数据又会被 Master-SSPSR 根据 Channel-Width 从 Master-SSPBUF 中移出, 通过 Master-SDO  管脚传给 Slave-SDI 管脚,  Slave-SSPSR 则把从  Slave-SDI 接收到的数据移入 Slave-SSPBUF 里.  与此同时, Slave-SSPBUF 里面的数据根据每次接收数据的大小(Channel-Width), 通过 Slave-SDO 发往 Master-SDI, Master-SSPSR 再把从 Master-SDI 接收的数据移入 Master-SSPBUF.在单次数据传输完成之后, 用户程序可以通过从 Master 设备的 Rx-Data 寄存器读取 Master 设备数据交换得到的数据.

5. Controller.

Master 设备里面的 Controller 主要通过时钟信号(Clock Signal)以及片选信号(Slave Select Signal)来控制 Slave 设备. Slave 设备会一直等待, 直到接收到 Master 设备发过来的片选信号, 然后根据时钟信号来工作.

Master 设备的片选操作必须由程序所实现. 例如: 由程序把 SS/CS 管脚的时钟信号拉低电平, 完成 SPI 设备数据通信的前期工作; 当程序想让 SPI 设备结束数据通信时, 再把 SS/CS 管脚上的时钟信号拉高电平.

转自:http://bbs.chinaunix.net/thread-1916003-1-1.html

UART与USART

1.字面区别:

UART:universal asynchronous receiver and transmitter通用异步收/发器

USART:universal synchronous asynchronous receiver and transmitter通用同步/异步收/发器

从名字上可以看出,USART在UART基础上增加了同步功能,即USART是UART的增强型,事实也确实是这样。但是具体增强到了什么地方呢?其实当我们使用USART在异步通信的时候,它与UART没有什么区别,但是用在同步通信的时候,区别就很明显了:大家都知道同步通信需要时钟来触发数据传输,也就是说USART相对UART的区别之一就是能提供主动时钟。如stm32的USART可以提供时钟支持ISO7816的智能卡接口。

2.信号区别

UART 有RX和TX两个信号线;而USART会多一个CLK时钟线。

UART需要固定的波特率,就是说两位数据的间隔要相等。UART总线是异步串口,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上有两根线,一根用于发送,一根用于接收。 显然,如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。

UART是一个并行输入成为串行输出的芯片,通常集成在主板上,多数是16550AFN芯片。因为计算机内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步传输,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,若是没有FIFO,信息将变得杂乱无章,不可能传送到Modem。

作为接口的一部分,UART还提供以下功能:将由计算机内部传送过来的并行数据转换为输出的串行数据流。将计算机外部来的串行数据转换为字节,供计算机内部使用并行数据的器件使用。在输出的串行数据流中加入奇偶校验位,并对从外部接收的数据流进行奇偶校验。在输出数据流中加入启停标记,并从接收数据流中删除启停标记。处理由键盘或鼠标发出的中断信号(键盘和鼠标也是串行设备)。可以处理计算机与外部串行设备的同步管理问题。

USART收发模块一般分为三大部分:时钟发生器、数据发送器和接收器。控制寄存器为所有的模块共享。时钟发生器由同步逻辑电路(在同步从模式下由外部时钟输入驱动)和波特率发生器组成。发送时钟引脚XCK仅用于同步发送模式下,发送器部分由一个单独的写入缓冲器(发送UDR)、一个串行移位寄存器、校验位发生器和用于处理不同浈结构的控制逻辑电路构成。使用写入缓冲器,实现了连续发送多浈数据无延时的通信。接收器是USART模块最复杂的部分,最主要的是时钟和数据接收单元。数据接收单元用作异步数据的接收。除了接收单元,接收器还包括校验位校验器、控制逻辑、移位寄存器和两级接收缓冲器(接收UDR)。接收器支持与发送器相同的帧结构,同时支持桢错误、数据溢出和校验错误的检测。USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。

以上信息整理自网络。

CMSIS标准简介

Cortex微控制器软件标准(Cortex Microcontroller Software Interface Standard)是ARM和一些编译器厂家以及半导体厂家共同遵循的一套标准,是由ARM提出,专门针对CORTEX-M系列的标准。在该标准的约定下,ARM和芯片厂商会提供一些通用的API接口(API:应用程序编程接口,是一些预先定义的函数,目的是提供程序与开发人员基于某软件或硬件的以访问一组例程的能力)来访问CORTEX内核以及一些专用外设,以减少更换芯片以及开发工具等移植工作所带来的金钱以及时间上的消耗。只要是基于M3的芯片,代码均是可以复用的。

该标准完全可扩展,可确保其适合于所有的CORTEX-M处理器系列微控制器。

CMSIS可以分为以下3个基本功能层:

  • 核内外设访问层 Core Peripheral Access Layer(CPAL)

  • 中间件访问层 Middleware Access Layer(MWAL)

  • 设备访问层 Device Peripheral Access Layer(DPAL)

  • 核内外设访问层 Core Peripheral Access Layer(CPAL)

该层用来定义一些CORTEX-M处理器内部的一些寄存器地址以及功能函数。如对内核寄存器,NVIC,调试子系统的访问。一些对特殊用途寄存器的访问被定义成内联函数或是内嵌汇编的形式。该层的实现由ARM提供。

  • 中间件访问层 Middleware Access Layer(MWAL)

该层一定访问中间件的一些通用API,该层也由ARM负责实现,但芯片厂商需要根据自己的设备进行更新,目前该层仍在开发中,还没有更进一步的消息。

  • 设备访问层 Device Peripheral Access Layer(DPAL)

该层和CPAL层类似,用来定义一些硬件寄存器的地址以及对外设的访问函数。另外芯片厂商还需要对异常向量表进行扩展,以实现对自己设备的中断处理。该层可饮用CPAL层定义的地址和函数,该层由具体芯片厂商提供。

ARM官网信息:

https://www.arm.com/zh/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php

STM32F1和STM32F4 区别

STM32F1和STM32F4 区别   (安富莱整理)
u F1采用Crotex M3内核,F4采用Crotex M4内核。

u  F1最高主频 72MHz, F4最高主频168MHz。

u  F4具有单精度浮点运算单元,F1没有浮点运算单元。

u  F4的具备增强的DSP指令集。F4的执行16位DSP指令的时间只有F1的30%~70%。F4执行32位DSP指令 的时间只有F1的25%~60%。

u  F1内部SRAM最大64K字节, F4内部SRAM有192K字节(112K+64K+16K)。

u  F4有备份域SRAM(通过Vbat供电保持数据),F1没有备份域SRAM。

u  F4从内部SRAM和外部FSMC存储器执行程序的速度比F1快很多。F1的指令总线I-Bus只接到Flash上,从SRAM和FSMC取指令只能通过S-Bus,速度较慢。F4的I-Bus不但连接到Flash上,而且还连接到SRAM和FSMC上,从而加快从SRAM或FSMC取指令的速度。

u  F1最大封装为144脚,可提供112个GPIO;F4最大封装有176脚,可提供140个GPIO。

u  F1的GPIO的内部上下拉电阻配置仅仅针对输入模式有用,输出时无效。而F4的GPIO在设置为输出模式时,上下拉电阻的配置依然有效。即F4可以配置为开漏输出,内部上拉电阻使能,而F1不行。

u  F4的GPIO最高翻转速度为84MHz,F1最大翻转速度只有18MHz。

u  F1最多可提供5个UART串口,F4最多可以提供6个UART串口。

u  F1可提供2个I2C接口,F4可以提供3个I2C接口。

u  F1和F4都具有3个12位的独立ADC,F1可提供21个输入通道,F4可以提供24个输入通道。F1的ADC最大采样频率为1Msps,2路交替采样可到2Msps(F1不支持3路交替采样)。F4的ADC最大采样频率为2.4Msps,3路交替采样可到7.2Msps。

u  F1只有12个DMA通道,F4有16个DMA通道。F4的每个DMA通道有4*32位FIFO,F1没有FIFO。

u  F1的SPI时钟最高速度为 18MHz, F4可以到37.5MHz。

u  F1没有独立的32位定时器(32位需要级联实现),F4的TIM2和TIM5具有32位上下计数功能。

u  F1和F4都有2个I2S接口,但是F1的I2S只支持半双工(同一时刻要么放音,要么录音),而F4的I2S支持全双工,放音和录音可以同时进行。

I2C调试中的错误分析

在调试Linux驱动时,经常会用到I2C总线。通常情况下,都会调用Linux I2C core的数据收发函数,老刘整理了几个常见的错误及应对方式,供大家参考:

1.EOPNOTSUPP错误 — Operation not supported on transport endpoint

  • 由于Linux的错误号一般都是负数,所以在return时,代码返回的是-EOPNOTSUPP,该值的定义为95。

  • 这个错误原因主要是使用了不支持的方法,从软件方面入手即可。

2.EAGAIN错误 — Try again

  • 该值的定义为11,重试错误,这个时候,表明I2C控制器可以操作I2C总线,只不过没有得到器件的响应。

  • 解决这类错误请先从设备连接上入手,看看I2C设备是否连接正常;

  • 确认I2C器件的地址是否正确,需要注意:I2C一般使用的是7bit地址,在有些设备明确写明是7位地址,而有些设备写的不是很清楚,此时可以尝试将设备手册中的地址右移1位,得到7位器件地址;对于10bit的器件,发送时需设置I2C_M_TEN参数,但这类设备似乎很少见。

3.ETIMEDOUT错误 — Connection timed out

  • 该值的定义为110。

  • 这类错误一般是由于I2C总线错误引起的,I2C控制器无法正常操作总线,一般要先检查是否有什么原因导致I2C是否被意外拉低,外设挂的很多时,还需要考虑I2C的驱动能力是否足够,上拉电阻是否到位等因素。

OTG线与普通USB线的区别

近日,老刘又犯了一个“经验主义”错误。调试一个开发板,要通过USB下载代码,说明书明确写的是需要一根OTG数据线。老刘清楚记得,OTG线和普通的USB线是不一样的,记得2010年的时候,用到OTG数据线,还是专门存市场上买了的,不能用普通的USB线,OTG线的一根ID需要跟地线相连,这样USB控制器才能进行检查,切换到Host模式。

从图中可以看出:

普通USB为5根线,但ID脚悬空不接:

 1. VBUS (5v)

 2. D-

 3. D+

 4. ID 悬空

 5. GND

OTG线也是5跟根线,但ID脚与GND连接:

 1. VBUS

 2. D-D

 3. D+

 4. ID 接 GND

 5. GND

    我又查阅了USB的文档,也会分A,B线的,凭借着经验,老刘当然只能去买了,后来经硬件朋友指点,才恍然大悟,告诉我现在的micro usb线就是OTG线???老刘有点晕菜

     那老刘的疑问来了,现在很多手机出来的USB接口接的控制器都是USB OTG控制器

1.一般的模式下,手机都只是做Device模式,那如果接了这种OTG线之后,手机的USB控制器应该会检测到ID线,那么应该切换成Host模式;然而电脑的USB只能做Host模式,这样以来,两个USB Host接到了一起,手机又能自动切换成Device模式了吗??

2.手机如果支持OTG,则可以用一种OTG线–一端为micro usb接口,另一端为母头的USB,可以直接接到U盘。这时候,OTG线接到手机之后,手机的USB切换到Host模式,U盘为Device,这是可以解释的通的。

3.老刘又做了另一个实验,用一个2中的OTG线,再配上一个双公的USB线(已确认4条线全部链接),这个时候模拟出来的,应该就是一个可以确保micro usb侧一定是接了ID线的OTG了。连接电脑,电脑无法识别板子了。(两个Host当然不能接到一起了)

这样,老刘猜测,所谓的USB OTG烧写线不是什么OTG线,烧写板子的时候,板子就应该是Device设备,不应该是作为Host控制电脑的吧,即真正的烧写线,就是普通的USB线,而不是什么OTG线。老刘目前真的只是猜测,因为老刘的万用表坏了,测试条件有限,希望哪个热心的硬件朋友能够予以解答!老刘在此表示感谢!!

中文输入法实现

这是06年老刘在UDTech时写的一个中文输入法的实现说明书,用在了IP可视电话项目上,UI是用MiniGUI写的,现在看来,当时的设计还是不错的。10年了,已经找不到当初UD的影子,昔日的同事,常联系的也没有几个了,现在发出来,应该涉及不到版权的问题。在UD的那段时光还是让我进步很大,所以文中依旧保留了当年UD的Logo,算是一个怀念吧。

这个设计思想,在如今智能机漫天飞舞的时代,应该已经用不上了,但对于坚守8位单片机的朋友或许是个启发吧。


中文输入法实现说明书.pdf

零欧电阻的作用

老刘今天看到一篇关于0欧电阻的说明总结,原来调试电路的时候经常会用到,但还真没认真总结过,转来分享给大家。

0欧的电阻在电路中有以下几个功能;

  1. 做为跳线使用。美观,安装方便;

  2. 在数字和模拟等混合电路中,往往要求两个地分开,并且单点连接。可以用一个0欧的电阻来连接这两个地,而不是直接连在一起。这样做的好处就是,地线被分成了两个网络,在大面积铺铜等处理时,就会方便得多。在这样的场合,有时也会用电感或者磁珠来连接;

  3. 做保险丝用。由于PCB上走线的熔断电流较大,如果发生短路过流等故障时,很难熔断,可能会带来更大的事故。由于0欧电阻电流承受能力比较弱(0欧电阻也有一定的电阻的,只是很小),过流时就先将0欧电阻熔断了,从而将电路断开,防止了更大事故的发生。有时也会用一些阻值为零点几或者几欧的小电阻来做保险丝。不过一般情况下,不推荐这样来用;

  4. 为调试预留的位置。可以根据需要,决定是否安装,或换用其它阻值。可用*来标注,表示由调试时决定;

  5. 作为配置电路使用。这个作用和跳线或者拨码开关类似,但是通过焊接固定上去的,这样就避免了普通用户随意修改配置。通过安装不同位置的电阻,可以更改电路的功能或设置地址等。

0欧电阻具有不同的规格,一般是按功率来分,有1/8瓦,1/4瓦等。

转载自:http://blog.sina.com.cn/s/blog_5f2b5ce90100cmb6.html

I2C总线

I2C总线无论是在嵌入式开发领域,应该是最常用的总线协议之一。老刘接触I2C应该是在2003年,做的是一个时钟芯片的驱动,当时使用的CPU也没有I2C控制器,采用的是GPIO模式的方式写的代码,对那次调试体会很深,按照I2C时序,输出正确的波形,配置/读取I2C器件的数据。

关于I2C协议,网上资料一抓一大吧,老刘也不打算整理太多,只是想根据以往的项目经验,给大家分享以下几点:

  • 如果使用GPIO模拟,最好不要让两个CPU可以操作同一个器件,因为那样会涉及到总线仲裁;

  • 如果使用GPIO模拟,最好接上拉电阻,使SDA和SCL线在空闲状态为高电平状态;

  • 现在由于低功耗的要求,现在很多CPU的电压的IO引脚输出电平会有所区别,有1.2V、1.5V、1.8V,这时需要与I2C器件的电平进行匹配,虽然现在一般的器件都可以认为要求的电压*0.7即可认为是高电平,但出于临界值得状态容易受到信号干扰,造成数据不可靠。如果电平不匹配,那就让硬件工程师接个电平转换器件吧,还能增强IO口的驱动能力呢;

  • 如果一条总线上接多个I2C器件,就要注意器件的地址不要出现重复,尤其是会使用多个相同器件的情况下更需注意;

  • 在2.6以后的Linux开发中,一般都是采用Attach的模式,先将I2C器件挂到platform总线上,而老版本的Linux内核采用的是Detach模式,Linux会自动检测所挂接的I2C器件,只有器件有回应之后才能正常操作。老刘吃过亏,因为当年还是用老思想调试电容触摸屏驱动,而其工作原理是只有被按下之后才会产生中断,允许I2C控制器的操作,它不接受I2C控制器的探测行为。

老刘在这里给大家找了份最基本的文档,来源于百度文库,文章的作者未知,老刘感谢其无私奉献精神,对于初学者应该会有一个帮助。


I2C总线接口详解.pdf

另外,在老刘做在玩Intel服务器CPU的时候,还用过一个SMBus总线,也是一个两线协议,与I2C协议有些区别和联系,老刘有时间再帮大家进行资料收集。