我会定期收到标题中显示的错误、我不确定是为什么。 它发生在我通过 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 ()函数将其打开。 除非我连续发送多个命令、否则这通常效果很好。 当我连续发送多个命令时、会崩溃。 我是否不能很好地处理回调?