i2c通信 msp430g2553_430 G2553 LAUNCHPAD 简单I2C通信,用TI官方的 using IIC MASTER(slaa382) 代码,改从器件地址后总是悬在while (...

使用TI官方的USCI I2C Master代码在MSP430G2553 LAUNCHPAD上进行简单I2C通信时遇到问题,修改从设备地址后,在`while (UCB0CTL1 & UCTXSTP)`处挂起,无法继续通信。尝试添加上下拉电阻并设置时钟输出,但问题依然存在。尽管外部BQ27441电源板与智能电源I2C开发板EV2300通信正常,表明从设备I2C功能正常,但与LAUNCHPAD的通信无法建立。
摘要由CSDN通过智能技术生成

430 G2553 LAUNCHPAD 简单I2C通信,用TI官方的 using IIC MASTER(slaa382) 代码,改从器件地址后总是悬在while (UCB0CTL1 & UCTXSTP)语句过不去。

详细是这样的:

用430 G2553 LAUNCHPAD作简单I2C通信和BQ27441电源板通信。认真读了几百页的SLAU44J(2553用户手册)。认真读了飞利浦I2C协议原版(为理清基本概念)。用http://www.ti.com/general/docs/litabsmultiplefilelist.tsp?&literatureNumber=slaa382   中的标准官方代码,仅仅改动了头文件包含 为 2553,

I2C从器件地址55(7位地址,未加读写控制位) ,引脚从P3改P1,避开加LED的p1.6,用1.4和1.7管脚当 SLC 和 sda。

/*** USCI master library ************************************************************

In this file the usage of the USCI I2C master library without DMA support is

shown. This library uses pointers to specify what data is to be sent.

When calling the TI_USCI_I2C_receive or TI_USCI_I2C_transmit routines

the number of bytes, which are to be transmitted or received have to be passed as

well as a pointer to a data field, that contains(or stores) the data.

This code checks if there is a slave with address 0x50 is connected to the I2C

bus and if the slave device is present, bytes are received and transmitted.

Uli Kretzschmar

MSP430 Systems

Freising

*******************************************************************************/

#include

#include "TI_USCI_I2C_master.h"

unsigned char timercounter;

unsigned char array[40] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb };

unsigned char store[40] = { 13, 13, 13, 13, 13, 13, 13, 0, 0, 0};

void main(void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

BCSCTL1 = CALBC1_1MHZ;

DCOCTL = CALDCO_1MHZ;

_EINT();

TI_USCI_I2C_transmitinit(0x55,0x40); // init transmitting with USCI

while ( TI_USCI_I2C_notready() ); // wait for bus to be free

if ( TI_USCI_I2C_slave_present(0x55) ) // slave address may differ from initialization

{

TI_USCI_I2C_receiveinit(0x55,0x40); // init receiving with USCI

while ( TI_USCI_I2C_notready() ); // wait for bus to be free

TI_USCI_I2C_receive(1,store);

while ( TI_USCI_I2C_notready() ); // wait for bus to be free

TI_USCI_I2C_transmitinit(0x55,0x40); // init transmitting with

while ( TI_USCI_I2C_notready() ); // wait for bus to be free

TI_USCI_I2C_transmit(4,array); // start transmitting

}

LPM3;

}

下面是TI_USCI_I2C_master.h头文件

#ifndef USCI_LIB

#define USCI_LIB

#define SDA_PIN BIT7 // msp430x261x UCB0SDA pin

#define SCL_PIN BIT4 // msp430x261x UCB0SCL pin

void TI_USCI_I2C_receiveinit(unsigned char slave_address, unsigned char prescale);

void TI_USCI_I2C_transmitinit(unsigned char slave_address, unsigned char prescale);

void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field);

void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field);

unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address);

unsigned char TI_USCI_I2C_notready();

#endif

下面是 :TI_USCI_I2C_master.c

//******************************************************************************

// MSP430 USCI I2C Transmitter and Receiver

//

// Description: This code configures the MSP430's USCI module as

// I2C master capable of transmitting and receiving bytes.

//

// ***THIS IS THE MASTER CODE***

//

// Master

// MSP430F2619

// -----------------

// /|\| XIN|-

// | | |

// --|RST XOUT|-

// | |

// | |

// | |

// | SDA/P1.1|------->

// | SCL/P1.2|------->

//

// Note: External pull-ups are needed for SDA & SCL

//

// Uli Kretzschmar

// Texas Instruments Deutschland GmbH

// November 2007

// Built with IAR Embedded Workbench Version: 3.42A

//******************************************************************************

#include // device specific header

//#include "msp430x22x4.h"

//#include "msp430x23x0.h"

//#include "msp430xG46x.h"

// ... // more devices are possible

#include "TI_USCI_I2C_master.h"

signed char byteCtr;

unsigned char *TI_receive_field;

unsigned char *TI_transmit_field;

//------------------------------------------------------------------------------

// void TI_USCI_I2C_receiveinit(unsigned char slave_address,

// unsigned char prescale)

//

// This function initializes the USCI module for master-receive operation.

//

// IN: unsigned char slave_address => Slave Address

// unsigned char prescale => SCL clock adjustment

//-----------------------------------------------------------------------------

void TI_USCI_I2C_receiveinit(unsigned char slave_address,

unsigned char prescale){

P1SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0

UCB0CTL1 = UCSWRST; // Enable SW reset

UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode

UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset

UCB0BR0 = prescale; // set prescaler

UCB0BR1 = 0;

UCB0I2CSA = slave_address; // set slave address

UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation

UCB0I2CIE = UCNACKIE;

IE2 = UCB0RXIE; // Enable RX interrupt

}

//------------------------------------------------------------------------------

