我会定期收到标题中显示的错误、我不确定是为什么。 它发生在我通过 I2C 从主机与 MSP430进行通信时、看起来像一个随机时间。 I2C 通信通常运行良好、直到我连续发送多个命令、然后 MSP430崩溃并出现此错误。 我已附上一些展示 I2C 通信接口的代码。
main 函数
/* --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--*/
//*****************************************************************************
// Development main.c for MSP430FR2676 CapTIvate devices.
//
// This starter application initializes the CapTIvate touch library
// for the touch panel specified by CAPT_UserConfig.c/.h via a call to
// CAPT_appStart(), which initializes and calibrates all sensors in the
// application, and starts the CapTIvate interval timer.
//
// Then, the capacitive touch interface is driven by calling the CapTIvate
// application handler, CAPT_appHandler(). The application handler manages
// whether the user interface (UI) is running in full active scan mode, or
// in a low-power wake-on-proximity mode.
//
// \version 1.83.00.05
// Released on May 15, 2020
//
//*****************************************************************************
#include <msp430.h> // Generic MSP430 Device Include
#include "driverlib.h" // MSPWare Driver Library
#include "captivate.h" // CapTIvate Touch Software Library
#include "CAPT_App.h" // CapTIvate Application Code
#include "CAPT_BSP.h" // CapTIvate EVM Board Support Package
#include "drivers/als.h" // Ambient Light Sensor Library
#include "drivers/leds.h" // LED Library
#include "drivers/trh.h" // Temperature/Relative Humidity Sensor Library
#include "host_interface/host_interface.h" // Host Interface Library
#include "system/timer.h" // Timer Library
void main(void)
{
// Disable watchdog
WDTCTL = WDTPW | WDTHOLD;
// Initialize MCU and enable global interrupts
BSP_configureMCU();
__bis_SR_register(GIE);
// Start the keypad CapTIvate application
CAPT_appStart();
// Start the LED driver
LEDs_initialize();
// Initialize the temperature/relative humidity sensor
TRH_initialize();
// Initialize the ambient light sensor
//ALS_initialize();
// Initialize the host interface
HostInterface_initialize();
//
// Background Loop
//
while(1)
{
// Run the captivate application handler.
CAPT_appHandler();
// Update the timers
Timer_update();
// Update the LEDs
LEDs_update();
// Update the temperature/relative humidity sensor
TRH_update();
// Update the ALS
//ALS_update();
// Go to sleep if there is nothing left to do
CAPT_appSleep();
} // End background loop
} // End main()
SPI 接口
/*
* @file host_interface.c
* @brief Source file for the Cerberus CV25 interface.
* @author Eric Smith <eric.smith@brivo.com>
* @copyright Brivo, Inc.
* @date 2023
*/
//*****************************************************************************
// Includes
//*****************************************************************************
#include "CAPT_App.h"
#include "driverlib.h"
#include "drivers/als.h"
#include "drivers/leds.h"
#include "drivers/trh.h"
#include "I2CSlave.h"
#include "host_interface.h"
//*****************************************************************************
// Definitions
//*****************************************************************************
//*****************************************************************************
//
//! \def HOSTINTERFACE_I2C_ADDRESS defines the I2C slave address.
//! Note that this is defined in I2CSlave_Definitions.h.
//
//*****************************************************************************
#define HOSTINTERFACE_I2C_ADDRESS (I2CSLAVE__ADDRESS)
//*****************************************************************************
//
//! \def These definitions define the registers of the host interface LEDs.
//
//*****************************************************************************
#define HOSTINTERFACE_REG_LED_OPERATION_MODE (0x00)
#define HOSTINTERFACE_REG_LED_KEYPAD_MODE (0x01)
//*****************************************************************************
//
//! \def HOSTINTERFACE_BUFFER_SIZE defines the I2C register buffer size.
//
//*****************************************************************************
#define HOSTINTERFACE_BUFFER_SIZE (32)
//*****************************************************************************
//
//! \def HOSTINTERFACE_OVRHD_LENGTH defines the I2C packet overhead length.
//! Includes sync, blank, and length bytes.
//
//*****************************************************************************
#define HOSTINTERFACE_OVRHD_LENGTH (3)
//*****************************************************************************
//
//! \def HOSTINTERFACE_DATA_LENGTH defines the I2C packet data length.
//
//*****************************************************************************
#define HOSTINTERFACE_DATA_LENGTH (6)
//*****************************************************************************
//
//! \def HOSTINTERFACE_CHKSUM_LENGTH defines the I2C packet checksum length.
//
//*****************************************************************************
#define HOSTINTERFACE_CHKSUM_LENGTH (2)
//*****************************************************************************
//
//! \def HOSTINTERFACE_REG_OFFSET defines the offset of the I2C register.
//
//*****************************************************************************
#define HOSTINTERFACE_REG_OFFSET (3)
//*****************************************************************************
//
//! \def HOSTINTERFACE_CMD_OFFSET defines the offset of the I2C command.
//
//*****************************************************************************
#define HOSTINTERFACE_CMD_OFFSET (4)
//*****************************************************************************
//
//! \def HOSTINTERFACE_BSL_CMD_SIZE defines the size of the BSL command.
//! The BSL command allows for a firmware update over I2C.
//
//*****************************************************************************
#define HOSTINTERFACE_BSL_CMD_SIZE (8)
//*****************************************************************************
// Function Declarations
//*****************************************************************************
//! \brief I2C slave receive callback function
//! \param count count of I2C message
//! \return true=>function exits active in I2C mode; false=>CPU returns to prev state
static bool HostInterface_ReceiveCallback(uint16_t count);
//*****************************************************************************
// Global Variables
//*****************************************************************************
//! \brief I2C slave data buffer
static uint8_t HostInterface_i2cDataBuffer[HOSTINTERFACE_BUFFER_SIZE];
//! \brief I2C slave handler
static const tI2CSlavePort HostInterface_handle = {
.pbReceiveCallback = HostInterface_ReceiveCallback,
.pvErrorCallback = 0,
.pReceiveBuffer = (HostInterface_i2cDataBuffer + HOSTINTERFACE_OVRHD_LENGTH),
.ui16ReceiveBufferSize = (HOSTINTERFACE_DATA_LENGTH + HOSTINTERFACE_CHKSUM_LENGTH),
.bSendReadLengthFirst = false,
};
//*****************************************************************************
// Function Implementations
//*****************************************************************************
void HostInterface_initialize(void)
{
// Set the host interrupt pin as an output
GPIO_setAsOutputPin(HOST_IRQ_PORT, HOST_IRQ_PIN);
// Open & Initialize the I2C Slave port
I2CSlave_openPort(&HostInterface_handle);
I2CSlave_setTransmitBuffer(
(HostInterface_i2cDataBuffer + HOSTINTERFACE_OVRHD_LENGTH),
(HOSTINTERFACE_BUFFER_SIZE - HOSTINTERFACE_OVRHD_LENGTH)
);
}
bool HostInterface_ReceiveCallback(uint16_t count)
{
// If there is no data sent, don't do anything
if (count == 0)
{
return false;
}
// Register read command
else if (count == 1)
{
uint8_t buffer;
switch (HostInterface_i2cDataBuffer[HOSTINTERFACE_REG_OFFSET])
{
// TODO: Add read functions
default:
break;
}
// Only send a value if something was read
if (buffer != NULL)
{
MAP_EUSCI_B_I2C_slavePutData(I2CSLAVE__EUSCI_B_PERIPHERAL, buffer);
}
}
// Register write command
else
{
uint8_t buffer = HostInterface_i2cDataBuffer[HOSTINTERFACE_CMD_OFFSET];
switch (HostInterface_i2cDataBuffer[HOSTINTERFACE_REG_OFFSET])
{
case HOSTINTERFACE_REG_LED_OPERATION_MODE:
LEDs_setFlag(LEDS_FLAG_OPERATION_MODE, buffer);
break;
case HOSTINTERFACE_REG_LED_KEYPAD_MODE:
LEDs_setFlag(LEDS_FLAG_KEYPAD_MODE, buffer);
break;
default:
break;
}
}
// Return false to exit with the CPU in its previous state.
// Since the response packet generation was handled immediately here,
// there is no need to exit active.
return false;
}
SPI 从器件驱动器(由 TI 自动生成)
/* --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--*/
//*****************************************************************************
// I2CSlave.c
//
// \version 1.83.00.05
// Released on May 15, 2020
//
//*****************************************************************************
//*****************************************************************************
//! \addtogroup I2CSlave
//! @{
//*****************************************************************************
#include "I2CSlave.h"
#if (I2CSLAVE__ENABLE==true)
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
#include "FunctionTimer.h"
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
//*****************************************************************************
//
//! var g_pI2CSlavePort stores a pointer to the I2C slave port configuration
//! structure that was passed to the I2CSlave_openPort function. The I2C
//! slave driver does not modify this structure.
//
//*****************************************************************************
const tI2CSlavePort *g_pI2CSlavePort;
//*****************************************************************************
//
//! var g_I2CSlaveConfiguration stores the MSP430 DriverLib EUSCI_B_I2C
//! configuration parameters for the EUSCI_B_I2C_initSlave() function call.
//
//*****************************************************************************
const EUSCI_B_I2C_initSlaveParam g_I2CSlaveConfiguration =
{
.slaveAddress = I2CSLAVE__ADDRESS,
.slaveAddressOffset = EUSCI_B_I2C_OWN_ADDRESS_OFFSET0,
.slaveOwnAddressEnable = EUSCI_B_I2C_OWN_ADDRESS_ENABLE
};
//*****************************************************************************
//
//! var g_pI2CTransmitBuffer stores a pointer to the current transmit buffer.
//
//*****************************************************************************
const uint8_t *g_pI2CTransmitBuffer;
//*****************************************************************************
//
//! var g_ui16I2CLength stores the valid data length of the data pointed
//! to by g_pI2CTransmitBuffer.
//
//*****************************************************************************
uint16_t g_ui16I2CLength;
//*****************************************************************************
//
//! var g_ui16I2CIndex stores the current transmit or receive buffer index.
//
//*****************************************************************************
volatile uint16_t g_ui16I2CIndex;
//*****************************************************************************
//
//! var g_I2CSlaveStatus stores the current status of the I2C slave port.
//! possible options are enumerated in tI2CSlaveStates.
//
//*****************************************************************************
volatile uint8_t g_I2CSlaveStatus = eI2CSlaveIsClosed;
//*****************************************************************************
//
//! var g_bI2CSlaveRequestPending indicates whether or not a read
//! operation is currently pending on the I2C bus master.
//
//*****************************************************************************
volatile bool g_bI2CSlaveRequestPending;
//*****************************************************************************
//
//! This function is for private use only. This is called by the I2C Slave
//! ISR when a receive (I2C write to this slave) operation is completed,
//! which is indicated either by a stop condition or a repeated start
//! condition. This function handles receiving the last byte of data (if
//! present) and calling the receive callback in the user's application,
//! if one is registered.
//
//! \par Parameters
//! none
//! \return true if the ISR should exit active (per the callback), else false.
//
//*****************************************************************************
static bool I2CSlave_handleEndOfReceive(void);
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
static bool I2CSlave_requestTimeoutHandler(void)
{
//
// If this function is called, the slave request to the master
// has timed out. This function cancels the request here
// and notifies the application via the error callback.
//
g_bI2CSlaveRequestPending = false;
if (g_pI2CSlavePort->pvErrorCallback != 0)
{
g_pI2CSlavePort->pvErrorCallback(eI2CSlaveTransmitRequestTimeout);
}
return true;
}
static bool I2CSlave_transactionTimeoutHandler(void)
{
//
// If this function is called, an I2C transaction with the master
// has timed out. This function resets the I2C port,
// and notifies the application via the error callback.
//
I2CSlave_openPort(g_pI2CSlavePort);
if (g_pI2CSlavePort->pvErrorCallback != 0)
{
g_pI2CSlavePort->pvErrorCallback(eI2CSlaveTransactionTimeout);
}
return true;
}
//*****************************************************************************
//
//! var g_I2CSlaveFunctionTimer contains the function timer configuration
//! for the two I2C timeout events- a slave request timeout (Fxn A)
//! and an I2C transaction timeout (Fxn B)
//
//*****************************************************************************
const tFunctionTimer g_I2CSlaveFunctionTimer =
{
.pbFunction_A = &I2CSlave_requestTimeoutHandler,
.pbFunction_B = &I2CSlave_transactionTimeoutHandler,
.ui16FunctionDelay_A = I2CSLAVE__REQ_TIMEOUT_CYCLES,
.ui16FunctionDelay_B = I2CSLAVE__TXFR_TIMEOUT_CYCLES
};
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
void I2CSlave_openPort(const tI2CSlavePort *pPort)
{
I2CSlave_closePort();
g_pI2CSlavePort = pPort;
g_bI2CSlaveRequestPending = false;
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
Timer_startDelayedFunctionTimer(&g_I2CSlaveFunctionTimer);
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
MAP_EUSCI_B_I2C_initSlave(
I2CSLAVE__EUSCI_B_PERIPHERAL,
(EUSCI_B_I2C_initSlaveParam*)&g_I2CSlaveConfiguration
);
MAP_EUSCI_B_I2C_enable(I2CSLAVE__EUSCI_B_PERIPHERAL);
MAP_EUSCI_B_I2C_clearInterrupt(I2CSLAVE__EUSCI_B_PERIPHERAL,I2CSLAVE__INT_MASK);
MAP_EUSCI_B_I2C_enableInterrupt(I2CSLAVE__EUSCI_B_PERIPHERAL, I2CSLAVE__INT_MASK);
I2C__INIT_REQ_SIGNAL;
g_I2CSlaveStatus = eI2CSlaveIsIdle;
}
void I2CSlave_closePort(void)
{
MAP_EUSCI_B_I2C_disable(I2CSLAVE__EUSCI_B_PERIPHERAL);
g_I2CSlaveStatus = eI2CSlaveIsClosed;
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
Timer_stopDelayedFunctionTimer();
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
}
uint8_t I2CSlave_getPortStatus(void)
{
return g_I2CSlaveStatus;
}
void I2CSlave_setTransmitBuffer(uint8_t *pBuffer, uint16_t ui16Length)
{
//
// Before setting the transmit buffer, safely wait for
// current read operations to finish
//
#if (I2CSLAVE__LPMx_bits>0)
while (1)
{
__bic_SR_register(GIE);
if ((g_I2CSlaveStatus == eI2CSlaveIsBeingRead)
|| (g_bI2CSlaveRequestPending==true))
{
__bis_SR_register(I2CSLAVE__LPMx_bits | GIE);
}
else
{
__bis_SR_register(GIE);
break;
}
};
#else
{
while((g_I2CSlaveStatus == eI2CSlaveIsBeingRead)|| (g_bI2CSlaveRequestPending==true));
}
#endif
//
// Update the transmit buffer and length.
//
g_ui16I2CLength = ui16Length;
g_pI2CTransmitBuffer = pBuffer;
}
void I2CSlave_setRequestFlag(void)
{
g_bI2CSlaveRequestPending = true;
I2C__PULL_REQ_SIGNAL;
//
// If the slave timeout feature is enabled,
// schedule a request flag timeout function
//
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
Timer_scheduleDelayedFunction(eTimerDelayedFunction_A);
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
//
// Before exiting the fxn,
// safely wait for read operation
// to begin before exiting
//
#if (I2CSLAVE__LPMx_bits>0)
while(1)
{
__bic_SR_register(GIE);
if (g_bI2CSlaveRequestPending==true)
{
__bis_SR_register(I2CSLAVE__LPMx_bits | GIE);
}
else
{
__bis_SR_register(GIE);
break;
}
}
#else
while(g_bI2CSlaveRequestPending==true);
#endif
//
// If the slave timeout feature is enabled,
// cancel the request flag timeout function
// as transmission has begun.
//
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
Timer_cancelDelayedFunction(eTimerDelayedFunction_A);
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
I2C__RELEASE_REQ_SIGNAL;
}
static bool I2CSlave_handleEndOfReceive(void)
{
uint8_t ui8Data;
//
// Check for final received data byte in case start/stop interrupt is being serviced
// before last rx interrupt due to MSP430 I2C interrupt priority
//
if(MAP_EUSCI_B_I2C_getInterruptStatus(I2CSLAVE__EUSCI_B_PERIPHERAL, EUSCI_B_I2C_RECEIVE_INTERRUPT0))
{
ui8Data = MAP_EUSCI_B_I2C_slaveGetData(I2CSLAVE__EUSCI_B_PERIPHERAL);
if (g_ui16I2CIndex < g_pI2CSlavePort->ui16ReceiveBufferSize)
{
g_pI2CSlavePort->pReceiveBuffer[g_ui16I2CIndex++] = ui8Data;
}
MAP_EUSCI_B_I2C_clearInterrupt(I2CSLAVE__EUSCI_B_PERIPHERAL, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
}
//
// Call receive callback if it exists
//
if (g_pI2CSlavePort->pbReceiveCallback != 0)
{
return g_pI2CSlavePort->pbReceiveCallback(g_ui16I2CIndex);
}
else
{
return false;
}
}
#pragma vector=I2CSLAVE__EUSCI_VECTOR
__interrupt void I2CSlave_ISR(void)
{
uint8_t ui8Data;
switch (__even_in_range(I2CSLAVE__EUSCI_IV, USCI_I2C_UCTXIFG0))
{
case USCI_I2C_UCSTTIFG:
//
// Check for the repeated start case. If this is a repeated start
// and the previous operation was a write to this device,
// handle the written (received) data. If this is a first-time stard,
// the previous I2C state is eI2CSlaveIsIdle.
//
if (g_I2CSlaveStatus == eI2CSlaveIsBeingWrittenTo)
{
if (I2CSlave_handleEndOfReceive() == true)
{
__bic_SR_register_on_exit(I2CSLAVE__LPMx_bits);
}
}
//
// Reset the I2C Index to zero to begin the new transaction.
// Then check the I2C mode (read/write) to determine
// the transaction mode.
//
g_ui16I2CIndex = 0;
if (MAP_EUSCI_B_I2C_getMode(I2CSLAVE__EUSCI_B_PERIPHERAL)
== EUSCI_B_I2C_TRANSMIT_MODE)
{
//
// If this is a read operation (read from this device),
// cancel the slave request flag and trigger and active
// exit to alert the application that the flag has changed.
//
g_I2CSlaveStatus = eI2CSlaveIsBeingRead;
g_bI2CSlaveRequestPending = false;
__bic_SR_register_on_exit(I2CSLAVE__LPMx_bits);
//
// If the driver is set up to send the number of bytes to be read
// before the rest of the buffer, load the number as the first data byte.
// Otherwise, load the first byte of the transmit buffer into the peripheral.
//
if (g_pI2CSlavePort->bSendReadLengthFirst == true)
{
ui8Data = g_ui16I2CLength;
}
else
{
ui8Data = g_pI2CTransmitBuffer[g_ui16I2CIndex++];
}
MAP_EUSCI_B_I2C_slavePutData(
I2CSLAVE__EUSCI_B_PERIPHERAL,
ui8Data
);
}
else
{
//
// If this is a write operation (write from master to this device),
// update the status accordingly and continue (no additional action is necessary).
//
g_I2CSlaveStatus = eI2CSlaveIsBeingWrittenTo;
}
//
// If the slave timeout feature is enabled, schedule a
// transaction timeout.
//
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
Timer_scheduleDelayedFunction(eTimerDelayedFunction_B);
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
break;
case USCI_I2C_UCSTPIFG:
//
// If the timeout feature is enabled, cancel
// the transaction timeout as the operation
// has finished successfully.
//
#if (I2CSLAVE__TIMEOUT_ENABLE==true)
Timer_cancelDelayedFunction(eTimerDelayedFunction_B);
#endif /* I2CSLAVE__TIMEOUT_ENABLE==true */
if (g_I2CSlaveStatus == eI2CSlaveIsBeingWrittenTo)
{
//
// If the operation that is ending was a write to this
// device, handle the written (received) data, and exit
// active if the callback function requested it.
//
if (I2CSlave_handleEndOfReceive() == true)
{
__bic_SR_register_on_exit(I2CSLAVE__LPMx_bits);
}
}
else if (g_I2CSlaveStatus == eI2CSlaveIsBeingRead)
{
//
// If the opreation that is ending was a read from this device,
// exit active in case a transmit (read) buffer pointer update
// was pending upon this read.
//
__bic_SR_register_on_exit(I2CSLAVE__LPMx_bits);
}
//
// Set new status to idle, as the I2C transaction has stopped.
//
g_I2CSlaveStatus = eI2CSlaveIsIdle;
break;
case USCI_I2C_UCRXIFG0:
//
// Grab the received (written) byte from the I2C peripheral.
// If there is receive buffer space left, store the received
// byte in the receive buffer. Otherwise, discard it and call
// the error callback fxn if one is registered.
//
ui8Data = ROM_EUSCI_B_I2C_slaveGetData(I2CSLAVE__EUSCI_B_PERIPHERAL);
if (g_ui16I2CIndex < g_pI2CSlavePort->ui16ReceiveBufferSize)
{
g_pI2CSlavePort->pReceiveBuffer[g_ui16I2CIndex++] = ui8Data;
}
else
{
if (g_pI2CSlavePort->pvErrorCallback != 0)
{
g_pI2CSlavePort->pvErrorCallback(eI2CSlaveReceiveBufferFull);
}
}
break;
case USCI_I2C_UCTXIFG0:
//
// If the transmit index is less than the length, there is still
// valid data in the buffer. Load the next byte.
// Else, there is no valid data left in the buffer, so transmit
// the invalid byte.
//
if (g_ui16I2CIndex<g_ui16I2CLength)
{
ui8Data = g_pI2CTransmitBuffer[g_ui16I2CIndex++];
}
else
{
ui8Data = I2CSLAVE__INVALID_BYTE;
if (g_pI2CSlavePort->pvErrorCallback != 0)
{
g_pI2CSlavePort->pvErrorCallback(eI2CSlaveWasReadBeyondTransmitBuffer);
}
}
MAP_EUSCI_B_I2C_slavePutData(I2CSLAVE__EUSCI_B_PERIPHERAL, ui8Data);
break;
}
}
#endif /* I2CSLAVE__ENABLE==true */
//*****************************************************************************
//! Close the doxygen group
//! @}
//*****************************************************************************
当我使用这段代码从主机向 MSP430发送"0x01 0x03"命令时、它会调用 HOSTINTERFACE_REG_LED_KEYPAD _MODE 情况。 它会更新标志以更改 LED、然后通过 main 中的 LEDS_UPDATE ()函数将其打开。 除非我连续发送多个命令、否则这通常效果很好。 当我连续发送多个命令时、会崩溃。 我是否不能很好地处理回调?