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.

[参考译文] MSP430FR2355:MSP430FR2355

Guru**** 2344390 points
Other Parts Discussed in Thread: MSP-TS430PT48, MSP430FR2355, BQ76940
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1073398/msp430fr2355-msp430fr2355

部件号:MSP430FR2355
“线程”中讨论的其它部件:MSP-TS430PT48BQ76940

你(们)好

我们正在将 MSP-ts430pt48与 MCU MSP430FR2355配合使用。

另一端是 bq76940 EVM。

两个 EVM 使用 i2c 通过外部线进行互连。

 在 MSP-ts430pt48上,它使用 p4.6和 p4.7执行 i2c ping。  

我移植一个样本程序,并在 MSP430FR2355发送的第一个数据上阻止它。

它在 I2CSendBytes()函数行226中保持循环

=========================================================

HWREG16 (基址+ OFS_UCBxCTLW0)|= UCTR + UCTXSTT;

While (!(HWREG16 (基址+ OFS_UCBxIFG)和 UCTXIFG))

=========================================================

我检查了 UCBxIE,它都打开了,所有的寄存器值对我都是有意义的。

不确定为什么标志总是0

请给出建议

谢谢

*
 * main.c
 *
 * This module demonstrates operation of CRC with the bq769x0 family
 * AFE devices using a MSP430G2553 
 *
 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

#include <driverlib.h>
#include <stdbool.h>
#include <bqMaximo_Ctrl_G2553.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
/*
 * main.c
 */

#define LPI_BYTE_COUNT 20

RegisterGroup Registers;

const unsigned int OVPThreshold = 4300;
const unsigned int UVPThreshold = 2500;
const unsigned char SCDDelay = SCD_DELAY_100us;
const unsigned char SCDThresh = SCD_THRESH_89mV_44mV;
const unsigned char OCDDelay = OCD_DELAY_320ms;
const unsigned char OCDThresh = OCD_THRESH_22mV_11mV;
const unsigned char OVDelay = OV_DELAY_2s;
const unsigned char UVDelay = UV_DELAY_8s;

unsigned int CellVoltage[15];
float Gain = 0;
int iGain = 0;

void ClockInitialise()
{
    /*
	DCOCTL = 0xE0;	//DCO = 7, MOD = 0

	BCSCTL1 &= 0x8F;  //RSEL = 0, DCOR = 0, 20MHz Clock

	BCSCTL2 = 0x0;

	BCSCTL3 = 0;
	*/
    HWREG8(CS_BASE + OFS_CSCTL1) = DCORSEL_3;   // 8MHz clock
    HWREG8(CS_BASE + OFS_CSCTL2) = 0;
    HWREG8(CS_BASE + OFS_CSCTL3) = 0;
}

void TimerAInit(uint16_t baseAddress)
{
    /*
	TA0CTL |= TASSEL1;
	TA0CTL &= ~TASSEL0;

	TA0CTL |= MC1;
	TA0CTL &= ~MC0;

	TA0CTL &= ~TAIE;
    */
}

