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.
想用G2553 写SMBus控制bq78350,但iic无反应。
使用官方iic例程,iic信号线是高电平,数据线是低电平。在线仿真代码死循环在
while (UCB0CTL1 & UCTXSTT); // Start condition sent?
请问什么原因呢?
两块G2553 一主一从IIC通信也是死循环在上面那条语句中。
bq78350作为Master 还是slave呢?usrs guide写的是Master 但是用示波器测scl线一直是低电平。TI官方有没有对bq78350SMBus示例代码?
你好,
给你一个IIC设备的例程程序,希望对你有帮助。
#include "msp430f2132.h"
#include "TI_USCI_I2C_multi.h"
void (*I2C_Rx_callback)();
void (*I2C_Tx_callback)();
void (*I2C_Start_callback)();
extern volatile unsigned char *I2C_Master_TxBuf;
extern volatile unsigned char I2C_Master_TxCtr;
extern volatile unsigned char *I2C_Master_RxBuf;
extern volatile unsigned char I2C_Master_RxCtr;
extern volatile unsigned char I2C_Master_Abort;
extern volatile unsigned char I2C_Master_TxComplete;
extern volatile unsigned char I2C_Exit_LPM;
/*------------------------------------------------------------------------------*
* This function initializes the USCI module for I2C Slave operation. *
* *
* IN: void (*SCallback)() => function is called when a START condition was *
* detected *
* void (*TCallback)(unsigned char volatile *value) => function is called *
* for every byte requested by master *
* void (*RCallback)(unsigned char value) => function is called for every *
* byte that is received *
* unsigned char slave_address => Slave Address *
*------------------------------------------------------------------------------*/
void TI_USCI_I2C_slaveinit(void (*SCallback)(),
void (*TCallback)(),
void (*RCallback)(),
unsigned char slave_address)
{
P3SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode
UCB0I2COA = slave_address; // set own (slave) address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0TXIE + UCB0RXIE; // Enable TX interrupt
UCB0I2CIE |= UCSTTIE; // Enable STT interrupt
I2C_Start_callback = SCallback;
I2C_Rx_callback = RCallback;
I2C_Tx_callback = TCallback;
}
/*
void I2C_multi_init(unsigned char master,
unsigned char my_own_addr,
unsigned char prescale,
void (*SCallback)(),
void (*TCallback)(unsigned char volatile *value),
void (*RCallback)(unsigned char value) )
{
P3SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0
UCB0CTL1 = UCSWRST;
if (master) // Enable SW reset
UCB0CTL0 = UCMST + UCMM + UCMODE_3 + UCSYNC; // Start as master, synchronous mode
else
UCB0CTL0 = UCMODE_3 + UCSYNC; // Start as slave, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = prescale; // set prescaler
UCB0BR1 = 0;
UCB0I2COA = my_own_addr; // set own (slave) address
// UCB0I2CSA = slave_address; // set slave address
I2C_Start_callback = SCallback;
I2C_Rx_callback = RCallback;
I2C_Tx_callback = TCallback;
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
if (master) // Enable SW reset
UCB0I2CIE = UCSTTIE + UCNACKIE;
else
UCB0I2CIE = UCSTTIE;
IE2 = UCB0TXIE + UCB0RXIE; // Enable TX interrupt
}
*/
void I2C_multi_init(unsigned char my_own_addr,
unsigned char prescale,
void (*SCallback)(),
void (*TCallback)(),
void (*RCallback)() )
{
UCB0CTL1 = UCSWRST;
UCB0I2CIE = 0;
UCB0STAT = 0;
IE2 &= ~UCB0TXIE;
IE2 &= ~UCB0RXIE;
IFG2 &= ~UCB0TXIFG;
IFG2 &= ~UCB0RXIFG;
P3SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0
UCB0CTL0 = UCMODE_3 + UCSYNC; // Start as slave, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = prescale; // set prescaler
UCB0BR1 = 0;
UCB0I2COA = my_own_addr; // set own (slave) address
I2C_Start_callback = SCallback;
I2C_Rx_callback = RCallback;
I2C_Tx_callback = TCallback;
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
}
void I2C_multi_slave(void)
{
UCB0CTL1 |= UCSWRST;
UCB0CTL0 = UCMODE_3 + UCSYNC; // Start as slave, synchronous mode
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0I2CIE = UCSTTIE;
IE2 = UCB0TXIE + UCB0RXIE; // Enable TX interrupt
}
void I2C_multi_master(void)
{
UCB0CTL1 |= UCSWRST;
UCB0CTL0 = UCMST + UCMM + UCMODE_3 + UCSYNC; // Start as master, synchronous mode
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
//IFG2 &= ~UCB0TXIFG;
UCB0I2CIE = UCALIE + UCNACKIE + UCSTTIE;
IE2 = UCB0TXIE + UCB0RXIE; // Enable TX 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)
{
P3SEL |= 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
}
*/
void I2C_Master_Transmit(unsigned char slave_addr, unsigned char byteCount, unsigned char *buffer)
{
I2C_Master_TxBuf = buffer;
I2C_Master_TxCtr = byteCount;
UCB0I2CSA = slave_addr; // Set slave address
//UCB0CTL0 |= UCMST + UCMM; // I2C Master, multi-master
//__disable_interrupt();
//I2C_Tx_Complete = 0x00;
//I2C_Master_TxComplete=0x00;
//__enable_interrupt();
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
}
void I2C_Master_Receive(unsigned char slave_addr, unsigned char byteCount, unsigned char *buffer)
{
I2C_Master_RxBuf = buffer;
UCB0I2CSA = slave_addr; // Set slave address
UCB0CTL1 &= ~UCTR;
//UCB0CTL0 |= UCMST + UCMM; // I2C Master, multi-master
I2C_Master_RxCtr = byteCount;
if ( byteCount == 1 )
{
__disable_interrupt();
UCB0CTL1 |= UCTXSTT; // I2C start condition
while (UCB0CTL1 & UCTXSTT); // Start condition sent?
UCB0CTL1 |= UCTXSTP; // I2C stop condition
__enable_interrupt();
}
else if ( byteCount > 1 )
{
UCB0CTL1 |= UCTXSTT; // I2C start condition
}
else
while (1);
}
/*-----------------------------------------------*
* USCI_B0 Data ISR *
*-----------------------------------------------*/
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if (IFG2 & UCB0TXIFG)
I2C_Tx_callback();
else if (IFG2 & UCB0RXIFG)
I2C_Rx_callback();
if (I2C_Exit_LPM)
LPM4_EXIT;
}
/*-----------------------------------------------*
* USCI_B0 State ISR *
*-----------------------------------------------*/
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
if (UCB0STAT & UCALIFG) {
I2C_Master_Abort |= 0x01;
UCB0STAT &= ~UCALIFG;
}
if (UCB0STAT & UCNACKIFG){ // send STOP if slave sends NACK
I2C_Master_Abort |= 0x01;
UCB0CTL1 |= UCTXSTP;
UCB0STAT &= ~UCNACKIFG;
IFG2 &= ~UCB0TXIFG;
}
if (UCB0STAT & (UCSTTIFG)){ // Start condition received
I2C_Start_callback();
UCB0STAT &= ~UCSTTIFG; // Clear start condition int flag
}
}
你需要移植到你的平台。