文章依据:TI官网《TMS320F2837xD Dual-Core Delfino Microcontrollers Technical Reference Manual》
一、DSP28377上的I2C模块功能简介
I2C模块支持任何与I2C兼容的从设备或主设备。图20-1显示了多个I2C模块的示例,这些模块用于从一个设备到其他设备的双向传输。
I2C总线设备没有像普通逻辑设备中那样的芯片选择引脚,取而代之的是分配给每个设备的从机地址。连接到I2C总线的每个设备都由一个唯一的地址来识别。
根据设备的功能,每个设备可以作为发射器或接收器工作。当执行数据传输时,连接到I2C总线的设备也可以被视为主设备或从设备。主设备是在总线上发起数据传输并生成时钟信号以允许该传输的设备。
在此传输过程中,此主设备寻址的任何设备都被视为从设备。I2C模块支持多主模式,其中一个或多个能够控制I2C总线的设备可以连接到同一I2C总线。
对于数据通信,I2C模块有一个串行数据引脚(SDA)和一个串行时钟引脚(SCL),如寄存器部分所示。这两个引脚在28x设备和连接到I2C总线的其他设备之间传送信息。SDA和SCL引脚都是双向的。它们必须使用上拉电阻器连接到正电源电压。当总线空闲时,两个引脚都很高。
这两个引脚的驱动器具有开漏配置,以执行所需的有线和有线功能。
有两种主要的传输技术:
- 标准模式:精确发送n个数据值,其中n是您在I2C模块寄存器中编程的值。有关更多信息,请参阅注册部分。
- 重复模式:一直发送数据值,直到使用软件启动停止条件或新的启动条件。有关RM位信息,请参阅寄存器。
28377内I2C模块具有以下功能:
- 符合飞利浦半导体I2C总线规范(2.1版):
–支持8位格式传输
–7位和10位寻址模式
–普通呼叫
–启动字节模式
–支持多个主发射机和从接收机
–支持多个从属发射机和主接收机
–组合主发送/接收和接收/发送模式
–数据传输速率从10 kbps到400 kbps(飞利浦快速模式速率)
- 一个16字节接收FIFO和一个16字节发送FIFO
- CPU始终可以使用的一个中断。此中断可由以下条件之一产生:传输数据就绪、接收数据就绪、寄存器访问就绪、未收到确认、仲裁丢失、检测到停止条件、寻址为从机。
- CPU在FIFO模式下可使用的额外中断
- 模块启用/禁用功能
- 自由数据格式模式
I2C模块不支持:
- 高速模式(Hs模式)
- CBUS兼容模式
I2C模块由以下主要模块组成:
- 串行接口:一个数据引脚(SDA)和一个时钟引脚(SCL)
- 数据寄存器和FIFO,用于临时保存SDA引脚和CPU之间的接收数据和传输数据
- 控制和状态寄存器
- 外围总线接口,使CPU能够访问I2C模块寄存器和FIFO。
- 时钟同步器,用于同步I2C输入时钟(来自设备时钟发生器)和时钟
- SCL引脚上,与不同时钟速度的主机同步数据传输
- 一个预分频器,用于划分驱动至I2C模块的输入时钟
- SDA和SCL两个引脚上各有一个噪声滤波器
- 一个仲裁器,用于处理I2C模块(当它是主模块时)和另一个主模块之间的仲裁
- 中断生成逻辑,以便中断可以发送到CPU
- FIFO中断生成逻辑,以便FIFO访问可以与I2C模块中的数据接收和数据传输同步
图20-2显示了非FIFO模式下用于传输和接收的四个寄存器。CPU将要传输的数据写入I2CDXR,并从I2CDRR读取接收到的数据。当I2C模块配置为发射器时,写入I2CDXR的数据被复制到I2CXSR,并在SDA引脚上一次移出一位。当I2C模块配置为接收器时,接收的数据被转移到I2CRSR,然后复制到I2CDRR。
二、I2C初始化配置
1. 时钟配置
I2C输入时钟相当于CPU时钟,然后在I2C模块内再分两次以产生模块时钟和主站总线时钟。模块时钟决定I2C模块工作的频率。I2C模块中的可编程预分频器将I2C输入时钟向下分频以产生模块时钟。当I2C模块是一个主站时,模块时钟被分频,用作SCL引脚上的主时钟。主时钟控制I2C模块和从站之间的通信时序。如图20-3所示,I2C模块中的第二个时钟分配器将模块时钟向下划分,以产生主时钟。
I2C预分频
初始化I2CPSC寄存器的IPSC字段,为了满足所有的I2C协议定时规范,模块时钟必须配置在7-12Mhz之间。
只有在I2C模块处于复位状态(I2CMDR寄存器中的IRS=0)时,才能初始化预分频器。预定频率仅在IRS更改为1时生效。当IRS=1时更改IPSC值无效。
I2C时钟分频寄存器
当I2C模块为主站时,模块时钟被分频,用作SCL上的时钟。如图20-4所示,SCL上时钟的形状取决于两个细分值:
- I2CCLKL中的ICCL:对于每个主时钟周期,ICCL确定低电平的时间。
- I2CCKLH中的ICCH:对于每个主时钟周期,ICCH确定高电平的时间。
主时钟周期(Tmst)是模块时钟周期(Tmod)的倍数,其中,d取决于分频值IPSC(I2CPSC寄存器):
2. 引脚配置
GPIO mux寄存器必须配置为将此外设连接到设备引脚。为避免管脚出现故障,必须首先配置GPyGMUX位(同时将相应的GPyMUX位保持在默认值0),然后将GPyMUX寄存器写入所需值。某些IO功能由独立于此外设的GPIO寄存器设置定义。对于输入信号,应通过将适当的GPxQSELn寄存器设置为11b,将GPIO输入限定设置为异步模式。内部上拉可以在GPyPUD寄存器中配置。
三、I2C总线协议及其实现方式
1. 电平转换
主站为每个传输的数据位产生一个时钟脉冲。由于可以连接到I2C总线的技术设备各有不同,因此逻辑0(低)和逻辑1(高)的电平不是固定的,取决于VDD的相关电平。
在时钟的高周期内,SDA上的数据必须稳定(见图20-5)。只有当SCL上的时钟信号低时,SDA(数据线的高或低状态)才应改变。
2. 运行模式转换
I2C模块有四种基本运行模式,以支持作为主站和从站的数据传输。
如果I2C模块为主站,它首先作为一个主发送器,通常为一个特定的从机发送一个地址。向从机发送数据时,I2C模块必须保持为主发送模式。要从从站接收数据,I2C模块必须切换为为主站接收模式。
如果I2C模块是从站,则它从从机接收模式开始运行,通常在从主站识别到它的从站地址时发送ACK位。如果主站向I2C模块发送数据,则该模块必须保持从站接收模式的状态。如果主站已从I2C模块请求数据,则必须将模块更改为从站发送器模式。
详见下图:
I2CMDR寄存器的RM、STT和STP位定义的主发射机/接收机总线活动:
3. 模块启停条件
当模块配置为I2C总线上的主模块时,I2C模块可以生成启动和停止条件。如图20-6所示:
- 启动条件定义为当SCL为高时,SDA线路上的高-低转换。主站以此表示数据传输的开始。
- 停止条件定义为当SCL为高时,SDA线上的低到高转换。主站以此表示数据传输的结束。
在启动条件之后和随后的停止条件之前,I2C总线被视为繁忙,I2CSTR的总线繁忙(BB)位为1。在停止条件和下一个启动条件之间,总线被视为空闲,BB为0。
要使I2C模块以启动条件启动数据传输,I2CMDR中的主模式位(MST)和启动条件位(STT)都必须为1。要使I2C模块以停止条件结束数据传输,停止条件位(STP)必须设置为1。当BB位设置为1,STT位设置为1时,产生重复启动条件。
4. 串行数据格式
I2C模块支持1到8位数据值。图20-7显示了I2C总线上传输8位数据的示例。SDA线上的每一位对应于SCL线上的一个脉冲,并且值总是以最高有效位(MSB)为第一位进行传输。可以传输或接收的数据值的数量是不受限制的。注:在图20-7到图20-10中,n=由I2CMDR的位计数(BC)字段指定的数据位数(从1到8)。
注:MSB(Most Significant Bit)即最高有效位,与之对应的是LSB(Least Significant Bit)最低有效位
7位地址格式(图20-8)
起始位后的第一个字节由7位从机地址和R/W位组成。R/W决定数据的方向:
- R/W=0:主设备将数据写入(传输)到寻址从设备。
- R/W=1:主设备从从从设备读取(接收)数据。
在每个字节之后插入专用于确认(ACK)的额外时钟周期。如果从机在主机的第一个字节后插入ACK位,则其后是来自发射机的n位数据(主机或从机,取决于R/W位)。n是由I2CMDR的位计数(BC)字段确定的从1到8的数字。在数据位被传输之后,接收器插入一个ACK位。
要选择7位寻址格式,请将0写入I2CMDR的扩展地址启用(XA)位,并确保自由数据格式模式已关闭(I2CMDR中的FDF=0)。
10位地址格式(图20-9)
10位寻址格式与7位寻址格式类似,但主设备通过两个单独的字节传输发送从设备地址。第一个字节由11110b、10位从机地址的两个MSB和R/W=0(写)组成。第二个字节是10位从机地址的剩余8位。从机必须在每两个字节的传输之后发送确认。一旦主设备将第二个字节写入从设备,主设备就可以写入数据或使用重复启动条件来改变数据方向。
要选择10位寻址格式,请将1写入I2CMDR的XA位,并确保自由数据格式模式已关闭(I2CMDR中的FDF=0)。
自由数据格式(图20-10)
起始条件后的第一个字节是数据字节。根据I2CMDR的BC字段,在每个数据字节后插入一个ACK位,可以是1到8位。未发送地址或数据方向位。因此,发送器和接收器都必须支持自由数据格式,并且在整个传输过程中数据的方向必须是恒定的。
要选择自由数据格式,请将1写入I2CMDR的自由数据格式(FDF)位。数字环回模式(I2CMDR中的DLB=1)不支持自由数据格式。
重复启动条件
在每个数据字节的末尾,主机可以驱动另一个启动条件。利用这一功能,一个主机可以与多个从机地址通信,而不必通过驱动停止条件来放弃对总线的控制。一个数据字节的长度可以是1到8位,由I2CMDR的BC字段选择。重复启动条件可用于7位寻址、10位寻址和自由数据格式。图20-11显示了7位寻址格式中的重复启动条件。
5. NACK位(不应答位)的生成
当I2C模块是接收端(主或从)时,它可以应答或忽略发射器发送的位。要忽略任何新位,I2C模块必须在总线上的确认周期内发送一个不应答(NACK;no-acknowledge)位。表20-5生成了通知I2C模块发送NACK位的各种方法。
以下情况会导致出现NACK位:
- 接收机没有发送机响应的地址,接收端没有任何ACK发送给发射机
- 由于接收机正在忙碌处理实时程序导致接无法接收或者发送
- 传输过程中,接收机识别不了发送机的数据或命令
- 接收机无法接收
- 主机接收完成读取数据后,要发送NACK结束告知从机
6. 时钟同步
在正常情况下,只有一个主设备产生时钟信号SCL。然而,在仲裁过程中,有两个或两个以上的主机,时钟必须同步,以便可以比较数据输出。图20-12说明了时钟同步。
SCL的线与特性意味着 首先在SCL上生成低周期的设备将优先于其他设备。在这种从高到低的转换中,其他设备的时钟发生器被迫开始它们自己的低周期。SCL由低周期最长的装置保持低。其他完成低周期的设备必须等待SCL释放,然后才能开始高周期。在SCL上获得同步信号,其中最慢的设备确定低周期的长度,最快的设备确定高周期的长度。
如果一个设备拉下时钟线的时间更长,结果是所有的时钟发生器必须进入等待状态。通过这种方式,从站会减慢快速的主站的速度,而慢速设备会产生足够的时间来存储接收到的字节或准备要传输的字节。
7. 仲裁
如果两个或多个主发送器试图在几乎相同的时间在同一总线上启动传输,则调用仲裁程序。
仲裁程序使用竞争变送器在串行数据总线(SDA)上提供的数据。图20-13说明了两个装置之间的仲裁程序。第一个释放SDA线路高电平的主发送器被另一个驱动SDA低电平的主发送器否决。仲裁程序优先考虑传输具有最低二进制值的串行数据流的设备。两个或多个设备是否发送相同的信息第一个字节,仲裁在随后的字节上继续。
仲裁失败的从站将切换到从属接收器模式,设置仲裁失败(AL)标志,并产生仲裁丢失中断请求。如果在串行传输期间,当重复启动条件或停止条件被传输到SDA时,仲裁程序仍在进行中,则所涉及的主站发送端必须在格式帧中的相同位置发送重复启动条件或停止条件。以下双方均不允许仲裁:
- 重复启动条件和数据位
- 停止条件和数据位
- 重复启动条件和停止条件
8. 数字回环模式
28377的I2C模块支持称为数字回环的自检模式,通过在I2CMDR寄存器中设置DLB位来启用。
在此模式下,I2CDXR寄存器发送的数据在I2CDRR寄存器中接收。数据遵循一条内部路径,需要n个周期才能到达I2CDRR,其中:
发送时钟和接收时钟相同。外部SDA引脚上的地址是I2COAR寄存器中的地址。图20-14显示了数字回环模式下的信号路由。
四、I2C模块的中断请求
1. 基本I2C中断请求
I2C模块可以生成七种类型的基本中断请求。
中断请求 | 中断源 |
---|---|
XRDYINT | 传输准备状态: 数据传输寄存器(I2CDXR)准备接受新数据,先前的数据已从I2CDXR复制到传输移位寄存器(I2CXSR)。 |
RRDYINT | 接收就绪条件: 数据接收寄存器(I2CDRR)已准备好被读取,数据已从接收移位寄存器(I2CRSR)复制到I2CDRR。 在FIFO模式下不应使用XRDYINT,应使用FIFO中断代替。 |
ARDYINT | 寄存器访问准备状态: I2C模块的寄存器准备好被访问,因为先前程序设置的地址、数据和命令值已被使用。 |
NACKINT | 无应答条件: I2C模块被配置为主发送器,未收到从接收器的应答。 |
ALINT | 仲裁失败情况: I2C模块与另一个主发送器的仲裁比较失败。 |
SCDINT | 检测到停止条件: 在I2C总线上检测到停止条件。 |
AASINT | 作为从设备寻址: I2C总线上的另一个主设备已将I2C作为从设备寻址。 |
如图20-15所示,所有请求通过一个仲裁器多路传输到一个I2C中断请求到CPU。每个中断请求在状态寄存器(I2CSTR)中有一个标志位,在中断启用寄存器(I2CIER)中有一个启用位。当某个指定事件发生时,将设置其标志位。如果相应的启用位为0,则中断请求被阻止。如果启用位为1,则请求作为I2C中断转发给CPU。
I2C中断是CPU的可屏蔽中断之一。与任何可屏蔽中断请求一样,如果在CPU中正确启用,CPU将执行相应的中断服务程序(I2CINT1A_ISR)。I2C中断的I2CINT1A_ISR可以通过读取中断源寄存器I2CISRC来确定中断源。然后I2CINT1A_ISR可以调转到相应的子程序。
CPU读取I2CISRC后,会发生以下事件:
- 源中断的标志在I2CSTR中被清除。特别说明:在读取I2CISRC时,I2CSTR中的ARDY、RRDY和XRDY位未清除。要清除这些位中的一位,需向其中写入1。
- 仲裁器确定剩余的中断请求中哪个具有最高优先级,将中断的代码写入I2CISRC,并将中断请求转送至CPU。
2. FIFO中断
除了七个基本的I2C中断,发送和接收FIFO都包含生成中断(I2CINT2A)的能力。传输FIFO可配置为在传输定义的字节数(最多16字节)后生成中断。接收FIFO可配置为在接收到规定的字节数(最多16字节)后生成中断。这两个中断源被“或”合并为一个可屏蔽的CPU中断。然后中断服务程序可以读取FIFO中断状态标志,以确定中断来自哪个源。请参阅I2C传输FIFO寄存器(I2CFFTX)和I2C接收FIFO寄存器(I2CFFRX)说明。
五、重置或禁用I2C模块
可以通过两种方式重置或禁用I2C模块:
- 将0写入I2C模式寄存器(I2CMDR)中的I2C复位位(IRS)。在I2CSTR中所有状态位被强制为其默认值,I2C模块保持禁用状态,直到IRS更改为1。SDA和SCL引脚处于高阻抗状态。
- 通过讲XRS引脚置低进行设备复位。整个设备复位,并保持在复位状态,直到引脚置高。释放XRS引脚后,所有I2C模块寄存器都将重置为其默认值。IRS位强制为0,这将重置I2C模块。I2C模块保持复位状态,直到将1写入IRS。
配置或重新配置I2C模块时,IRS必须为0。强制IRS为0可用于节省电源和清除错误条件。
六、I2C寄存器
1. 2个I2C模块的寄存器基地址
2. 每个I2C模块的寄存器地址
3. 重要寄存器(需主动配置)
I2C中断使能寄存器
I2C时钟分频寄存器(I2CCLKL、I2CCLKH)
I2C从站地址寄存器
I2C模式寄存器
RM:重复模式(仅当I2C模块为主变送器时适用)
重复模式时:每次写入I2CDXR寄存器时(或在FIFO模式下传输FIFO为空时),都会传输一个数据字节,直到手动设置STP位。I2CCNT的值被忽略。ARDY位/中断可用于确定I2CDXR(或FIFO)何时准备好接收更多数据,或何时数据已全部发送且允许CPU写入STP位。
STT:启动条件位(仅当I2C模块为主模块时适用)
RM、STT和STP位确定I2C模块何时开始和停止数据传输(见表9-6)。请注意,STT和STP位可用于终止重复模式,当IRS=0时,该位不可写。
0h(R/W):在主模式下,STT在生成启动条件后自动清除。
1h(R/W):在主模式下,将STT设置为1会导致I2C模块在I2C总线上生成启动条件
STP:停止条件位(仅当I2C模块为主模块时适用)
在主站模式下,RM、STT和STP位确定I2C模块何时开始和停止数据传输。
请注意,STT和STP位可用于终止重复模式,并且当IRS=0时,该位不可写入。在非重复模式下,在生成停止条件之前,必须至少传输一个字节。I2C模块延迟清除该位,直到设置I2CSTR[SCD]位。为了避免中断I2C状态机,用户必须等到该位清除后才能启动新消息。
0h(R/W):STP在生成停止条件后自动清除
1h(R/W):STP已被设备设置为当I2C模块的内部数据计数器倒计时至0时生成停止条件