void I2CInitialise(uint16_t baseAddress)
{
    /*
	P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0, P1.6 for SCL and P1.7 for SDA
	P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0, P1.6 for SCL and P1.7 for SDA

	ADC10AE0 &= 0x3F;
	CAPD &= 0x3F;

	UCB0CTL1 |= UCSWRST;                      // Enable SW reset, hold USCI logic in reset state
	UCB0CTL0 = UCMODE_3 + UCSYNC;			//set to I2C mode, sync=1
	UCB0BR0 = 20;
	UCB0BR1 = 0;

	UCB0I2CIE = 0;
    IE2 &= ~(UCB0TXIE + UCB0RXIE);	//disable interrupts

    UCB0CTL1 |= UCSSEL_2;
    UCB0CTL1 &= ~UCSWRST;
    */


    uint16_t mask;

    P4SEL0 |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0, P1.6 for SCL and P1.7 for SDA
    P4SEL1 |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0, P1.6 for SCL and P1.7 for SDA

    HWREG16(baseAddress + OFS_UCBxCTLW0) = UCSWRST;

    //Configure Automatic STOP condition generation
    HWREG16(baseAddress + OFS_UCBxCTLW1) &= ~UCASTP_3;
    HWREG16(baseAddress + OFS_UCBxCTLW1) |= UCASTP_2;

    HWREG16(baseAddress + OFS_UCBxTBCNT) = LPI_BYTE_COUNT;

    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMST + UCMODE_3 + UCSYNC;

    HWREG16(baseAddress + OFS_UCBxBRW) = 0x8;

    HWREG16(baseAddress + OFS_UCBxIE) = 0;

    mask = UCRXIE0 | UCTXIE0 | UCSTPIE | UCNACKIE;
    HWREG16(baseAddress + OFS_UCBxIE) &= ~mask;

    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSSEL_2;

    HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCSWRST;

    //HWREG16(baseAddress + OFS_UCBxIE) |= mask;
    HWREG16(baseAddress + OFS_UCBxIE) |= ~0;
}

