大家好、
客户正在调试 msp430F5510+MAX7311的 I2C 操作、目前正在使用例程中的代码 "MSP430F550x_uscib0_i2c_08.c"。 客户配置好端口后、现在它发现在进入中断后无法发送数据、然后退出中断。 从范围来看、它停留在从器件被发送的地址、然后 SCL 时钟似乎有问题。
原理图如下、单片的 I2C 连接到一个电平转换芯片、一个上拉引脚连接到 I2C 芯片:
运行至:UCB1CTL1 |= UCTR + UCTXSTT;// I2C TX、启动条件
UCSCLLOW 和 UCBBUSY 被置位为1、然后进入一个中断、生成 SCL、并发送从机地址(0x44被置位)。 之后无法继续发送 slave_reg 地址和数据。
客户通过断点进行调试、并使用 SCLK 在 UCB1I2CSA (0x44)中发送数据。 无法发送 UCB1TXBUF 中的数据(0x11)并且此时钟丢失(在示波器中、前八位数据和第九个确认位可用。 应该没有从第10个时钟开始的数据或时钟)。
例程如下所示:
规范如下:
#include <msp430f5510.h> #include "cmd.h" #include <stdint.h> #include <stdio.h> unsigned char timeFlag; unsigned char *PTxData; // Pointer to TX data unsigned char TXByteCtr; const unsigned char TxData[] = // Table of data to transmit { 0x11,0x22,0x33,0x44,0x55 }; void writeI2C() { PTxData = (unsigned char *)TxData; // TX array start address // Place breakpoint here to see each // transmit operation. TXByteCtr = sizeof TxData; // Load TX byte counter UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(GIE); __no_operation(); while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent } void GPIO_Init(void) { PJDIR |= 0x01; // PJ.0 output } void I2C_Init(void) { P4SEL |= 0x06; // Assign I2C pins to UCB1 P4.1 P4.2 UCB1CTL1 |= UCSWRST; // Enable SW reset UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB1BR1 = 0; UCB1I2CSA = 0x44; UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB1IE |= UCTXIE; // Enable TX interrupt } void timer0_Init(void) { TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = 52616; // ~50ms TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR } void uart_Init(void) { P4SEL |= BIT4+BIT5; // P4.4,5 = USCI_A1 TXD/RXD UCA1CTL1 |= UCSWRST; // **Put state machine in reset** UCA1CTL1 |= UCSSEL_2; // SMCLK UCA1BR0 = 9; // 1MHz 115200 (see User's Guide) UCA1BR1 = 0; // 1MHz 115200 UCA1MCTL |= UCBRS_1 + UCBRF_0; // Modulation UCBRSx=1, UCBRFx=0 UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA1IE |= UCRXIE; // Enable USCI_A1 RX interrupt } void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT GPIO_Init(); I2C_Init(); timer0_Init(); uart_Init(); _EINT(); // __bis_SR_register(GIE); PrintfBufLen = sprintf(PrintfBuf,"\r\nI2C Switch Debug:\r\n"); UARTwrite(PrintfBuf,PrintfBufLen); while(1) { UartTx(); if(timeFlag == 1) { timeFlag = 0; writeI2C(); } } } // Timer0 A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) { PJOUT ^= 0x01; // Toggle P1.0 timeFlag++; } #pragma vector=USCI_A1_VECTOR __interrupt void USCI_A1_ISR(void) { // while (!(UCA1IFG&UCTXIFG)); // USCI_A1 TX buffer ready? // UCA1TXBUF = UCA1RXBUF; // TX -> RXed character } #pragma vector = USCI_B1_VECTOR __interrupt void USCI_B1_ISR(void) { switch(__even_in_range(UCB1IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: break; // Vector 10: RXIFG case 12: // Vector 12: TXIFG if (TXByteCtr) // Check TX byte counter { UCB1TXBUF = *PTxData++; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB1CTL1 |= UCTXSTP; // I2C stop condition UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag } default: break; } }
您能帮助检查这个案例吗? 谢谢。
此致、
切里