This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP430F5529:关于MSP430F5529的I2C帮助

Guru**** 2611705 points
Other Parts Discussed in Thread: MSP430F5529, INA260, MSP430F2619, ENERGIA

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/664590/ccs-msp430f5529-i2c-help-on-msp430f5529

部件号:MSP430F5529
主题中讨论的其他部件: INA260MSPWAREMSP430F2619ENERGIA

工具/软件:Code Composer Studio

团队,

我 是一个应用程序旋转器,正在为客户启动和运行新的传感器演示。 该传感器需要i2c,我们正在对MSP430F5529进行降级。 目前,我正努力让i2c工作,以便我可以在寄存器中写入和读取数据。 我不确定应该降级的传感器是否正常工作,因此目前我只是尝试通过i2c对INA260 EVM进行读写操作。 到目前为止,我尝试了多种方法。 我尝试将代码从USBIB0基址读取和写入多个字节的“示例”。 我还尝试将其他人的I2C代码从其他微控制器移植到5529,但没有成功。 我认为我的主要问题是编写ISR,我没有找到这方面的好例子。  

问题1:

TI是否有任何良好的I2C示例用于读/写器件?

问题2:

我在下面列出了我的3种方法。 如果其中任何一个看起来很接近,我将非常感谢您对我如何开始使用I2C的意见。 我以前在微芯片控制器上使用过I2C,并阅读了我可以找到的所有TI文献(用户指南,数据表,如何使用I2C,I2C基础知识和mspware)。 我现在也熟悉了USCI图书馆。  

方法1:根据 MSP430F2619的示例代码编写i2c。

主要c 
#include <stdio.h>
#include <msp430f5529.h>
#include <lib5529i2c.h>

unsigned char array[5]={ 0x00, 0x07, 0x27};
unsigned char array2[5];
signed char byteCtr;
unsigned char *TI_receive字段;
unsigned char *TI_transmit_field;


void main(void)
{

WDTCTL = WDTPW + WDTHOLD;//禁用看门狗
P1DIR |= 0x01;
p1out= 0x00;//将WFP 1.0 配置为输出
_EINT();//启用中断
__enable_interrupit();
TI_USI_I2C_TEXINIT (0x40,0x12);//初始化USCI
同时( TI_USI_I2C_NOREADY());
TI_USI_I2C_Transmit (3,array);//传输数组的前3个字节
//LPM0;//在通信期间将CPU置于休眠状态
TI_USI_I2C_receiveinit(0x40,0x12);
同时( TI_USI_I2C_NOREADY());
TI_USI_I2C_receive (3,array2);
} 

lib5529i2c.h

/*
* lib5529i2c.h
*
*创建时间:2018年2月9日
* 作者:a22.6654万
*/

#ifndef LIB5529I2C_H_
#define LIB5529I2C_H_

#define SDA_PIN BIT0 // msp430x261x UCB0SDA引脚
#define SCL_PIN BIT1 // msp430x261x UCB.S引脚



void TI_USI_I2C_receiveinit(unsigned char slaver_address, unsigned char presale);
void TI_USI_I2C_transmitinit(unsigned char slaver_address, unsigned char presale);


void TI_I2C_unsigned