// void TI_USCI_I2C_transmitinit(unsigned char slave_address,

// unsigned char prescale)

//

// This function initializes the USCI module for master-transmit operation.

//

// IN: unsigned char slave_address => Slave Address

// unsigned char prescale => SCL clock adjustment

//------------------------------------------------------------------------------

void TI_USCI_I2C_transmitinit(unsigned char slave_address,

unsigned char prescale){

P1SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0

UCB0CTL1 = UCSWRST; // Enable SW reset

UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode

UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset

UCB0BR0 = prescale; // set prescaler

UCB0BR1 = 0;

UCB0I2CSA = slave_address; // Set slave address

UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation

UCB0I2CIE = UCNACKIE;

IE2 = UCB0TXIE; // Enable TX ready interrupt

}

//------------------------------------------------------------------------------

// void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field)

//

// This function is used to start an I2C commuincation in master-receiver mode.

//

// IN: unsigned char byteCount => number of bytes that should be read

// unsigned char *field => array variable used to store received data

//------------------------------------------------------------------------------

void TI_USCI_I2C_receive(unsigned char byteCount, unsigned char *field){

TI_receive_field = field;

if ( byteCount == 1 ){

byteCtr = 0 ;

__disable_interrupt();

UCB0CTL1 |= UCTXSTT; // I2C start condition

while (UCB0CTL1 & UCTXSTT); // Start condition sent?

UCB0CTL1 |= UCTXSTP; // I2C stop condition

__enable_interrupt();

} else if ( byteCount > 1 ) {

byteCtr = byteCount - 2 ;

UCB0CTL1 |= UCTXSTT; // I2C start condition

} else

while (1); // illegal parameter

}

//------------------------------------------------------------------------------

// void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field)

//

// This function is used to start an I2C commuincation in master-transmit mode.

//

// IN: unsigned char byteCount => number of bytes that should be transmitted

// unsigned char *field => array variable. Its content will be sent.

//------------------------------------------------------------------------------

void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field){

TI_transmit_field = field;

byteCtr = byteCount;

UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition

}

//------------------------------------------------------------------------------

// unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address)

//

// This function is used to look for a slave address on the I2C bus.

//

// IN: unsigned char slave_address => Slave Address

// OUT: unsigned char => 0: address was not found,

// 1: address found

//------------------------------------------------------------------------------

unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address)

{

unsigned char ie2_bak, slaveadr_bak, ucb0i2cie, returnValue;

ucb0i2cie = UCB0I2CIE; // store old UCB0I2CIE

ie2_bak = IE2; // store IE2 register

slaveadr_bak = UCB0I2CSA; // store old slave address

UCB0I2CIE &= ~ UCNACKIE; // no NACK interrupt

UCB0I2CSA = slave_address; // set slave address

IE2 &= ~(UCB0TXIE + UCB0RXIE); // no RX or TX interrupts

__disable_interrupt();

UCB0CTL1 |= UCTR + UCTXSTT +UCTXSTP; // I2C TX, start condition

while (UCB0CTL1 & UCTXSTP); // wait for STOP condition

returnValue = !(UCB0STAT & UCNACKIFG);

__enable_interrupt();

IE2 = ie2_bak; // restore IE2

UCB0I2CSA = slaveadr_bak; // restore old slave address

UCB0I2CIE = ucb0i2cie; // restore old UCB0CTL1

return returnValue; // return whether or not

// a NACK occured

}

//------------------------------------------------------------------------------

// unsigned char TI_USCI_I2C_notready()

//

// This function is used to check if there is commuincation in progress.

//

// OUT: unsigned char => 0: I2C bus is idle,

// 1: communication is in progress

//------------------------------------------------------------------------------

unsigned char TI_USCI_I2C_notready(){

return (UCB0STAT & UCBBUSY);

}

#pragma vector = USCIAB0RX_VECTOR

__interrupt void USCIAB0RX_ISR(void)

{

if (UCB0STAT & UCNACKIFG){ // send STOP if slave sends NACK

UCB0CTL1 |= UCTXSTP;

UCB0STAT &= ~UCNACKIFG;

}

}

#pragma vector = USCIAB0TX_VECTOR

__interrupt void USCIAB0TX_ISR(void)

{

if (IFG2 & UCB0RXIFG){

if ( byteCtr == 0 ){

UCB0CTL1 |= UCTXSTP; // I2C stop condition

*TI_receive_field = UCB0RXBUF;

TI_receive_field++;

}

else {

*TI_receive_field = UCB0RXBUF;

TI_receive_field++;

byteCtr--;

}

}

else {

if (byteCtr == 0){

UCB0CTL1 |= UCTXSTP; // I2C stop condition

IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag

}

else {

UCB0TXBUF = *TI_transmit_field;

TI_transmit_field++;

byteCtr--;

}

}

}

总是走到TI_USCI_I2C_master.c的unsigned char TI_USCI_I2C_slave_present(unsigned char slave_address)函数中

while (UCB0CTL1 & UCTXSTP);  语句死循环,查看watch是UCB0CTL1寄存器的UCTXSTP不清零,就是stop信号没发出去。

量 SCL SDA无电压,后加语句

P1REN|=0xFF;(目的是将P1口所有加上上下拉电阻)

P1DIR|=BIT4;(这句加上或者不加应该影响不大,目的是将时钟设为输出)

后,量SCL SDA均有3.5v电压。无示波器,对不起大家。

按理说官方例程不会有错误的,只能是我没调好,但就是卡在那一句while (UCB0CTL1 & UCTXSTP);

外部器件BQ27441板接智能电源I2C开发板EV2300良好,说明外部器件I2C工作正常,可为什么就是不能与我的LAUNCHPAD通讯呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值