int I2CSendByte(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char data)
{
	unsigned long int DelayCounter = 0;

	//UCB0CTL0 |= UCMST;
	HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMST;

	//UCB0I2CSA = I2CSlaveAddress;
	EUSCI_B_I2C_setSlaveAddress(baseAddress, I2CSlaveAddress);

	//UCB0CTL1 |= UCTR; //data in transmit direction
    //UCB0CTL1 |= UCTXSTT; //Generate Start Condition
	 	 	 	 	 	  //Send Start Byte

	HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;

	//while(!(IFG2 & UCB0TXIFG))  //if UCB0TXIFG != 0, wait here
	while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
	{
		 DelayCounter ++;
		 if (DelayCounter >= DELAY_LIMIT)
			 break;
	}

	if (DelayCounter >= DELAY_LIMIT)
		 return -1;

	//UCB0TXBUF = data;				// send the data
	HWREG16(baseAddress + OFS_UCBxTXBUF) = data;

	DelayCounter = 0;

	//while(DelayCounter < DELAY_LIMIT && !(IFG2 & UCB0TXIFG))
	while(DelayCounter < DELAY_LIMIT && !(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
	{
		 DelayCounter++;
	}

	if (DelayCounter >= DELAY_LIMIT)
		 return -1;

	//UCB0CTL1 |= UCTXSTP;			//send stop bit
	HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;

	DelayCounter = 0;

	//while(DelayCounter < DELAY_LIMIT && (UCB0CTL1 & UCTXSTP))
	while(DelayCounter < DELAY_LIMIT && (HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTP))
	{
		DelayCounter++;
	}

	if (DelayCounter >= DELAY_LIMIT)	//check if NACK condition occurred
		return -1;
	else
		return 0;

}

int I2CSendBytes(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char *DataBuffer, unsigned int ByteCount, unsigned int *SentByte)
{
	unsigned long int DelayCounter = 0;
    unsigned int NumberOfBytesSent = 0;
    unsigned char *DataPointer;

	//UCB0CTL0 |= UCMST;
    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMST;
	//UCB0I2CSA = I2CSlaveAddress;
    EUSCI_B_I2C_setSlaveAddress(baseAddress, I2CSlaveAddress);

    DataPointer = DataBuffer;

	//UCB0CTL1 |= UCTR; //data in transmit direction
	//UCB0CTL1 |= UCTXSTT; //Generate Start Condition
	 	 	 	 	 	  //Send Start Byte
	HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;

	//while(!(IFG2 & UCB0TXIFG))  //if UCTXSTT != 0, wait here
	while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
	{
		DelayCounter ++;
		if (DelayCounter > DELAY_LIMIT)
			break;
	}

	if (DelayCounter >= DELAY_LIMIT)   //check if NACK condition occurred
	{
		 *SentByte = NumberOfBytesSent;
		 //UCB0CTL1 |= UCTXSTP;
		 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
		 return -1;
	}

	for(NumberOfBytesSent = 0; NumberOfBytesSent < ByteCount; NumberOfBytesSent++)
	{
		//UCB0TXBUF= *DataPointer;
	    HWREG16(baseAddress + OFS_UCBxTXBUF) = *DataPointer;
		DelayCounter = 0;

		//while(DelayCounter < DELAY_LIMIT && (!(IFG2 & UCB0TXIFG) || (UCB0CTL1 & UCTXSTT)))	//check if the byte has been sent
		while(DelayCounter < DELAY_LIMIT && (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG) ||
		                                    (HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTT)))
		{
			DelayCounter++;
		}

		if (DelayCounter >= DELAY_LIMIT)	//check if NACK condition occurred
		{
			 *SentByte = NumberOfBytesSent;
			 //UCB0CTL1 |= UCTXSTP;				//send stop condition
			 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
			 return -1;
		}

		DataPointer++;
	}

	 //IFG2 &= ~UCB0TXIFG;
	HWREG16(baseAddress + OFS_UCBxIFG) &= ~UCTXIFG;
	//UCB0CTL1 |= UCTXSTP;		//send stop bit
	HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;

	DelayCounter = 0;

	//while(DelayCounter < DELAY_LIMIT && ((UCB0CTL1 & UCTXSTP)))
	while(DelayCounter < DELAY_LIMIT && ((HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTP)))
	{
		DelayCounter++;
	}

	*SentByte =  NumberOfBytesSent;

	if (DelayCounter >= DELAY_LIMIT)	//check if NACK condition occurred
	{
		//UCB0CTL1 |= UCSWRST;
	    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
		return -1;
	}
	else
		return 0;
}

int I2CWriteRegisterByte(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned char Data)
{
	unsigned char DataBuffer[2];
	unsigned int SentByte = 0;


	DataBuffer[0] = Register;
	DataBuffer[1] = Data;

	return(I2CSendBytes(baseAddress, I2CSlaveAddress, DataBuffer, 2, &SentByte));
}

int I2CWriteRegisterByteWithCRC(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned char Data)
{
	unsigned char DataBuffer[4];
	unsigned int SentByte = 0;

    DataBuffer[0] = I2CSlaveAddress << 1;
	DataBuffer[1] = Register;
	DataBuffer[2] = Data;
	DataBuffer[3] = CRC8(DataBuffer, 3, CRC_KEY);

	return(I2CSendBytes(baseAddress, I2CSlaveAddress, DataBuffer + 1, 3, &SentByte));
}

int I2CWriteRegisterWordWithCRC(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned int Data)
{
	unsigned char DataBuffer[6];
	unsigned int SentByte = 0;

    DataBuffer[0] = I2CSlaveAddress << 1;
	DataBuffer[1] = Register;
	DataBuffer[2] = LOW_BYTE(Data);
	DataBuffer[3] = CRC8(DataBuffer, 3, CRC_KEY);
	DataBuffer[4] = HIGH_BYTE(Data);
	DataBuffer[5] = CRC8(DataBuffer + 4, 1, CRC_KEY);

	return(I2CSendBytes(baseAddress, I2CSlaveAddress, DataBuffer + 1, 5, &SentByte));
}

int I2CWriteBlockWithCRC(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char StartAddress, unsigned char *Buffer, unsigned char Length)
{
	unsigned char *BufferCRC, *Pointer;
	int i;
	unsigned int SentByte = 0;
	int result;

	BufferCRC = (unsigned char*)malloc(2*Length + 2);
	if (NULL == BufferCRC)
		return -1;

	Pointer = BufferCRC;
	*Pointer = I2CSlaveAddress << 1;
	Pointer++;
	*Pointer = StartAddress;
	Pointer++;
	*Pointer = *Buffer;
	Pointer++;
	*Pointer = CRC8(BufferCRC, 3, CRC_KEY);

	for(i = 1; i < Length; i++)
	{
        Pointer++;
        Buffer++;
        *Pointer = *Buffer;
		*(Pointer + 1) = CRC8(Pointer, 1, CRC_KEY);
		Pointer++;
	}

	result = I2CSendBytes(baseAddress, I2CSlaveAddress, BufferCRC + 1, 2*Length + 1, &SentByte);

	free(BufferCRC);
	BufferCRC = NULL;

	return result;
}

int I2CWriteRegisterWord(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned int Data)
{
	unsigned char DataBuffer[3];
	unsigned int SentByte = 0;

	DataBuffer[0] = Register;
	DataBuffer[1] = LOWBYTE(Data);
	DataBuffer[2] = HIGHBYTE(Data);

	return(I2CSendBytes(baseAddress, I2CSlaveAddress, DataBuffer, 3, &SentByte));
}

int I2CReadBytes(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char *DataBuffer, unsigned int ExpectedByteNumber, unsigned int *NumberOfReceivedBytes)
{
	unsigned long int DelayCounter = 0;
    unsigned char *DataPointer;
    unsigned int *NumberOfReceivedBytesPointer;

    NumberOfReceivedBytesPointer = NumberOfReceivedBytes;
    *NumberOfReceivedBytesPointer = 0;

    //UCB0CTL0 |= UCMST;
    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;

    DataPointer = DataBuffer;
	//UCB0I2CSA = I2CSlaveAddress;
    EUSCI_B_I2C_setSlaveAddress(baseAddress, I2CSlaveAddress);

	//UCB0CTL1 &= ~(UCTR); //data in receive direction
    HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCTR;

	//UCB0CTL1 |= UCTXSTT; //Generate Start Condition
    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTT;

	//while((UCB0CTL1 & UCTXSTT))  //if UCTXSTT != 0, wait here
    while (HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTT)
	{
		 DelayCounter ++;
		 if (DelayCounter >= DELAY_LIMIT)
			 break;
	}

	//if (DelayCounter >= DELAY_LIMIT || UCB0STAT & UCNACKIFG)   //check if NACK condition occurred
    if (DelayCounter >= DELAY_LIMIT || HWREG16(baseAddress + OFS_UCBxIFG) & UCNACKIFG)
		 return -1;

	for(*NumberOfReceivedBytesPointer = 0; *NumberOfReceivedBytesPointer < ExpectedByteNumber; (*NumberOfReceivedBytesPointer)++)
	{
		if(*NumberOfReceivedBytesPointer + 1 == ExpectedByteNumber)
			//UCB0CTL1 |= UCTXSTP;
		    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;

		DelayCounter = 0;

		//while(DelayCounter < DELAY_LIMIT && !(IFG2 & UCB0RXIFG))
		while(DelayCounter < DELAY_LIMIT && !(HWREG16(baseAddress + OFS_UCBxIFG) & UCRXIFG))
		{
			DelayCounter++;
		}

		if(DelayCounter == DELAY_LIMIT)
		{
			//UCB0CTL1 |= UCSWRST;   //if I2C overtime condition occurred, reset I2C engine
		    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
			return -1;
		}

		*DataPointer = UCB0RXBUF;

		DataPointer++;
	}

	DelayCounter = 0;
	//while(DelayCounter < DELAY_LIMIT && (UCB0CTL1 & UCTXSTP))
	while(DelayCounter < DELAY_LIMIT && (HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTP))
	{
		DelayCounter++;
	}

	if(DelayCounter >= DELAY_LIMIT)
	{
		//UCB0CTL1 |= UCSWRST;
	    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
		return -1;
	}

	return 0;

}

int I2CReadRegisterByte(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned char *Data)
{
	unsigned char TargetRegister = Register;
	unsigned int SentByte = 0;
	unsigned int ReadDataCount = 0;
    int ReadStatus = 0;
    int WriteStatus = 0;

	WriteStatus = I2CSendBytes(baseAddress, I2CSlaveAddress, &TargetRegister, 1, &SentByte);

	ReadStatus = I2CReadBytes(baseAddress, I2CSlaveAddress, Data, 1, &ReadDataCount);

	if (ReadStatus != 0 || WriteStatus != 0)
	{
		return -1;
	}

	return 0;
}

int I2CReadBlock(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char StartRegisterAddress, unsigned char *Buffer, unsigned int BlockSize, unsigned int *NumberOfBytes)
{
	unsigned char TargetRegister = StartRegisterAddress;
	unsigned int SentByte = 0;
	int ReadStatus = 0;
	int WriteStatus = 0;

	WriteStatus = I2CSendBytes(baseAddress, I2CSlaveAddress, &TargetRegister, 1, &SentByte);

	ReadStatus = I2CReadBytes(baseAddress, I2CSlaveAddress, Buffer, BlockSize, NumberOfBytes);

	if(ReadStatus != 0 || WriteStatus != 0)
	{
		return -1;
	}

	return 0;
}

unsigned char CRC8(unsigned char *ptr, unsigned char len,unsigned char key)
{
	unsigned char i;
	unsigned char crc=0;
	while(len--!=0)
	{
		for(i=0x80; i!=0; i/=2)
		{
			if((crc & 0x80) != 0)
			{
				crc *= 2;
				crc ^= key;
			}
			else
				crc *= 2;

			if((*ptr & i)!=0)
				crc ^= key;
		}
		ptr++;
	}
	return(crc);
}

int I2CReadRegisterByteWithCRC(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned char *Data)
{
	unsigned char TargetRegister = Register;
	unsigned int SentByte = 0;
	unsigned char ReadData[2];
	unsigned int ReadDataCount = 0;
	unsigned char CRCInput[2];
	unsigned char CRC = 0;
    int ReadStatus = 0;
    int WriteStatus = 0;

	WriteStatus = I2CSendBytes(baseAddress, I2CSlaveAddress, &TargetRegister, 1, &SentByte);

	ReadStatus = I2CReadBytes(baseAddress, I2CSlaveAddress, ReadData, 2, &ReadDataCount);

	if (ReadStatus != 0 || WriteStatus != 0)
	{
		return -1;
	}

	CRCInput[0] = (I2CSlaveAddress << 1) + 1;
	CRCInput[1] = ReadData[0];

	CRC = CRC8(CRCInput, 2, CRC_KEY);

	if (CRC != ReadData[1])
		return -1;

	*Data = ReadData[0];
	return 0;
}

int I2CReadRegisterWordWithCRC(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned int *Data)
{
	unsigned char TargetRegister = Register;
	unsigned int SentByte = 0;
	unsigned char ReadData[4];
	unsigned int ReadDataCount = 0;
	unsigned char CRCInput[2];
	unsigned char CRC = 0;
    int ReadStatus = 0;
    int WriteStatus = 0;

	WriteStatus = I2CSendBytes(baseAddress, I2CSlaveAddress, &TargetRegister, 1, &SentByte);

	ReadStatus = I2CReadBytes(baseAddress, I2CSlaveAddress, ReadData, 4, &ReadDataCount);

	if (ReadStatus != 0 || WriteStatus != 0)
	{
		return -1;
	}

	CRCInput[0] = (I2CSlaveAddress << 1) + 1;
	CRCInput[1] = ReadData[0];

	CRC = CRC8(CRCInput, 2, CRC_KEY);

	if (CRC != ReadData[1])
		return -1;

	CRC = CRC8(ReadData + 2, 1, CRC_KEY);

	if (CRC != ReadData[3])
		return -1;

	*Data = ReadData[0];

	*Data = (*Data << 8) + ReadData[2];

	return 0;
}

int I2CReadBlockWithCRC(uint16_t baseAddress, unsigned char I2CSlaveAddress, unsigned char Register, unsigned char *Buffer, unsigned char Length)
{
	unsigned char TargetRegister = Register;
	unsigned int SentByte = 0;
	unsigned char *ReadData = NULL, *StartData = NULL;
	unsigned int ReadDataCount = 0;
	unsigned char CRCInput[2];
	unsigned char CRC = 0;
    int ReadStatus = 0;
    int WriteStatus = 0;
    int i;

    StartData = (unsigned char *)malloc(2 * Length);

    if (NULL == StartData)
    	return -1;

    ReadData = StartData;

	WriteStatus = I2CSendBytes(baseAddress, I2CSlaveAddress, &TargetRegister, 1, &SentByte);

	ReadStatus = I2CReadBytes(baseAddress, I2CSlaveAddress, ReadData, 2 * Length, &ReadDataCount);

	if (ReadStatus != 0 || WriteStatus != 0)
	{
		free(StartData);
		StartData = NULL;

		return -1;
	}

	CRCInput[0] = (I2CSlaveAddress << 1) + 1;
	CRCInput[1] = *ReadData;

	CRC = CRC8(CRCInput, 2, CRC_KEY);

	ReadData++;
	if (CRC != *ReadData)
	{
		free(StartData);
		StartData = NULL;
		return -1;
	}
	else
		*Buffer = *(ReadData - 1);

	for(i = 1; i < Length; i++)
	{
		ReadData++;
		CRC = CRC8(ReadData, 1, CRC_KEY);
		ReadData++;
		Buffer++;

		if (CRC != *ReadData)
		{
			free(StartData);
			StartData = NULL;

			return -1;
		}
		else
			*Buffer = *(ReadData - 1);
	}

	free(StartData);
	StartData = NULL;

	return 0;
}

int GetADCGainOffset(uint16_t baseAddress)
{
	int result;

	result = I2CReadRegisterByteWithCRC(baseAddress, BQMAXIMO, ADCGAIN1, &(Registers.ADCGain1.ADCGain1Byte));
	result = I2CReadRegisterByteWithCRC(baseAddress, BQMAXIMO, ADCGAIN2, &(Registers.ADCGain2.ADCGain2Byte));
	result = I2CReadRegisterByteWithCRC(baseAddress, BQMAXIMO, ADCOFFSET, &(Registers.ADCOffset));

	return result;
}

int ConfigureBqMaximo(uint16_t baseAddress)
{
	int result = 0;
	unsigned char bqMaximoProtectionConfig[5];

	result = I2CWriteBlockWithCRC(baseAddress, BQMAXIMO, PROTECT1, &(Registers.Protect1.Protect1Byte), 5);

	result = I2CReadBlockWithCRC(baseAddress, BQMAXIMO, PROTECT1, bqMaximoProtectionConfig, 5);

	if(bqMaximoProtectionConfig[0] != Registers.Protect1.Protect1Byte
			|| bqMaximoProtectionConfig[1] != Registers.Protect2.Protect2Byte
			|| bqMaximoProtectionConfig[2] != Registers.Protect3.Protect3Byte
			|| bqMaximoProtectionConfig[3] != Registers.OVTrip
			|| bqMaximoProtectionConfig[4] != Registers.UVTrip)
	{
		result = -1;
	}

	return result;
}

int InitialisebqMaximo(uint16_t baseAddress)
{
	int result = 0;

	Registers.Protect1.Protect1Bit.SCD_DELAY = SCDDelay;
	Registers.Protect1.Protect1Bit.SCD_THRESH = SCDThresh;
	Registers.Protect2.Protect2Bit.OCD_DELAY = OCDDelay;
	Registers.Protect2.Protect2Bit.OCD_THRESH = OCDThresh;
	Registers.Protect3.Protect3Bit.OV_DELAY = OVDelay;
	Registers.Protect3.Protect3Bit.UV_DELAY = UVDelay;

	result = GetADCGainOffset(baseAddress);

	Gain = (365 + ((Registers.ADCGain1.ADCGain1Byte & 0x0C) << 1) + ((Registers.ADCGain2.ADCGain2Byte & 0xE0)>> 5)) / 1000.0;
	iGain = 365 + ((Registers.ADCGain1.ADCGain1Byte & 0x0C) << 1) + ((Registers.ADCGain2.ADCGain2Byte & 0xE0)>> 5);

    Registers.OVTrip = (unsigned char)((((unsigned short)((OVPThreshold - Registers.ADCOffset)/Gain + 0.5) - OV_THRESH_BASE) >> 4) & 0xFF);
    Registers.UVTrip = (unsigned char)((((unsigned short)((UVPThreshold - Registers.ADCOffset)/Gain + 0.5) - UV_THRESH_BASE) >> 4) & 0xFF);

    result = ConfigureBqMaximo(baseAddress);

    return result;
}

int UpdateVoltageFromBqMaximo(uint16_t baseAddress)
{
	int Result = 0, i = 0;
	unsigned char *pRawADCData = NULL;
	unsigned int iTemp = 0;
	unsigned long lTemp = 0;

	Result = I2CReadBlockWithCRC(baseAddress, BQMAXIMO, \
			VC1_HI_BYTE, \
			&(Registers.VCell1.VCell1Byte.VC1_HI), \
			30);

	pRawADCData = &Registers.VCell1.VCell1Byte.VC1_HI;
	for (i = 0; i < 15; i++)
	{
		iTemp = (unsigned int)(*pRawADCData << 8) + *(pRawADCData + 1);
		lTemp = ((unsigned long)iTemp * iGain)/1000;
		lTemp += Registers.ADCOffset;
		CellVoltage[i] = lTemp;
		pRawADCData += 2;
	}

	return Result;
}

int main(void)
{
	int Result;


    //WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer

    DISABLE_INT;

    ClockInitialise();

    I2CInitialise(EUSCI_B1_BASE);

    InitialisebqMaximo(EUSCI_B1_BASE);

    while(1)
    {
    	Result = UpdateVoltageFromBqMaximo(EUSCI_B1_BASE);
    }

	return Result;
}

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

    >P4SEL0 |= BIT6 + BIT7;//将 I2C 引脚分配给 USCI_B0,用于 SCL 的 P1.6和用于 SDA 的 P1.7
    >P4SEL1 |= BIT6 + BIT7;//将 I2C 引脚分配给 USCI_B0,用于 SCL 的 P1.6和用于 SDA 的 P1.7

    要在 P4.6/7上获取 UCB1SDA/SCL,您需要 PSEL=0,即 PSEL1位应为=0 [参考 FR2355数据表(SLASEC4D)表6-66]。

    删除这些行中的第二行。

    -----

    您是否安装了 I2C 上拉装置? [参考 EVM 数据表(SLVU925C)第6.6节]

    如果您的导线非常短,并且您的总线运行速度不是太快(请尝试 BRW=80,而不是 BRW=8),则您可能会成功执行内部抽拉:

    >P4OUT |=(BIT6|BIT7);

    >P4REN |=(BIT6|BIT7);

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

    在以下步骤中更改配置

    1>上拉两侧的 I2C

    2>  

    P4SEL0 |= BIT6 + BIT7;//将 I2C 引脚分配给 USCI_B0,用于 SCL 的 P1.6和用于 SDA 的 P1.7
    P4SEL1 = 0;
    P4OUT |= BIT6 + BIT7;
    P4REN |= BIT6 + BIT7;

    当我尝试相同的步骤时,我确实看到 UCTXIFG 设置为1。

    但是,它位于 B0模块中。

    我的设置在 B1模块上。

    这是否合理?如何解决?

    请给出建议

    谢谢

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

    这似乎是不寻常的。 EUSCI_B1_BASE 的值是多少? (应该是0x05C0)[右键单击名称并“转至定义”。]

    其他 UCB0寄存器是否也显示您的设置? 未初始化的 EUSCI_B 具有 UCTXIFG=1 [参考用户指南(SLAU445I)表23-18]。

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

    您好,

    有关调试 MSP430的 I2C 问题,请参阅以下资源。

    MSP 学院:I2C 概念

    eUSCI 和 USCI 串行通信常见问题的解决方案

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

    我认为这个问题甚至与 I2C 无关。

    我们刚刚发现 MSP-ts430pt48 没有晶体。

    我将把这个问题标记为已解决。

    谢谢