char (i2C_dich_present (i2C_unsigned char ;#I2I2C_unsigned char /uchar未签名char 55_unsigned char i2I2I2I2I2_unsigned char *









lib5529i2c.c

//************************************************************************************************
// MSP430 USCI I2C发送器和接收器
////
说明:此代码将MSP430的USCI模块配置为
// I2C主模块,能够发送和接收字节。
////***
这是主代码***////

母版
// MSP430F2619
// --------
// /|\\| Xin|-
// || |//
--|RST XOUT|-
// | |//
| |//
| |//
| SDA/WFP 3.1 >//
| SCL/WFP 3.2 (SCL/WFP设置)|----------- >///

注:SDA和SCL需要外部拉拔
//
Uli Kretzschmar
// Texas Instruments Deutschland GmbH
// 2007年11月
//使用IAR嵌入式工作台版本:3.42A
//************************************************************************************************构建

包含"msp430f5529.h" //器件特定标头
//#include "msp430x22x4.h"
//#include "msp430x23x0.h"
//#include "msp430xG46x.h"
//... //可能有更多的设备

#include "lib5529i2c.h"

signed char byteCtr;
unsigned char *TI_receive_field;
unsigned char *TI_transmit_field;
int q=0;
//------------
// void TI_USI_I2C_receiveinit (unsigned char slaver_address
,// unsigned char prescale)
////
此函数初始化主接收操作的USCI模块。
////
in:unsigned char slaver_address => Slave Address
// 无符号字符预分页 => SCL时钟调整
//------------------
void TI_USI_I2C_receiveinit(unsigned char slaver_address,
unsigned char prescale){
P3SEL || SDA_PIN + SCL_PIN; //将I2C引脚分配给USI_B0
UCB0CTL1 = UCSWRST; //启用软件重置
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
UCB0BR0 =预分页; // set prescaler
UCB0BR1 = 0;
UCB0I2CSA = slaver_address; //设置从属地址
UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
UCB0IE = UCNACKIE;
UCB0IE = UCRXIE; //启用RX中断
}//------------------


// void TI_USI_I2C_TRANSLINIT (unsigned char slaver_address
,// unsigned char prescale)
////
此函数初始化主传输操作的USCI模块。
////
in:unsigned char slaver_address => Slave Address
// 无符号字符预分页 => SCL时钟调整
//------------------
void TI_USI_I2C_TRANSLINIT (unsigned char slaver_address,
unsigned char prescale){
P3SEL || SDA_PIN + SCL_PIN; //将I2C引脚分配给USI_B0
UCB0CTL1 |= UCSWRST; //启用软件重置
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
UCB0BR0 =预分页; // set prescaler
UCB0BR1 = 0;
UCB0I2CSA = slaver_address; //设置从属地址
UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
UCB0IE = UCNACKIE;
UCB0IE |= UCTXIE; //启用TX就绪中断
}//------------------


// void TI_USI_I2C_RECEIVE(unsigned char byteCount, unsigned char *field)
////
此函数用于在主接收器模式下启动I2C通信。
////
in:unsigned char byteCount =>应该读取的字节数
// 无符号字符*field =>用于存储收到的数据的数组变量
//------------------
void TI_USI_I2C_receive (unsigned char byteCount,unsigned char *field){
TI_receive_field = field;
if ( byteCount ==1).
byteCtr =0;
__disable_interrupt ();
UCB0CTL1 || UCTXSTT; // I2C启动条件
期间(UCB0CTL1和UCTXSTT); //开始条件已发送?
UCB0CTL1 || UCTXSTP; // I2C停止条件
__enable_interrupt ();
}如果(byteCount > 1),则为其它项{
byteCtr = byteCount -2;
UCB0CTL1 || UCTXSTT; // I2C启动条件
} else
同时(1); //非法参数
}//------------------


// void TI_USI_I2C_Transmit (unsigned char byteCount,unsigned char *field)
////
此函数用于在主传输模式下启动I2C通信。
////
in:unsigned char byteCount =>应该传输的字节数
// 无符号字符*field =>数组变量。 其内容将被发送。
//------------------
void TI_USI_I2C_Transmit (unsigned char byteCount,unsigned char *field){
TI_Transmit_field = field;
byteCtr = byteCount;
UCB0CTL1 || UCTR + UCTXSTT; // I2C TX,启动条件
}//------------------


// unsigned char TI_USI_I2C_SLAVE_Present (unsigned char slaver_address)
////
此函数用于查找I2C总线上的从属地址。
////
in:unsigned char slaver_address => Slave Address
// out:unsigned char => 0:未找到地址,
// 1:找到的地址
//------------------
unsigned char TI_USCI_I2C_SLAVER_present (unsigned char slaver_address){
unsigned char IE2_bak,slaveadr_Bak,ucb0i2cie,returnValue;
ucb0i2cie = UCB0IE; //恢复旧的UCB0I2CIE
IE2_BAK = UCB0IE; // store IE2 register
slaveadr_Bak = UCB0I2CSA; //存储旧的从属地址
UCB0IE &=~ UCNACKIE; // no nack interrupt
UCB0I2CSA = slaver_address; //设置从属地址
UCB0IE &=~(UCTXIE + UCRXIE); // NO RX或TX中断
__disable_interrupt();
UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP; // I2C TX,启动条件
while (UCB0CTL1和UCTXSTP); //等待停止条件

returnValue =!(UCB0STAT & UCNACKIFG);
__ENable_INTERRUC();
UCB0IE = IE2_BAK; //恢复IE2
UCB0I2CSA = slaveadr_Bak; //恢复旧的从属地址
UCB0IE = ucb0i2cie; //恢复旧的UCB0CTL1
返回值; //无论是否返回
//发生了一个nack
}//------------------


// unsigned char TI_USI_I2C_NOREADY()////

此函数用于检查是否正在进行通信。
//
//输出:unsigned char => 0:I2C总线空闲
,// 1:通信正在进行
中//----------------------------------
unsigned char TI_USSCI_I2C_NOFLEY(){
RETURN (UCB0STAT & UCBBUSY);
}


#pragma vector = USSCI_B0_Vector
__interrupt void USI_B0_ISR(void){

开关(__偶 数_IN_RANGE (UCB0IV,12))
{

案例10:
Q=10;//引导程序10:RXIFG --我还没有使用它(但我需要它)
IF (UCB0STAT和UCNACKIFG){ //如果从设备发送nack,则发送停止
UCB0CTL1 || UCTXSTP;
UCB0STAT &=~UCNACKIFG;
}
中断;
案例12:
Q=12;//矢量12:TXIFG
IF (P2IFG和UCRXIFG){
如果( byteCtr == 0){
UCB0CTL1 || UCTXSTP; // I2C停止条件
*TI_RECETE_FIELD = UCB0RXBUF;
TI_Receive_field+;
}
否则{
*TI_RECETE_FIELD = UCB0RXBUF;
TI_Receive_field++;
byteCtr --;
}
}
否则{
如果(byteCtr ==0){
UCB0CTL1 || UCTXSTP; // I2C停止条件
P2IFG &=~UCTXIFG; //清除USI_B0 TX int标志
}
否则{
UCB0TXBUF =*TI_Transmit_field;
TI_Transmit_field++;
byteCtr --;
}
}
中断;
默认:
中断;

}

} 

方法2:根据5529读/写示例代码编写库  

包含"msp430f5529.h" //器件特定标头
//#include "msp430x22x4.h"
//#include "msp430x23x0.h"
//#include "msp430xG46x.h"
//... //可能有更多设备

#include "lib5529i2c.h"

带符号char byteCtr;
unsigned char *TI_receive_field;
unsigned char *TI_transmit_field;
unsigned char TXByteCtr =0;
unsigned char RXByteCtr =0;

void TI_USI_I2C_receiveinit(unsigned char slaver_address,
unsigned char prescale){
P3SEL || SDA_PIN + SCL_PIN; //将I2C引脚分配给USI_B0
UCB0CTL1 = UCSWRST; //启用软件重置
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
UCB0BR0 =预分页; // set prescaler
UCB0BR1 = 0;
UCB0I2CSA = slaver_address; //设置从属地址
UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
UCB0IE = UCNACKIE;
UCB0IE = UCRXIE; //启用RX中断
}


void TI_USI_I2C_TRANSLINIT (unsigned char slaver_address,
unsigned char prescale){
P3SEL || SDA_PIN + SCL_PIN; //将I2C引脚分配给USI_B0
UCB0CTL1 |= UCSWRST; //启用软件重置
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
UCB0BR0 =预分页; // set prescaler
UCB0BR1 = 0;
UCB0I2CSA = slaver_address; //设置从属地址
UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
UCB0IE = UCNACKIE;
UCB0IE |= UCTXIE; //启用TX就绪中断
}


void TI_USI_I2C_receive(unsigned char byteCount, unsigned char *field){
TI_receive_field = field;
if ( byteCount ==1){
RXByteCtr = 0;
__disable_interrupt ();
UCB0CTL1 || UCTXSTT; // I2C启动条件
期间(UCB0CTL1和UCTXSTT); //开始条件已发送?
UCB0CTL1 || UCTXSTP; // I2C停止条件
__enable_interrupt ();
}如果(byteCount > 1),则为其它项{
RXByteCtr =字节计数-2;
UCB0CTL1 || UCTXSTT; // I2C启动条件
} else
同时(1); //非法参数
}


void TI_USI_I2C_Transmit (unsigned char byteCount,unsigned char *field){
TI_Transmit_field = field;
TXByteCtr = byteCount;
UCB0CTL1 ||= UCTR + UCTXSTT; // I2C tx,起始条件
}


unsigned char TI_USI_I2C_SLAVE_Present (unsigned char slaver_address){
unsigned char IE2_bak,slaveadr_Bak,ucb0i2cie,returnValue;
ucb0i2cie = UCB0IE; //恢复旧的UCB0I2CIE
IE2_BAK = UCB0IE; // store IE2 register
slaveadr_Bak = UCB0I2CSA; //存储旧的从属地址
UCB0IE &=~ UCNACKIE; // no nack interrupt
UCB0I2CSA = slaver_address; //设置从属地址
UCB0IE &=~(UCTXIE + UCRXIE); // NO RX或TX中断
__disable_interrupt();
UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP; // I2C TX,启动条件
while (UCB0CTL1和UCTXSTP); //等待停止条件

returnValue =!(UCB0STAT & UCNACKIFG);
__ENable_INTERRUC();
UCB0IE = IE2_BAK; //恢复IE2
UCB0I2CSA = slaveadr_Bak; //恢复旧的从属地址
UCB0IE = ucb0i2cie; //恢复旧的UCB0CTL1
返回值; //无论是否返回
//出现一个nack
}


unsigned char TI_USSCI_I2C_nofedy(){
Return (UCB0STAT & UCBBUSY);
}


#pragma vector = USSCI_B0_vector
__interrupt void USSCI_B0_ISR(void){

开关(__偶 数_IN_RANGE (UCB0IV,12))
{

案例10:

RXByteCtr --; // Decrement RX字节计数器
IF (RXByteCtr)
{
*TI_RECETE_FIELD = UCB0RXBUF; //将RX数据移动到PRxData地址
IF (RXByteCtr == 1) //只剩下一个字节?
UCB0CTL1 || UCTXSTP; //生成I2C停止条件
}
否则
{
*TI_RECETE_FIELD = UCB0RXBUF; //将最终RX数据移至PRxData
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出活动CPU
}

案例12:

IF (TXByteCtr) //检查TX字节计数器
{
UCB0TXBUF =*TI_Transmit_field; //加载TX缓冲区
TXByteCtr // Decrement TX字节计数
器}
否则
{
UCB0CTL1 || UCTXSTP; // I2C停止条件
UCB0IFG &=~UCTXIFG; //清除USI_B0 TX int标志
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
}

默认:
中断;

}

}

/*
*以下是使用MSP430G2553对24LC512和DS3231 RTC进行读/写的示例。
*提供两种读写功能。
*
*该代码避免了任何while循环,并完全依赖于MSP430的中断和低功耗模式,将功耗降低到
*最低。
*
作者:Ahmed Talaat (aa_talaat@yahoo.com)
*日期:2012年10月19日
*

包含"msp430f5529.h"

#define ONEBYTEADDR 1.
#define TWOBYTEADDR 2.
#定义写入 0 // ISR模式写入或读取
#定义读取 1.
#define NOACK 二
#define EEPROM_ADDR 0x40
#define DS3231_ADDR 0x00

unsigned char txdataeepro[2];
unsigned char txdataDS3231[7]={0x20, 0x30, 0x20, 0x04, 0x17, 0x10,0x12};
unsigned char rxdata[150];

typedef结构{
volatile unsigned char *data_buf; // TX或Rx数据缓冲区的地址
volatile unsigned char buf_size; //缓冲区的大小
volatile unsigned char buf_index; //缓冲区中的索引
volatile unsigned char addr_index; //字节地址索引(0,1)
volatile unsigned char ISR_MODE; // Tx或Rx影响中断逻辑
要读/写的地址的volatile unsigned char addr_high字节;//高字节
要读/写的地址的volatile unsigned char addr_low_bytes;//低字节
volatile unsigned char addr_type; //两个字节(如EEPROM)或1个字节(如RTC
)} I2C_t;

I2c_t i2c_packet;

void i2c_init(void);
void i2c_tx (unsigned char,unsigned char *,unsigned char,unsigned char,unsigned char, unsigned char);
void i2c_rx (unsigned char,unsigned char *,unsigned char,unsigned char,unsigned char, unsigned char);
作废usdelay (int);

Void主(void)
{
WDTCTL = WDTPW + WDTHOLD; //停止WDT
I2C_INIT(); //初始化I2C
txdataeeproem[0]=0x61;
txdataeepro[1]=0x3F;

I2C_TX (EEPROM_ADDR,txdataeeprom,sizeof(txdataeeprom)-1,ONEBYTEADDR,0x00,0x00);//i2c TX 115字节起始地址@ 01:00

I2C_Rx (EEPROM_ADDR,rxdata,2,ONEBYTEADDR,0x00,0x00);//i2c从EEPROM起始值@地址01:00接收115字节


LPM0; //输入LPM0 w/ interrupts
}

void i2c_init(void){
P3SEL || BIT0 + BIT1; //设置I2C引脚
//P1SEL2|= BIT6 + BIT7;
UCB0CTL1 |= UCSWRST; //启用软件重置
UCB0CTL0 = UCMST + UCMODE_3 + UCWYNC;//I2C主控,同步模式
UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
UCB0BR0 = 10; //fSCL = SMCLK/11 =~100kHz
UCB0BR1 = 0;
UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
UCB0IE |= UCTXIE; //启用TX中断
UCB0IE |= UCRXIE; //启用RX中断
UCB0IE |= UCNACKIE; //需要启用状态更改中断
__enable_interrupit(); //启用全局中断
}


void i2c_tx (unsigned char slaver_addr,unsigned char *txdata,unsigned char bufSize,unsigned char addr_size,
unsigned char high byte_addr,unsigned char low byte_addr){
I2C_PACKGE.ISR_MODE=写入;
I2c_packet.data_buf=txdata;
I2c_packet.buf_size=bufSize;
I2c_packet.buf_index=0;
I2c_packet.addr_type=addr_size;
I2c_packet.addr_high字节=高字节地址;
I2c_packet.addr_low_byte=low_byte_addr;
I2c_packet.addr_index=0;
UCB0I2CSA = slaver_addr; //从属地址

而(1){
UCB0CTL1 || UCTR + UCTXSTT; // I2C TX,启动条件
LPM0; //输入LPM0
//并保留,直到所有数据都已发送
如果(i2c_packet.isR_mode == NOACK){//如果没有收到ACK,则休眠0.5毫秒并重试
I2C_PACKGE.ISR_MODE =写入;
I2c_packet.addr_index=0; //为下一个写入操作重置地址索引
usdelay(500);

} 否则{
中断; //写入成功,然后退出
}
}
}

/*
*此函数从任何I2C设备读取。 它将作为参数:
*-从属地址(7位)
*-指向数据缓冲区的指针,以填充读取的数据。
*-缓冲区的大小
*-开始写入的地址位置的大小。 某些EEPROM为2个字节,而单字节
*适用于其他设备。 请注意,此函数的ISR假定地址字节写得高
先是*字节,然后是低字节秒。
*如果是单字节地址设备,则只使用高位字节来设置地址。
*-开始读取位置的高字节和低字节地址。
*
*函数以写入操作开始,以指定带有start的读取操作的地址
*如果写入操作的启动条件不是ack (例如,EEPROM正忙于前一个写入周期),
*相应的中断会检测此情况,生成停止信号和计时器A1 (非计时器A0)
对于0.5 ms,*被激活,然后重复尝试写入。
*
*一旦写入地址成功,功能将切换到读取模式,并填充提供的缓冲区
*
*/


void i2c_rx(unsigned char slaver_addr, unsigned char *rxdata, unsigned char bufSize, unsigned char addr_size,
unsigned char high byte_addr,unsigned char low byte_addr){
I2C_PACKGE.ISR_MODE=读; // ISR将发送地址字节,然后唤醒CPU。
I2c_packet.addr_type=addr_size;
I2c_packet.addr_high字节=高字节地址;
I2c_packet.addr_low_byte=low_byte_addr;
I2c_packet.addr_index=0;
UCB0I2CSA = slaver_addr; //从属地址

而(1){
UCB0CTL1 || UCTR + UCTXSTT; // I2C TX,启动条件
LPM0; //输入LPM0
//并保留,直到所有数据都已发送
如果(i2c_packet.isR_mode == NOACK){//如果没有收到ACK,则休眠0.5毫秒并重试
I2C_PACKGE.ISR_MODE =读取;
I2c_packet.addr_index=0; //为下一个写入操作重置地址索引
usdelay(500);
} 否则{
中断; //写入成功,然后退出
}
}
//我们已经编写了地址,因此现在只读数据。
I2c_packet.addr_index=i2c_packet.addr_type;
I2c_packet.data_buf=rxdata;
I2c_packet.buf_size=bufSize;
I2c_packet.buf_index=0;
UCB0CTL1 &=~UCTR; // I2C RX
UCB0CTL1 || UCTXSTT; // I2C重新启动条件
LPM0; //输入LPM0
//并一直保留,直到收到所有数据
}


//interrupt (USCIAB0RX_vector)状态更改,从从实例

/*中捕获NO_Ack
*每次UCSI_B模块准备好在UCB0TXBUF中获取新字节以发送到I2C设备时,都会调用此中断。 或者
*将新字节读取到UCB0RXBUF中,我们应该将其拾取。
*当启用UCB0TXIE和UCB0RXIE时,调用中断。 要无限期停止调用此中断,应
清除相应的*中断标志。
*如果UCB0XXBUF是访问,则USI_B模块会自动清楚地显示这些标志。 但是,如果我们要执行的操作与读取
*或向UCB0XXBUF写入字节不同,我们需要自己清除相应的标志,否则ISR将被调用
*,整个程序将挂起。
*/


#pragma vector = USI_B0_Vector
__interrupt void USI_B0_ISR(void)
{
开关(__偶 数_IN_RANGE (UCB0IV,12))
{
案例10:
RXByteCtr --; // Decrement RX字节计数器
IF (RXByteCtr)
{
*PRxData++= UCB0RXBUF; //将RX数据移动到PRxData地址
IF (RXByteCtr == 1) //只剩下一个字节?
UCB0CTL1 || UCTXSTP; //生成I2C停止条件
}
否则
{
*PRxData = UCB0RXBUF; //将最终RX数据移至PRxData
__BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出活动CPU
}
案例12:
//无论发送或接收模式如何,发送地址字节均不受限制。*/
如果(i2c_packet.addr_index=0){
UCB0TXBUF = i2c_packet.addr_high字节;
I2c_packet.addr_index+;
}
否则,如果(i2c_packet.addr_index=1 && i2c_packet.addr_type=TWOBYTEADDR){
UCB0TXBUF = i2c_packet.addr_low_byte;
I2c_packet.addr_index+;
}
否则,如果(UCTXIFG & P2IFG && i2c_packet.ISR_MODE=read){
// USI_B已准备好获取新的数据字节来传输它,我们处于读取模式。
//因此,我们不应继续编写,而应退出调用函数
//将USI_B切换为读模式
P2IFG &=~UCTXIFG; //手动清除USI_B0 TX int标志,因为我们没有写入UCB0TXBUF
LPM0_EXIT; //退出LPM0
}

否则,如果(UCTXIFG & P2IFG && i2c_packet.ISR_MODE=WRITE){// USSCI_B准备获取新的数据字节以进行传输,并且我们处于写入模式。

IF (i2c_packet.buf_index == i2c_packet.buf_size){//如果没有更多数据要传输,则发出停止条件并唤醒CPU。
P2IFG &=~UCTXIFG; //手动清除USI_B0 TX int标志,因为我们没有写入UCB0TXBUF
UCB0CTL1 || UCTXSTP; // I2C停止条件
LPM0_EXIT; //退出LPM0
} 否则{
UCB0TXBUF = i2c_packet.data_buf[i2c_packet.buf_index];
I2c_packet.buf_index++; //增量TX字节计数
器}
}
否则,如果(UCRXIFG & P2IFG && i2c_packet.addr_index=i2c_packet.addr_type){
//读取模式,我们已经完成了地址的写入
I2c_packet.data_buf[i2c_packet.buf_index]= UCB0RXBUF;
I2c_packet.buf_index++; //增量RX字节计数器
IF (i2c_packet.buf_index == i2c_packet.buf_size){//如果接收最后一个字节,则发出停止条件并唤醒CPU。
P2IFG &=~UCRXIFG; //清除USI_B0 RX int标志
UCB0CTL1 || UCTXSTP; //此处的I2C停止条件是避免读取任何额外的字节
LPM0_EXIT; //退出LPM0
}
}/*

中断;
默认:
中断;
*/
}

}




//------------------
//微秒延迟
//
void usdelay (int interval){
//设置时间A
TA1CCTL0 = CCIE; //中断已启用
TA1CCR0 = TA1R +间隔;//微秒@ 1MHz时钟
TA1CTL = tassel_2 + MC_2;// SMCLK,连续模式。
LPM0; //暂停CPU
}

//计时器A1中断服务例程。 TIMERx_AY_VECTOR。(x是计时器的索引,y是此计时器的矢量)
#pragma vector=Timer1_A0_vector
__interrupt void Timer1_A0 (void)
{
TA1CTL = 0; //停止计时器_A1
LPM0_EXIT; //返回活动
}

//************************************************************************************************ //  MSP430 USCI I2C发送器和接收器//// 说明:此代码将MSP430的USCI模块配置为// I2C主控器,能够发送和接收字节。/// ***这是主代码***///           主//          MSP430F2619//        -------- //      /|\\|        Xin|-//      ||          |//      --|RST      XOUT|-//       |          |//       |          |//       |          |//       |      SDA/WFP 3.1 >//       |      SCL/WFP 3.2 (SCL/WFP设置)|----------- >///注:SDA和SCL///Uli Kretzschmar// Texas Instruments Deutschland GmbH// 2007年11月//使用IAR嵌入式工作台版本:3.42A/************************************************************************************************************************构建外部拉线 /*#包括"msp430f5529.h"             //器件特定标头//#include "msp430x22x4.h"//#include "msp430x23x0.h"//#include "msp430xG46x.h"/...                      //可以使用更多设备
#include "lib5529i2c.h"
signed char byteCtr;unsigned char *TI_receive字段;unsigned char *TI_transmit_field;int q=0;//------------------ // void TI_USI_I2C_receiveinit(unsigned char slaver_address,//                unsigned char prescale)////此函数初始化主接收操作的USCI模块。//// in:  unsigned char slaver_address  => Slave Address//    unsigned char prescale     => SCL时钟调整//------------------ void TI_USI_I2C_receiveinit(unsigned char slaver_address,                unsigned char prescale){ P3SEL || SDA_PIN + SCL_PIN;          //将I2C引脚分配给USI_B0 UCB0CTL1 = UCSWRST;             //启用软件重置 UCB0CTL0 = UMST + UCMODE_3 + UCSYNC;    // I2C主控,同步模式 UCB0CTL1 = UCSSEL_2 + UCSWRST;        //使用SMCLK,保持软件重置 UCB0BR0 =预分页;              // set prescaler UCB0BR1 = 0; UCB0I2CSA = slaver_address;          //设置从属地址 UCB0CTL1 &=~UCSWRST;             //清除软件重置,恢复操作 UCB0IE = UCNACKIE; UCB0IE = UCRXIE;               //启用RX中断}
//------------------ // void TI_USI_I2C_TRANSLINIT (unsigned char slaver_address,//                 unsigned char prescale)////此函数初始化主传输操作的USCI模块。//// in:  unsigned char slaver_address  => Slave Address//    unsigned char prescale     => SCL时钟调整//------------------ void TI_USI_I2C_TRANSLINIT (unsigned char slaver_address,              unsigned char prescale){ P3SEL || SDA_PIN + SCL_PIN;          //将I2C引脚分配给USI_B0 UCB0CTL1 |= UCSWRST;             //启用软件重置 UCB0CTL0 = UMST + UCMODE_3 + UCSYNC;    // I2C主控,同步模式 UCB0CTL1 = UCSSEL_2 + UCSWRST;        //使用SMCLK,保持软件重置 UCB0BR0 =预分页;              // set prescaler UCB0BR1 = 0; UCB0I2CSA = slaver_address;          //设置从属地址 UCB0CTL1 &=~UCSWRST;             //清除软件重置,恢复操作 UCB0IE = UCNACKIE; UCB0IE |= UCTXIE;               //启用TX就绪中断}
//------------------ // void TI_USI_I2C_RECEIVE(unsigned char byteCount, unsigned char *field)////此函数用于在主接收器模式下启动I2C通信。//// in:  unsigned char byteCount => 应该读取的字节数/    未签名的char *field   => 数组变量,用于存储接收的数据//------- void TI_USI_I2C_receive (unsigned char byteCount,unsigned char *field){ TI_receive_field = field; if ( byteCount ==1){  byteCtr =0;  __disable_interrupti();  UCB0CTL1 || UCTXSTT;            // I2C启动条件  while (UCB0CTL1和UCTXSTT);         //开始条件已发送?   UCB0CTL1 || UCTXSTP;            // I2C停止条件  __enable_interrupt(); }否则,如果( byteCount >1){  byteCtr = byteCount -2;  UCB0CTL1 |= UCTXSTT;            // I2C启动条件 }其他  ,同时(1);                 //非法参数}
//------------------ // void TI_USI_I2C_Transmit (unsigned char byteCount,unsigned char *field)////此函数用于在主传输模式下启动I2C通信。//// in:  unsigned char byteCount => 应传输的字节数//    unsigned char *field   => 数组变量。 它的内容将被发送。//------------------ void TI_USI_I2C_Transmit (unsigned char byteCount,unsigned char *field){ TI_Transmit_field = field; byteCtr = byteCount; UCB0CTL1 || UCTR + UCTXSTT;          // I2C TX,启动条件}
//------------------ // unsigned char TI_USI_I2C_SLAVE_Present (unsigned char slaver_address)////此函数用于查找I2C总线上的从属地址。//// in:  unsigned char slaver_address => SlaverAddress// out: unsigned char         => 0:未找到地址,//                     1:地址已找到//-------------------------------------------------- unsigned char TI_USCI_I2C_SLAVER_present (unsigned char slaver_address){ unsigned char IE2_bak,slaveadr_Bak,ucb0i2cie,returnValue; ucb0i2cie = UCB0IE;            //恢复旧的UCB0I2CIE IE2_BAK = UCB0IE;                // store IE2 register slaveadr_Bak = UCB0I2CSA;           //存储旧的从属地址 UCB0IE &=~ UCNACKIE;           // no nack interrupt UCB0I2CSA = slaver_address;          //设置从属地址 UCB0IE &=~(UCTXIE + UCRXIE);        // NO RX或TX中断 __disable_interrupt(); UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP;    // I2C TX,启动条件 while (UCB0CTL1和UCTXSTP);          //等待停止条件
 returnValue =!(UCB0STAT & UCNACKIFG); __enable_interrupt(); UCB0IE = IE2_BAK;                //恢复IE2 UCB0I2CSA = slaveadr_Bak;           //恢复旧的从属地址 UCB0IE = ucb0i2cie;            //恢复旧的UCB0CTL1 返回值;              //无论是否返回                        //发生了一个nack}
//------------------ // unsigned char TI_USI_I2C_NOREADY()///此函数用于检查是否正在进行通信。////输出: unsigned char => 0:I2C总线空闲,//              1:通信正在进行中//------------------ unsigned char TI_USSCI_I2C_NOREADY(){ Return (UCB0STAT & UCBBUSY);}

#pragma vector = USI_B0_vector__interrupt void USI_B0_ISR(void){  switch (__偶 数_in_range(UCB0IV, 12))     {
    案例10:       Q=10;//引导程序10:RXIFG --我还没有使用它(但我需要它)       IF (UCB0STAT和UCNACKIFG){       //如果从设备发送nack,则发送停止        UCB0CTL1 || UCTXSTP;        UCB0STAT &=~UCNACKIFG;      }       中断;     案例12:       Q=12;//矢量12:TXIFG       IF (P2IFG和UCRXIFG){           如果( byteCtr == 0){            UCB0CTL1 || UCTXSTP;           // I2C停止条件            *TI_RECETE_FIELD = UCB0RXBUF;            TI_Receive_field+;          }           否则{            *TI_RECETE_FIELD = UCB0RXBUF;            TI_Receive_field++;            byteCtr --;          }          }          否则{           如果(byteCtr ==0){            UCB0CTL1 || UCTXSTP;           // I2C停止条件            P2IFG &=~UCTXIFG;            //清除USI_B0 TX int标志          }           否则{            UCB0TXBUF =*TI_Transmit_field;            TI_Transmit_field++;            byteCtr --;          }          }       中断;     默认:       中断;
    }
  }

