大家好、
客户正在调试 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;
}
}
您能帮助检查这个案例吗? 谢谢。
此致、
切里
