目录
- 硬知识
- USCI的I2C模式
- I2C概述
- MSP430单片机I2C模块特征及结构框图
- I2C原理
- I2C主从操作
- (1)从模式
- (2)主模式
- I2C模式下的USCI中断
- USCI寄存器—I2C模式
- I2C API (机翻)
- API介绍
- 主机模式
- 主机模式单字节传输
- 主机模式多字节传输
- 主机模式单字节接收
- 主机模式多字节接收
- 带超时的主机模式单字节传输
- 带超时的主机模式多字节传输
- 带超时的主机模式单字节接收
- 从机模式
- 从机模式发送API
- 从机模式接收API
- API细分
- 处理中断的函数
- 参数
- 处理状态和初始化的函数
- 参数
- 从机模式收发函数
- 参数
- 主机模式收发函数
- 参数
- DMA相关
- 参数
平台:Code Composer Studio 10.3.1
MSP430F5529 LaunchPad™ Development Kit
(MSP‑EXP430F5529LP)
硬知识
USCI的I2C模式
I2C概述
MSP430单片机的USCI_B模块能够支持I2C通信,能够为MSP430单片机与具有I2C接口的设备互连提供条件。软件上只需要完成I2C功能的配置,硬件能够完全实现I2C通信的功能。相比较利用GPIO软件模拟实现I2C操作,能够减少CPU的负荷。
MSP430单片机I2C模块特征及结构框图
(1)MSP430单片机I2C模块的主要特征
与Philips半导体I2C规范V2.1兼容;
7位或10位设备寻址模式;
群呼;
开始/重新开始/停止;
多主机发送/接收模式;
从机发送/接收模式;
支持100 kbps的标准模式和高达400 kbps的快速模式;
主机模式下时钟发生器UCxCLK频率可编程;
支持低功耗模式;
从机接收根据检测到开始信号自动将MSP430单片机从LPMx模式下唤醒;
LPM4模式下的从模式操作。
(2)MSP430单片机的USCI模块配置为I2C模式时的结构框图
MSP430单片机的USCI模块配置为I2C模式时的结构框图如图所示。
I2C原理
(1)I2C设备连接原理
I2C设备连接示意图如图所示。I2C总线是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。在MSP430单片机与被控IC(集成电路)之间、IC与IC之间进行双向传送,最高传送速率400kbps。各种设备均并联在总线上,两条总线都被上拉电阻上拉到VCC,所有设备地位对等,都可作为主机或从机,就像电话机一样只要拨通各自的号码就能正常工作,所以,每个设备都有唯一的地址。在信息的传输过程中,I2C总线上并接的每个设备既是主设备(或从设备),又是发送设备(或接收设备),这取决于它所要完成的功能。每个设备都可以把总线接地拉低,却不允许把总线电平直接连到VCC上置高。把总线电平拉低称为占用总线,总线电平为高等待被拉低则称为总线被释放。
(2)I2C数据通信协议
I2C数据通信时序图如图所示。下面首先介绍起始位和停止位,起始位和停止位都是由主设备产生的,如图中虚线所示。
I2C总线上每位数据传输的示意图如图所示。
(3)I2C的寻址方式
MSP430单片机的I2C模块支持7位和10位两种寻址模式,7位寻址模式最多寻址128个设备,10位寻址模式最多寻址1024个设备。I2C总线理论上可以允许的最大设备数是以总线上所有器件的电容总和不超过400pF为限(其中,包括连线本身的电容和其连接端的引出等效电容),总线上所有器件要依靠SDA发送的地址信号寻址,不需要片选信号。
① 7位寻址模式
② 10位寻址模式
③ 二次发送从地址模式(重复产生起始条件)
(4)总线多机仲裁
I2C协议是完全对称的多主机通信总线,任何一个设备都可以成为主机从而控制总线。但是,同一时间只能有一个主机控制总线,当有两个或两个以上的器件都想与其他器件进行通信时,则需要总线仲裁决定究竟由谁控制总线。总线仲裁过程能够避免总线冲突,如图所示。
仲裁过程中使用的数据就是相互竞争的设备发送到SDA数据线上的数据。第1个检测到自己发送的数据和总线上数据不匹配的设备会失去仲裁能力。如果两个或更多的设备发送的第一个字节的内容相同,那么仲裁就发生在随后的传输中。也许直到相互竞争的设备已经传输了许多字节后,仲裁才会完成。当产生竞争时,如果某个设备当前发送位的二进制数值和前一个时钟节拍发送的内容相同,那么它在仲裁过程中就获得较高的优先级。如上图所示,第1个主发送设备产生的逻辑高电平被第2个主发送设备产生的逻辑低电平否决,因为前一个节拍总线上是低电平。失去仲裁的第1个主发送设备转变成从接收模式,并且设备仲裁失效中断标志位UCALIFG。
在总线仲裁的过程中,两主机的时钟肯定不会完全一致,因此,需要对来自不同主设备的时钟信号进行同步处理,I2C模块的时钟同步操作如下图所示。设备1和设备2的时钟不同步,两者“线与”之后,才是总线时钟。即在第1个产生低电平时钟信号的主设备强制时钟总线SCL拉低,直到所有的主设备都结束低电平时钟,时钟总线SCL才被拉高。在SCL低电平的时间内,如果有主设备已经结束低电平状态,就开始等待。因此,时钟同步会降低数据传输速率。
I2C主从操作
在I2C模式下,USCI模块可以工作在主发送模式、主接收模式、从发送模式或从接收模式。本节详细介绍这些模式。
(1)从模式
① I2C从机发送模式
② I2C从机接收模式
③ I2C从机10位寻址模式
(2)主模式
通过设置UCMODEx=11,USCYNC=1,置位UCMST控制位,USCI模块将被配置为I2C主模式。若当前主机是多主机系统的一部分时,必须将UCMM置位,并将其自身地址编程写入UCBxI2COA寄存器。当UCA10=0时,选择7位寻址模式;当UCA10=1时,选择10位寻址模式。UCGCEN控制位选择USCI模块是否对全呼做出反应。
① I2C主机发送模式
初始化之后,主发送模式通过下列方式启动:将目标从地址写入UCBxI2CSA寄存器,通过UCSLA10控制位选择从地址大小,置位UCTR控制位将主机设置为发送模式,然后置位UCTXSTT控制位产生起始条件。
② I2C主机接收模式
初始化之后,通过下列方式启动主接收模式:把目标从地址写入UCBxI2CSA寄存器,通过UCSLA10控制位选择从地址大小,清除UCTR控制位来选择接收模式,置位UCTXSTT控制位产生一个起始条件。
I2C模式下的USCI中断
USCI模块只有一个中断向量。该中断向量由发送、接收及状态改变中断复用。USCI_Ax和SUCI_Bx不使用同一个中断向量。每个中断标志都有自己的中断允许位,当总中断允许GIE置位时,如果使能一个中断,且产生了该中断标志位,将会产生中断请求。在集成有DMA控制器的芯片上,UCTXIFG和UCRXIFG标志将控制DMA传输。
(1)I2C发送中断操作
为了表明发送缓冲寄存器UCBxTXBUF为空,即可以接收新的字符,发送器将置位UCTXIFG中断标志位。如果此时UCTXIE和GIE也已经置位,则会产生一个中断请求。当有字符写入UCBxTXBUF或接收到NACK信号时,UCTXIFG会自动复位。当选择I2C模式且UCSWRST=1时,将会置位UCTXIFG中断标志位。PUC复位后或UCSWRST被配置为1时,UCTXIE将自动复位。
(2)I2C接收中断操作
当接收到一个字符并将其装载到UCBxRXBUF中时,将置位UCRXIFG中断标志位。如果此时UCRXIE和GIE也已经置位,则会产生一个中断请求。PUC复位后或者UCSWRST被配置为1时,UCRXIFG和UCTXIE复位。对UCxRXBUF进行读操作之后,UCRXIFG将会自动复位。
(3)I2C状态改变中断操作
I2C状态改变中断标志位及其说明如表所示。
USCI寄存器—I2C模式
I2C模式下可用的USCI寄存器如表所示。
I2C API (机翻)
API介绍
主机模式
要驱动主模块,需要按以下顺序调用api
USCI_B_I2C_initMaster ()
USCI_B_I2C_setSlaveAddress ()
USCI_B_I2C_setMode ()
USCI_B_I2C_enable ()
USCI_B_I2C_enableInterrupt()(如果正在使用中断)
随后可能会有用于传输或接收所需的api。
用户必须首先初始化USCI_B_I2C模块,并通过调用USCI_B_I2C_initMaster()将其配置为一个主模块。该功能将设置时钟和数据速率。然后调用USCI_B_I2C_setSlaveAddress来设置主服务器想要与之通信的从服务器地址。然后使用USCI_B_I2C_setMode选择操作模式(发送或接收)。现在可以使用USCI_B_I2C_enable启用USCI_B_I2C模块。建议在开启中断前先开启USCI_B_I2C模块。在启用中断(如果有的话)后,任何数据的传输或接收都可以在此时启动。
然后可以通过调用传输或接收相关api在总线上启动事务,如下所示。如果设备在等待设置IFG标志时被卡住,可以使用包含超时的api来避免陷入无限循环
主机模式单字节传输
USCI_B_I2C_masterSendSingleByte()
主机模式多字节传输
USCI_B_I2C_masterSendMultiByteStart()
USCI_B_I2C_masterSendMultiByteNext()
USCI_B_I2C_masterSendMultiByteFinish()
USCI_B_I2C_masterSendMultiByteStop()
主机模式单字节接收
USCI_B_I2C_masterReceiveSingleStart()
USCI_B_I2C_masterReceiveSingle()
主机模式多字节接收
USCI_B_I2C_masterReceiveMultiByteStart()
USCI_B_I2C_masterReceiveMultiByteNext()
USCI_B_I2C_masterReceiveMultiByteFinish()
USCI_B_I2C_masterReceiveMultiByteStop()
带超时的主机模式单字节传输
USCI_B_I2C_masterSendSingleByteWithTimeout()
带超时的主机模式多字节传输
USCI_B_I2C_masterSendMultiByteStartWithTimeout()
USCI_B_I2C_masterSendMultiByteNextWithTimeout()
USCI_B_I2C_masterReceiveMultiByteFinishWithTimeout()
USCI_B_I2C_masterSendMultiByteStopWithTimeout()
带超时的主机模式单字节接收
USCI_B_I2C_masterReceiveSingleStartWithTimeout()
对于中断驱动事务,用户必须为USCI_B_I2C设备注册一个中断处理程序,并启用USCI_B_I2C中断。
从机模式
要驱动从模块,需要按以下顺序调用api
USCI_B_I2C_initSlave ()
USCI_B_I2C_setMode ()
USCI_B_I2C_enable ()
USCI_B_I2C_enableInterrupt()(如果正在使用中断)
随后可能会有用于传输或接收所需的api
用户必须先调用USCI_B_I2C_initSlave来初始化USCI_B_I2C中的从模块
模式,并设置从地址。接下来是一个呼叫来设置操作模式(发送或接收)。现在可以使用USCI_B_I2C_enable()启用USCI_B_I2C模块。建议在启用中断之前启用USCI_B_I2C模块。在启用中断(如果有的话)后,任何数据的传输或接收都可以在此时启动。
然后可以通过调用传输或接收相关api在总线上启动事务,如下所示。
从机模式发送API
USCI_B_I2C_slavePutData()
从机模式接收API
USCI_B_I2C_slaveGetData()
对于中断驱动事务,用户必须为USCI_B_I2C设备注册一个中断处理程序,并启用USCI_B_I2C中断。
API细分
USCI_B_I2C API被分成三组函数:
处理中断的函数,
处理状态和初始化的函数,
处理发送和接收数据的函数。
处理中断的函数
USCI_B_I2C_enableInterrupt(uint16_t baseAddress, uint8_t mask)
//使能单个I2C中断源
USCI_B_I2C_disableInterrupt(uint16_t baseAddress, uint16_t mask)
//禁用单个I2C中断源
USCI_B_I2C_clearInterrupt(uint16_t baseAddress, uint8_t mask)
//清除I2C中断源
USCI_B_I2C_getInterruptStatus(uint16_t baseAddress, uint8_t mask)
//获取当前I2C中断状态
USCI_B_I2C_masterIsStopSent(uint16_t baseAddress)
//指示是否已发送STOP
USCI_B_I2C_masterIsStartSent(uint16_t baseAddress)
//指示是否已发送START
参数
baseAddress
USCI_B0_BASE
USCI_B1_BASE
mask
/*is the bit mask of the interrupt sources to be enabled. Mask value is the logical
OR of any of the following:*/
USCI_B_I2C_STOP_INTERRUPT /*- STOP condition interrupt*/
USCI_B_I2C_START_INTERRUPT /*- START condition interrupt*/
USCI_B_I2C_RECEIVE_INTERRUPT /*- Receive interrupt*/
USCI_B_I2C_TRANSMIT_INTERRUPT /*- Transmit interrupt*/
USCI_B_I2C_NAK_INTERRUPT /*- Not-acknowledge interrupt*/
USCI_B_I2C_ARBITRATIONLOST_INTERRUPT /*- Arbitration lost interrupt*/
处理状态和初始化的函数
USCI_B_I2C_initMaster(uint16_t baseAddress, USCI_B_I2C_initMasterParam ∗ param)
//初始化I2C模块为主机模式
USCI_B_I2C_enable(uint16_t baseAddress)
//启用I2C模块
USCI_B_I2C_disable(uint16_t baseAddress)
//禁用I2C模块
USCI_B_I2C_isBusBusy(uint16_t baseAddress)
//指示I2C总线是否忙
USCI_B_I2C_initSlave(uint16_t baseAddress, uint8_t slaveAddress)
//初始化I2C模块为从机模式
USCI_B_I2C_getInterruptStatus(uint16_t baseAddress, uint8_t mask)
//获取当前I2C中断状态
USCI_B_I2C_setSlaveAddress(uint16_t baseAddress, uint8_t slaveAddress)
//设置I2C模块的目标地址
USCI_B_I2C_setMode(uint16_t baseAddress, uint8_t mode)
//设置I2C设备模式
参数
baseAddress
USCI_B0_BASE
USCI_B1_BASE
USCI_B_I2C_initMasterParam
//*****************************************************************************
//
//! \brief Used in the USCI_B_I2C_initMaster() function as the param parameter.
//
//*****************************************************************************
typedef struct USCI_B_I2C_initMasterParam {//! Is the clocksource.//! \n Valid values are://! - \b USCI_B_I2C_CLOCKSOURCE_ACLK//! - \b USCI_B_I2C_CLOCKSOURCE_SMCLKuint8_t selectClockSource;//! Is the rate of the clock supplied to the I2C module.uint32_t i2cClk;//! Set up for selecting data transfer rate.//! \n Valid values are://! - \b USCI_B_I2C_SET_DATA_RATE_400KBPS//! - \b USCI_B_I2C_SET_DATA_RATE_100KBPSuint32_t dataRate;
} USCI_B_I2C_initMasterParam;
slaveAddress
7位从机地址
mask
/*is the bit mask of the interrupt sources to be enabled. Mask value is the logical
OR of any of the following:*/
USCI_B_I2C_STOP_INTERRUPT /*- STOP condition interrupt*/
USCI_B_I2C_START_INTERRUPT /*- START condition interrupt*/
USCI_B_I2C_RECEIVE_INTERRUPT /*- Receive interrupt*/
USCI_B_I2C_TRANSMIT_INTERRUPT /*- Transmit interrupt*/
USCI_B_I2C_NAK_INTERRUPT /*- Not-acknowledge interrupt*/
USCI_B_I2C_ARBITRATIONLOST_INTERRUPT /*- Arbitration lost interrupt*/
mode
/*indicates whether module is in transmit/receive mode Valid values
are:*/
USCI_B_I2C_TRANSMIT_MODE
USCI_B_I2C_RECEIVE_MODE /*[Default]*/
从机模式收发函数
USCI_B_I2C_slavePutData(uint16_t baseAddress, uint8_t transmitData)
//从机模式下I2C模块发送一个字节
USCI_B_I2C_slaveGetData(uint16_t baseAddress)
//从机模式下接收已发送到I2C模块的字节
参数
baseAddress
USCI_B0_BASE
USCI_B1_BASE
transmitData
I2C模块要发送的数据
主机模式收发函数
USCI_B_I2C_masterSendSingleByte(uint16_t baseAddress, uint8_t txData)
//从主机到从机进行单字节传输
USCI_B_I2C_masterSendMultiByteStart(uint16_t baseAddress, uint8_t txData)
//发送从主机到从机多字节传输的START信号和首个数据
USCI_B_I2C_masterSendMultiByteNext(uint16_t baseAddress, uint8_t txData)
//发送从主机到从机多字节传输的中间数据
USCI_B_I2C_masterSendMultiByteFinish(uint16_t baseAddress, uint8_t txData)
//发送从主机到从机多字节传输的结尾数据和STOP信号
USCI_B_I2C_masterSendMultiByteStop(uint16_t baseAddress)
//发送从主机到从机多字节传输的STOP信号
USCI_B_I2C_masterReceiveMultiByteStart(uint16_t baseAddress)
//主机模块使用此函数启动多字节接收,该函数的作用如下:发送START信号
USCI_B_I2C_masterReceiveMultiByteNext(uint16_t baseAddress)
//主机模块使用此函数来接收多字节接收中的中间字节,这个函数读取当前接收的字节
USCI_B_I2C_masterReceiveMultiByteFinish(uint16_t baseAddress)
//主机模块使用此函数来接收多字节接收的末字节,接收末字节并发送STOP信号
USCI_B_I2C_masterReceiveMultiByteStop(uint16_t baseAddress)
//主机模块使用此函数在多字节接收后发送STOP信号
USCI_B_I2C_masterReceiveSingleStart(uint16_t baseAddress)
//主机模块启动一个单字节接收,这个函数立即发送一个START和STOP来准备单字节接收
USCI_B_I2C_masterReceiveSingle(uint16_t baseAddress)
//接收已发送到I2C主机模块的字节,这个函数从I2C接收数据寄存器读取一个字节的数据
USCI_B_I2C_getReceiveBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块I2C的RX缓冲区的地址
USCI_B_I2C_getTransmitBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的12C的TX缓冲区的地址
参数
baseAddress
USCI_B0_BASE
USCI_B1_BASE
txData
I2C模块要发送的数据
DMA相关
USCI_B_I2C_getReceiveBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的2C的RX缓冲区的地址
USCI_B_I2C_getTransmitBufferAddressForDMA(uint16_t baseAddress)
//返回DMA模块的12C的TX缓冲区的地址
参数
baseAddress
USCI_B0_BASE
USCI_B1_BASE