我在MSP430FR5739微控制器上有三个INA226电流传感器连接到eUSCI_B,P1.6和P1.7。
我的I2C写入地址代码只提供一个NACKIFG,然后永远挂起。在示波器上,信号看起来几乎是完美的方形,没有过冲,上升和下降时间比时钟时间脉冲小10-20倍。我使用2k2上拉。电线在PCB上一起大约8厘米。
以前我甚至没有设法通过移动" UCB0IE | = UCNACKIE |来获得任何中断。 ..."在UCWRST区域之外的代码,我至少得到了这个。
#include "i2c.h"
#include "main.h"
#include "uart.h"
#include "ina226.h"
volatile unsigned int RXByte=0;
unsigned char TXData[] ={0, 0, 0, 0}; // Pointer to TX data
unsigned char TXByteCtr=0;
unsigned char TXByteCnt=0;
unsigned char RXByteCnt=0;
volatile unsigned int RXWord=0;
void init_i2c() {
P1SEL1 |= (BIT7 | BIT6);
P1SEL0 &= ~(BIT7 | BIT6);
uart_puts("I2C initialized\n\r");
}
void i2c_write_addr(unsigned int addr, unsigned char byte) {
UCB0CTL1 = UCSWRST; // Enable Module Reset
UCB0CTL0 |= UCMODE_3 | UCMST; // I2C, Master mode, ACLK 12MHz
UCB0CTL1 |= UCSSEL__ACLK;
UCB0BRW = 120;//200; //15; // 24MHz/240 = 100kHz Clock, 24MHz/60 = 400kHz
UCB0I2CSA = addr;
UCB0CTLW1 = UCASTP_2; // Automatic stop and interrupt, reduce deglich to 25 ns
UCB0CTLW0 |= UCTR; //Tranciever
UCB0TBCNT = 1;
UCB0CTL1 &= ~UCSWRST;
UCB0IE |= UCNACKIE | UCTXIE0 | UCRXIE | UCBCNTIE | UCNACKIE | UCSTTIE | UCSTPIE;
TXData[0] = byte;
TXByteCtr = 1; // Load TX byte counter
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(GIE + CPUOFF); // Enter LPM0 w/ interrupts
uart_puts("i2c_write_addr 6\n\r");
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
#else
#error Compiler not supported!
#endif
{
LED1OUT |= LED1B;
switch(__even_in_range(UCB0IV,0x1E)) {
case 0x00: break; // Vector 0: No interrupts break;
case 0x02: break; // Vector 2: ALIFG break;
case 0x04: // Vector 4: NACKIFG break;
UCB0CTL1 |= UCTXSTT; // Resend I2C start condition
uart_puts("NACKIFG\n\r");
break;
case 0x06: break; // Vector 6: STTIFG break;
case 0x08: break; // Vector 8: STPIFG break;
case 0x0a: break; // Vector 10: RXIFG3 break;
case 0x0c: break; // Vector 14: TXIFG3 break;
case 0x0e: break; // Vector 16: RXIFG2 break;
case 0x10: break; // Vector 18: TXIFG2 break;
case 0x12: break; // Vector 20: RXIFG1 break;
case 0x14: break; // Vector 22: TXIFG1 break;
case 0x16: // Vector 24: RXIFG0 break;
RXByte = UCB0RXBUF; // Get RX data
RXWord = RXWord <<8;
RXWord |= RXByte;
uart_puts("RXIFG0\n\r");
break;
case 0x18: // Vector 26: TXIFG0 break;
if (TXByteCtr) // Check TX byte counter
{
TXByteCtr--;
UCB0TXBUF = TXData[TXByteCtr]; // Load TX buffer
}
else
{
//UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
//UCB0CTLW0 |= UCTXSTP;
__bic_SR_register_on_exit(CPUOFF);// Exit LPM0
}
uart_puts("TXIFG0\n\r");
break;
case 0x1a: // Vector 28: BCNTIFG break;
uart_puts("BCNTIFG\n\r");
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
break;
case 0x1c: // Vector 30: clock low timeout break;
LED1OUT ^= LED1B;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
uart_puts("CLKLOWTO\n\r");
break;
case 0x1e: break; // Vector 32: 9th bit break;
default: break;
}
}
我剥掉了main.c
void configure_clock()
{
FRCTL0 = FWPW | NACCESS_2 | NPRECHG_1; // Change the NACCESS_x value to add the right amount of waitstates
// Configure Clock System
CSCTL0_H = CSKEY >> 8; // Unlock CS registers
CSCTL1 = DCOFSEL_3 | DCORSEL; // Set DCO = 24MHz
CSCTL2 = SELA__DCOCLK | SELS__DCOCLK | SELM__DCOCLK;// Set ACLK=VLO SMCLK=DCO
CSCTL3 = DIVA__2 | DIVS__1 | DIVM__2; // Set all dividers (A=12MHz, S=24MHz, M=12MHz)
CSCTL0_H = 0; // Lock CS registers
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
configure_clock();
//Configure Debug UART
init_uart_115200();
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
//Configure i2c
init_i2c();
_enable_interrupts();
i2c_write_addr(U3_ADDR, 0xFE); // Already stops here
uart_puts("INA216 ID: ");
uart_puti(i2c_read_uint(U3_ADDR));
while (1) {}
}