请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:MSP430FR5969 工具与软件:
主代码:
void main(void)
{
//Init similiar to receive example for MSP430 FR5969
init_I2C();
while(1){
cmd_process();
}
}
init_i2C():
void init_I2C(){
WDT_A_hold(WDT_A_BASE);
// Configure Pins for I2C
//Set P1.6 and P1.7 as Secondary Module Function Input.
/*
* Select Port 1
* Set Pin 6, 7 to input Secondary Module Function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
*/
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P1,
GPIO_PIN6 + GPIO_PIN7,
GPIO_SECONDARY_MODULE_FUNCTION
);
/*
* Disable the GPIO power-on default high-impedance mode to activate
* previously configured port settings
*/
PMM_unlockLPM5();
// eUSCI configuration
EUSCI_B_I2C_initSlaveParam param = {0};
param.slaveAddress = SLAVE_ADDRESS;
param.slaveAddressOffset = EUSCI_B_I2C_OWN_ADDRESS_OFFSET0;
param.slaveOwnAddressEnable = EUSCI_B_I2C_OWN_ADDRESS_ENABLE;
EUSCI_B_I2C_initSlave(EUSCI_B0_BASE, ¶m);
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT
);
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT
);
// __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
// __no_operation();
}
CMD_PROCESS():
void cmd_process() {
switch(current_Statemachine) {
case IDLE:
resumeI2CInterrupts();
break;
case HEALTH_CHECK: // Simply Returns the received data
TXData = myPayload;
current_Statemachine = IDLE;
break;
... Rest of the code
Arduino 主代码(teensy):
#include <Wire.h>
byte arrToSend[] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
void test_health_check(int numofBytes)
{
Wire.beginTransmission(0x08); // Address of the MSP430 slave
Wire.write(0x22);
int i;
for(i = 0; i<numofBytes; i++)
{
Wire.write(arrToSend[i]);
}
Wire.endTransmission();
delay(1000);
Wire.requestFrom(0x08, ++numofBytes);
Serial.write("Receiving ");
Serial.print(numofBytes);
Serial.write(" byte(s):");
while(Wire.available()) {
char c = Wire.read(); // Receive a byte
Serial.write(" ");
Serial.write(c); // Print the character
numofBytes--;
if(numofBytes == 0) break;
}
Serial.write("\n");
}
void setup() {
Wire.begin(); // Join the I2C bus as a master
Serial.begin(9600);
int i;
for(i = 0; i < 10; i++)
test_health_check(i);
}
void loop() {
int i;
for(i = 0; i < 10; i++)
{
delay(2000);
test_health_check(i);
}
}
问题发生在哪里
ISR:
void suspendI2CInterrupts() {
EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT
);
}
void resumeI2CInterrupts() {
EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_RECEIVE_INTERRUPT0 + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_STOP_INTERRUPT
);
__bis_SR_register(CPUOFF + GIE); // Enter LPM with interrupts
}
#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)
{
// static uint8_t * incoming_Data = myPayload;
static uint8_t incoming_data_index = 0;
static uint8_t rcving_Data = 0;
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)
break;
case USCI_I2C_UCSTTIFG: // START condition detected with own address (slave mode only)
break;
case USCI_I2C_UCSTPIFG: // STOP condition detected (master & slave mode)
incoming_data_index = 0;
if (rcving_Data==1){
rcving_Data = 0;
cmd_receive();
}
break;
case USCI_I2C_UCRXIFG3: // RXIFG3
break;
case USCI_I2C_UCTXIFG3: // TXIFG3
break;
case USCI_I2C_UCRXIFG2: // RXIFG2
break;
case USCI_I2C_UCTXIFG2: // TXIFG2
break;
case USCI_I2C_UCRXIFG1: // RXIFG1
break;
case USCI_I2C_UCTXIFG1: // TXIFG1
break;
case USCI_I2C_UCRXIFG0: // RXIFG0
// suspendI2CInterrupts(); // Commenting this allowed us to send data the case "USCI_I2C_UCTXIFG0"
__bic_SR_register_on_exit(CPUOFF);
RXData = EUSCI_B_I2C_slaveGetData(EUSCI_B0_BASE);
// if (RXData == 0x01){
// GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
//
// GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
// }else if (RXData == 0x02){
// GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
//
// GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
// }
// *incoming_Data = RXData;
// incoming_Data++;
myPayload[incoming_data_index++] = RXData;
rcving_Data = 1;
break;
case USCI_I2C_UCTXIFG0: // TXIFG0
__bic_SR_register_on_exit(CPUOFF);
EUSCI_B_I2C_slavePutData(EUSCI_B0_BASE,
*TXData
);
TXData++;
break;
case USCI_I2C_UCBCNTIFG: // Byte count limit reached (UCBxTBCNT)
break;
case USCI_I2C_UCCLTOIFG: // Clock low timeout - clock held low too long
break;
case USCI_I2C_UCBIT9IFG: // Generated on 9th bit of a transmit (for debugging)
break;
default:
break;
}
}如果我发送4个字节、
对于前三个字节、运行"USCI_I2C_UCRXIFG0"情形、
然后运行停止条件情况"USCI_I2C_UCSTPIFG"
然后处理最后一个字节并运行"USCI_I2C_UCRXIFG0"情形、即使该情形应该在停止条件之前发生也是如此。



忽略串行输出中的第一个运行、后续运行会重写第一个索引、因为停止条件始终在处理最后一个字节之前执行、打印的第一个字节应为"0x22"。
我使用5.5k 欧姆的上拉、MSP430提供3.6V 的 VCC。
MSP430是从器件、Arduino Teensy 是主器件。