请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:MSP430FR2433 我正在运行 eusci_b_i2c_ex3_masterTxMultiple 的修改版本。
当我调用 EUSCI_B_I2C_masterSendMultiByteStart 时、它会在"传输中断标志轮询"处挂起。
有什么想法可能会导致这种情况?
代码有时会起作用。 我有一个逻辑分析仪、能够看到通过 I2C 总线发送的数据字节。

代码:
/* --COPYRIGHT--,BSD
* Copyright (c) 2017, Texas Instruments Incorporated
* All rights reserved.
*
* 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.
* --/COPYRIGHT--*/
//******************************************************************************
//
//! This example shows how to configure the I2C module as a master for
//! multi byte transmission in interrupt driven mode. The address of the slave
//! module is set in this example.
//!
//! Demo - EUSCI_B0 I2C Master TX multiple bytes to MSP430 Slave
//!
//! Description: This demo connects two MSP430's via the I2C bus. The master
//! transmits to the slave. This is the MASTER CODE. It cntinuously
//! transmits an array of data and demonstrates how to implement an I2C
//! master transmitter sending multiple bytes using the USCI_B0 TX interrupt.
//! ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1MHz
//!
//! /|\ /|\
//! MSP430FR2xx_4xx Board 10k 10k MSP430FR2xx_4xx Board
//! slave | | master
//! ----------------- | | -----------------
//! | UCB0SDA|<-|----+->|UCB0SDA |
//! | | | | |
//! | | | | |
//! | UCB0SCL|<-+------>|UCB0SCL |
//! | | | |
//!
//! This example uses the following peripherals and I/O signals. You must
//! review these and change as needed for your own board:
//! - I2C peripheral
//! - GPIO Port peripheral (for I2C pins)
//! - SCL
//! - SDA
//!
//! This example uses the following interrupt handlers. To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - USCI_B0_VECTOR.
//
//******************************************************************************
#include "driverlib.h"
#include "Board.h"
//*****************************************************************************
//
//Set the address for slave module. This is a 7-bit address sent in the
//following format:
//[A6:A5:A4:A3:A2:A1:A0:RS]
//
//A zero in the "RS" position of the first byte means that the master
//transmits (sends) data to the selected slave, and a one in this position
//means that the master receives data from the slave.
//
//*****************************************************************************
#define SLAVE_ADDRESS 0x77
//*****************************************************************************
//
//Target frequency for SMCLK in kHz
//
//*****************************************************************************
#define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ 1000
//*****************************************************************************
//
//SMCLK/FLLRef Ratio
//
//*****************************************************************************
#define CS_SMCLK_FLLREF_RATIO 30
// Pointer to TX data
uint8_t TXData[] = {0x06, 0x00, 0x02, 0xFF, 0x02, 0x00};
int i = 0;
uint8_t TXByteCtr;
void main(void)
{
WDT_A_hold(WDT_A_BASE);
//Set DCO FLL reference = REFO
CS_initClockSignal(
CS_FLLREF,
CS_REFOCLK_SELECT,
CS_CLOCK_DIVIDER_1
);
//Set Ratio and Desired MCLK Frequency and initialize DCO
CS_initFLLSettle(
CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ,
CS_SMCLK_FLLREF_RATIO
);
//Set ACLK = VLO with frequency divider of 1
CS_initClockSignal(
CS_ACLK,
CS_VLOCLK_SELECT,
CS_CLOCK_DIVIDER_1
);
//Set SMCLK = DCO with frequency divider of 1
CS_initClockSignal(
CS_SMCLK,
CS_DCOCLKDIV_SELECT,
CS_CLOCK_DIVIDER_1
);
//Set MCLK = DCO with frequency divider of 1
CS_initClockSignal(
CS_MCLK,
CS_DCOCLKDIV_SELECT,
CS_CLOCK_DIVIDER_1
);
// Configure Pins for I2C
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_UCB0SCL,
GPIO_PIN_UCB0SCL,
GPIO_FUNCTION_UCB0SCL
);
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_UCB0SDA,
GPIO_PIN_UCB0SDA,
GPIO_FUNCTION_UCB0SDA
);
/*
* Disable the GPIO power-on default high-impedance mode to activate
* previously configured port settings
*/
PMM_unlockLPM5();
EUSCI_B_I2C_initMasterParam param = {0};
param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
param.i2cClk = CS_getSMCLK();
param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
param.byteCounterThreshold = 0;
param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, ¶m);
//Specify slave address
EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,
SLAVE_ADDRESS
);
//Set Master in receive mode
EUSCI_B_I2C_setMode(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_MODE
);
//Enable I2C Module to start operations
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
EUSCI_B_I2C_NAK_INTERRUPT
);
//Enable master Receive interrupt
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
EUSCI_B_I2C_NAK_INTERRUPT
);
while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData[i]);
while(1)
{
__delay_cycles(5000); // Delay between transmissions
TXByteCtr = 1; // Load TX byte counter
if(i == 4) i = 2;
while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData[i]);
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
// is TX'd
// Increment data byte
}
}
//------------------------------------------------------------------------------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
{
switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: // No interrupts break;
break;
case USCI_I2C_UCALIFG: // Arbitration lost
break;
case USCI_I2C_UCNACKIFG: // NAK received (master only)
//resend start if NACK
EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
break;
case USCI_I2C_UCTXIFG0: // TXIFG0
// Check TX byte counter
if (TXByteCtr)
{
i++;
EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData[i]);
// Decrement TX byte counter
TXByteCtr--;
}
else
{
EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
// Exit LPM0
__bic_SR_register_on_exit(CPUOFF);
}
break;
default:
break;
}
}