*/

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    团队,  

    对不起,我没有正确地附加上最后一个方法。 这里是:

    /*
    *以下是使用MSP430G2553对24LC512和DS3231 RTC进行读/写的示例。
    *提供两种读写功能。
    *
    *该代码避免了任何while循环,并完全依赖于MSP430的中断和低功耗模式,将功耗降低到
    *最低。
    *
    作者:Ahmed Talaat (aa_talaat@yahoo.com)
    *日期:2012年10月19日
    *
    
    包含"msp430f5529.h"
    
    #define ONEBYTEADDR 1.
    #define TWOBYTEADDR 2.
    #定义写入 0 // ISR模式写入或读取
    #定义读取 1.
    #define NOACK 二
    #define EEPROM_ADDR 0x40
    #define DS3231_ADDR 0x00
    
    unsigned char txdataeepro[2];
    unsigned char txdataDS3231[7]={0x20, 0x30, 0x20, 0x04, 0x17, 0x10,0x12};
    unsigned char rxdata[150];
    
    typedef结构{
    volatile unsigned char *data_buf; // TX或Rx数据缓冲区的地址
    volatile unsigned char buf_size; //缓冲区的大小
    volatile unsigned char buf_index; //缓冲区中的索引
    volatile unsigned char addr_index; //字节地址索引(0,1)
    volatile unsigned char ISR_MODE; // Tx或Rx影响中断逻辑
    要读/写的地址的volatile unsigned char addr_high字节;//高字节
    要读/写的地址的volatile unsigned char addr_low_bytes;//低字节
    volatile unsigned char addr_type; //两个字节(如EEPROM)或1个字节(如RTC
    )} I2C_t;
    
    I2c_t i2c_packet;
    
    void i2c_init(void);
    void i2c_tx (unsigned char,unsigned char *,unsigned char,unsigned char,unsigned char, unsigned char);
    void i2c_rx (unsigned char,unsigned char *,unsigned char,unsigned char,unsigned char, unsigned char);
    作废usdelay (int);
    
    Void主(void)
    {
    WDTCTL = WDTPW + WDTHOLD; //停止WDT
    I2C_INIT(); //初始化I2C
    txdataeeproem[0]=0x61;
    txdataeepro[1]=0x3F;
    
    I2C_TX (EEPROM_ADDR,txdataeeprom,sizeof(txdataeeprom)-1,ONEBYTEADDR,0x00,0x00);//i2c TX 115字节起始地址@ 01:00
    
    I2C_Rx (EEPROM_ADDR,rxdata,2,ONEBYTEADDR,0x00,0x00);//i2c从EEPROM起始值@地址01:00接收115字节
    
    
    LPM0; //输入LPM0 w/ interrupts
    }
    
    void i2c_init(void){
    P3SEL || BIT0 + BIT1; //设置I2C引脚
    //P1SEL2|= BIT6 + BIT7;
    UCB0CTL1 |= UCSWRST; //启用软件重置
    UCB0CTL0 = UCMST + UCMODE_3 + UCWYNC;//I2C主控,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
    UCB0BR0 = 10; //fSCL = SMCLK/11 =~100kHz
    UCB0BR1 = 0;
    UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
    UCB0IE |= UCTXIE; //启用TX中断
    UCB0IE |= UCRXIE; //启用RX中断
    UCB0IE |= UCNACKIE; //需要启用状态更改中断
    __enable_interrupit(); //启用全局中断
    }
    
    
    void i2c_tx (unsigned char slaver_addr,unsigned char *txdata,unsigned char bufSize,unsigned char addr_size,
    unsigned char high byte_addr,unsigned char low byte_addr){
    I2C_PACKGE.ISR_MODE=写入;
    I2c_packet.data_buf=txdata;
    I2c_packet.buf_size=bufSize;
    I2c_packet.buf_index=0;
    I2c_packet.addr_type=addr_size;
    I2c_packet.addr_high字节=高字节地址;
    I2c_packet.addr_low_byte=low_byte_addr;
    I2c_packet.addr_index=0;
    UCB0I2CSA = slaver_addr; //从属地址
    
    而(1){
    UCB0CTL1 || UCTR + UCTXSTT; // I2C TX,启动条件
    LPM0; //输入LPM0
    //并保留,直到所有数据都已发送
    如果(i2c_packet.isR_mode == NOACK){//如果没有收到ACK,则休眠0.5毫秒并重试
    I2C_PACKGE.ISR_MODE =写入;
    I2c_packet.addr_index=0; //为下一个写入操作重置地址索引
    usdelay(500);
    
    } 否则{
    中断; //写入成功,然后退出
    }
    }
    }
    
    /*
    *此函数从任何I2C设备读取。 它将作为参数:
    *-从属地址(7位)
    *-指向数据缓冲区的指针,以填充读取的数据。
    *-缓冲区的大小
    *-开始写入的地址位置的大小。 某些EEPROM为2个字节,而单字节
    *适用于其他设备。 请注意,此函数的ISR假定地址字节写得高
    先是*字节,然后是低字节秒。
    *如果是单字节地址设备,则只使用高位字节来设置地址。
    *-开始读取位置的高字节和低字节地址。
    *
    *函数以写入操作开始,以指定带有start的读取操作的地址
    *如果写入操作的启动条件不是ack (例如,EEPROM正忙于前一个写入周期),
    *相应的中断会检测此情况,生成停止信号和计时器A1 (非计时器A0)
    对于0.5 ms,*被激活,然后重复尝试写入。
    *
    *一旦写入地址成功,功能将切换到读取模式,并填充提供的缓冲区
    *
    */
    
    
    void i2c_rx(unsigned char slaver_addr, unsigned char *rxdata, unsigned char bufSize, unsigned char addr_size,
    unsigned char high byte_addr,unsigned char low byte_addr){
    I2C_PACKGE.ISR_MODE=读; // ISR将发送地址字节,然后唤醒CPU。
    I2c_packet.addr_type=addr_size;
    I2c_packet.addr_high字节=高字节地址;
    I2c_packet.addr_low_byte=low_byte_addr;
    I2c_packet.addr_index=0;
    UCB0I2CSA = slaver_addr; //从属地址
    
    而(1){
    UCB0CTL1 || UCTR + UCTXSTT; // I2C TX,启动条件
    LPM0; //输入LPM0
    //并保留,直到所有数据都已发送
    如果(i2c_packet.isR_mode == NOACK){//如果没有收到ACK,则休眠0.5毫秒并重试
    I2C_PACKGE.ISR_MODE =读取;
    I2c_packet.addr_index=0; //为下一个写入操作重置地址索引
    usdelay(500);
    } 否则{
    中断; //写入成功,然后退出
    }
    }
    //我们已经编写了地址,因此现在只读数据。
    I2c_packet.addr_index=i2c_packet.addr_type;
    I2c_packet.data_buf=rxdata;
    I2c_packet.buf_size=bufSize;
    I2c_packet.buf_index=0;
    UCB0CTL1 &=~UCTR; // I2C RX
    UCB0CTL1 || UCTXSTT; // I2C重新启动条件
    LPM0; //输入LPM0
    //并一直保留,直到收到所有数据
    }
    
    
    //interrupt (USCIAB0RX_vector)状态更改,从从实例
    
    /*中捕获NO_Ack
    *每次UCSI_B模块准备好在UCB0TXBUF中获取新字节以发送到I2C设备时,都会调用此中断。 或者
    *将新字节读取到UCB0RXBUF中,我们应该将其拾取。
    *当启用UCB0TXIE和UCB0RXIE时,调用中断。 要无限期停止调用此中断,应
    清除相应的*中断标志。
    *如果UCB0XXBUF是访问,则USI_B模块会自动清楚地显示这些标志。 但是,如果我们要执行的操作与读取
    *或向UCB0XXBUF写入字节不同,我们需要自己清除相应的标志,否则ISR将被调用
    *,整个程序将挂起。
    */
    
    
    #pragma vector = USI_B0_Vector
    __interrupt void USI_B0_ISR(void)
    {
    开关(__偶 数_IN_RANGE (UCB0IV,12))
    {
    案例10:
    RXByteCtr --; // Decrement RX字节计数器
    IF (RXByteCtr)
    {
    *PRxData++= UCB0RXBUF; //将RX数据移动到PRxData地址
    IF (RXByteCtr == 1) //只剩下一个字节?
    UCB0CTL1 || UCTXSTP; //生成I2C停止条件
    }
    否则
    {
    *PRxData = UCB0RXBUF; //将最终RX数据移至PRxData
    __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出活动CPU
    }
    案例12:
    //无论发送或接收模式如何,发送地址字节均不受限制。*/
    如果(i2c_packet.addr_index=0){
    UCB0TXBUF = i2c_packet.addr_high字节;
    I2c_packet.addr_index+;
    }
    否则,如果(i2c_packet.addr_index=1 && i2c_packet.addr_type=TWOBYTEADDR){
    UCB0TXBUF = i2c_packet.addr_low_byte;
    I2c_packet.addr_index+;
    }
    否则,如果(UCTXIFG & P2IFG && i2c_packet.ISR_MODE=read){
    // USI_B已准备好获取新的数据字节来传输它,我们处于读取模式。
    //因此,我们不应继续编写,而应退出调用函数
    //将USI_B切换为读模式
    P2IFG &=~UCTXIFG; //手动清除USI_B0 TX int标志,因为我们没有写入UCB0TXBUF
    LPM0_EXIT; //退出LPM0
    }
    
    否则,如果(UCTXIFG & P2IFG && i2c_packet.ISR_MODE=WRITE){// USSCI_B准备获取新的数据字节以进行传输,并且我们处于写入模式。
    
    IF (i2c_packet.buf_index == i2c_packet.buf_size){//如果没有更多数据要传输,则发出停止条件并唤醒CPU。
    P2IFG &=~UCTXIFG; //手动清除USI_B0 TX int标志,因为我们没有写入UCB0TXBUF
    UCB0CTL1 || UCTXSTP; // I2C停止条件
    LPM0_EXIT; //退出LPM0
    } 否则{
    UCB0TXBUF = i2c_packet.data_buf[i2c_packet.buf_index];
    I2c_packet.buf_index++; //增量TX字节计数
    器}
    }
    否则,如果(UCRXIFG & P2IFG && i2c_packet.addr_index=i2c_packet.addr_type){
    //读取模式,我们已经完成了地址的写入
    I2c_packet.data_buf[i2c_packet.buf_index]= UCB0RXBUF;
    I2c_packet.buf_index++; //增量RX字节计数器
    IF (i2c_packet.buf_index == i2c_packet.buf_size){//如果接收最后一个字节,则发出停止条件并唤醒CPU。
    P2IFG &=~UCRXIFG; //清除USI_B0 RX int标志
    UCB0CTL1 || UCTXSTP; //此处的I2C停止条件是避免读取任何额外的字节
    LPM0_EXIT; //退出LPM0
    }
    }/*
    
    中断;
    默认:
    中断;
    */
    }
    
    }
    
    
    
    
    //------------------
    //微秒延迟
    //
    void usdelay (int interval){
    //设置时间A
    TA1CCTL0 = CCIE; //中断已启用
    TA1CCR0 = TA1R +间隔;//微秒@ 1MHz时钟
    TA1CTL = tassel_2 + MC_2;// SMCLK,连续模式。
    LPM0; //暂停CPU
    }
    
    //计时器A1中断服务例程。 TIMERx_AY_VECTOR。(x是计时器的索引,y是此计时器的矢量)
    #pragma vector=Timer1_A0_vector
    __interrupt void Timer1_A0 (void)
    {
    TA1CTL = 0; //停止计时器_A1
    LPM0_EXIT; //返回活动
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,

    很抱歉,但是这个代码太多了,我看不了:)

    您为什么不在"资源管理器"中举例? 对我来说,它们似乎更容易。

    或者你可以尝试用ENERGIA来做。

    我通常会将写作示例与阅读示例合并。

    这是MSP430F55xx_uscib0_i2c_08.c的代码:

    /*--版权--,BSD_EX
    *版权所有(c) 2012,Texas Instruments Incorporated
    *保留所有权利。
    *
    **
    允许以源代码和二进制格式重新发布和使用,无论是否进行*修改,只要
    满足以下条件*:
    *
    ****重新发布源代码必须保留上述版权
    *声明,此条件列表和以下免责声明。
    *
    ***以二进制格式重新分发时,必须在
    
    随分发提供的*文档和/或其他材料中复制上述版权*声明,此条件列表和以下免责声明。
    *
    ***
    
    未经事先书面许可,不得使用德州仪器(TI)公司的名称或*其贡献者的名称来支持或促销由本软件衍生的产品*。
    *
    *本软件由版权所有者和贡献者"按原样"提供
    *,
    
    不提供任何明示或暗示的担保,包括但不限于*对适销性和特定*用途适用性的暗示担保。 在任何情况下,版权所有者或
    *贡献者均不对任何直接,间接,附带,特殊,
    *示范, 或后果性损害(包括但不限于
    *购买替代商品或服务;使用,数据或利润损失;
    (*或业务中断),但根据任何责任理论
    ,*无论是合同,严格责任还是侵权行为(包括疏忽或
    *其他),均因使用本软件而导致*
    ,即使已被告知此类损害的可能性。
    *
    ******************
    *
    ** MSP430代码示例免责声明
    *
    MSP430代码示例是独立的低级程序
    ,通常*以高度
    *简洁的方式演示单个外设功能或器件功能。 因此,代码可能依赖于设备的开机默认
    值*寄存器值和设置(如时钟配置),
    在合并多个示例中的代码时必须*小心,以避免潜在的副作用
    *。 另请参阅www.ti.com/grace了解GUI,并参阅www.ti.com/msp430ware
    *了解外围设备配置的API功能库方法。
    *
    **--/copyright--*//************************************************************************************************************************
    
    // MSP430F552x演示- USI_B0 I2C主TX多字节到MSP430从属
    //
    描述:此演示通过I2C总线连接两个MSP430。 主
    //传输到从属设备。 这是主代码。 它以Cntinuuse//
    方式传输一组数据,并演示如何实现I2C
    //主发送器使用USI_B0 TX中断发送多个字节。
    // aclk = n/a,MCLK = SMCLK = BRCLK =默认DCO =~1.045MHz
    ///
    ***与“MSP430F55xx_uscib0_i2c_09.c”***
    //
    一起使用 /|\/|\
    // MSP430F5529 10公里10公里 MSP430F5529
    // 从属 || 母版
    // -------- ||--------------------
    // -|Xin 3.0 (新局)/UCB0SDA|<-|!--++->|WFP (局) 3.0 (局)/UCB0SDA Xin|-//
    | || | |//
    -|XOUT || | XOUT|-
    // | WFP 3.1 / UCB.S.|<-++--- >>|WFP 3.1 / UCB.S. |//
    | | | |////
    
    Bhargavi Nisarga
    //德州仪器(TI)
    // 2009年4月
    //使用CCSv4和IAR嵌入式工作台构建版本:4.21
    //**********************************************************************************************
    
    #include <MSP430-h>
    
    unsigned char *PTxData; //指向TX数据
    的指针unsigned char TXByteCtr;
    
    const unsigned char TxData[]= //要传输
    的数据表{0x11,
    
    0x22,
    0x33,
    0x44,
    0x55};
    
    
    int main (void){
    
    unsigned int I;
    
    WDTCTL = WDTPW + WDTHOLD; //停止WDT
    P3SEL |= 0x03; //将I2C引脚分配给USI_B0
    UCB0CTL1 |= UCSWRST; //启用软件重置
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C主控,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSSWRST; //使用SMCLK,保持软件重置
    UCB0BR0 =12; // fSCL = SMCLK/12 =~100kHz
    UCB0BR1 = 0;
    UCB0I2CSA = 0x48; //从属地址为048h
    UCB0CTL1 &=~UCSWRST; //清除软件重置,恢复操作
    UCB0IE || UCTXIE; //启用TX中断
    
    ,同时(1){
    
    对于(i=0;i<10;i++); //交易之间需要延迟
    PTxData =(unsigned char *)TxData; // TX阵列起始地址
    //在此处放置断点以查看每个断点
    //传输操作。
    TXByteCtr = TxData的大小; //加载TX字节计数器
    
    UCB0CTL1 || UCTR + UCTXSTT; // I2C TX,启动条件
    
    __bis_sr_register (LPM0_bits + GIE); //输入LPM0,启用中断
    __no_operation(); //保留在LPM0中,直到所有数据
    //已发送
    同时(UCB0CTL1和UCTXSTP); //确保已发送停止条件
    }//------------------
    
    
    
    // USCIAB0TX_ISR的结构使其可以通过
    预加载具有字节计数的TXByteCtr来传输任何//字节数。 此外,TXData
    //指向要传输的下一个字节。
    //------------------
    #if defined(__TI_Compiler_version__)|| defined(__IAR_SYSTEMS _ICC__)
    #pragma vector = USI_B0_vector
    __interrupt void USI_B0_ISR(void)
    #Elif defined(__GISR__)
    void __attribute__(interrupt (USCI_B0_vector))#USI_void
    
    
    #endif
    {
    SWITCH(__EIN_RANGE(UCB0IV,12)){
    
    案例0:中断; //矢量0:无中断
    案例2:中断; //矢量2:ALIFG
    案例4:中断; //矢量4:NACKIFG
    案例6:中断; //向量6:STTIFG
    案例8:中断; //矢量8:STPIFG
    案例10:中断; //矢量10:RXIFG
    案例12: //矢量12:TXIFG
    IF (TXByteCtr) //检查TX字节计数器
    {
    UCB0TXBUF =* PTxData++; //加载TX缓冲区
    TXByteCtr // Decrement TX字节计数
    器}
    否则
    {
    UCB0CTL1 || UCTXSTP; // I2C停止条件
    UCB0IFG &=~UCTXIFG; //清除USI_B0 TX int标志
    __BIC_SR_REGISTER_ON_EXIT (LPM0_bits);//退出LPM0
    }
    默认值:break;
    }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好Luke:

    通常,发布大量代码,期望社区对其进行审查并不是一种好的做法。 相反,我建议将您的较大问题分解为更小,更易于管理的问题,这些问题更容易提供有针对性的反馈并从我们的社区中获得反馈。

    正如kazola 正确指出的那样,我们在资源管理器中的代码示例是编码方面的最佳起点。 我们推荐的另一个起点是 MSP430TmMCU上常见eUSCI和USCI串行通信问题解决方案 应用手册(参见第5节)。 此外,在使用I2C时,应该需要一个逻辑分析仪,因为它将向您显示传输和不传输的确切内容。

    希望这有助于您的发展!

    此致,

    詹姆斯

    MSP客户应用程序