TI中文支持网
TI专业的中文技术问题搜集分享网站

I2C的操作问题

Part Number:MSP430F5510

我这边在调试msp430f5510+MAX7311的I2C操作,目前用的是例程里的代码调,文件“MSP430F550x_uscib0_i2c_08.c”,我把端口配置成我要使用的端口,现在发现进入中断后数据送不出去,然后从中断里退出了,从示波器上看,一直都停留在发送Slave的地址,然后SCL时钟看着也不太正常的样子

原理图:

大致如下,单片机的I2C的引连练到电平转换芯片上,引脚加个上拉,连到I2C芯片上

     

调试过程:

一旦运行到这个语句: UCB1CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

UCSCLLOW和UCBBUSY会置1,后面会进入中断,产生SCL,发送slave地址(我这边设置的是0x44),后面就不正常了,我这边想要接着继续发slave_reg地址和数据就没法发送

我通过打断点调试,发送UCB1I2CSA里的数据是有的(0x44)也有伴随SCLK。UCB1TXBUF里的数据(0x11)就发不出来,时钟也没了(从示波器上数过来,前8位数据和第9位应答位都有的,应该是第10个时钟开始,就没数据和时钟了),我搞不懂哪里出错了。

然后我参考之前有人提的一个问题:https://e2echina.ti.com/support/microcontrollers/msp430/f/msp-low-power-microcontroller-forum/5758/msp430f5418a-i2c/16163 

代码都差不多,但他起码还能发送4个数据,而我这边就发送了1个从机地址的数据就挂了。

官方例程:

代码如下:(编辑的时候,插入代码貌似没法正常显示)

#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;
}
}

Cherry Zhou:

您好,您的问题我们需要升级到英文论坛看下,有答复尽快给到您。

,

zhang chunyi:

好的

,

zhang chunyi:

有解决的办法吗?实在不行我就用软件模拟的方式去写了,这个问题已经拖了我一个礼拜了

,

Cherry Zhou:

您好,

我们的专家正在查看中。由于前几天是假期,所以进度会慢一些哈。

请问您是否在 MAX7311器件上某处连接了 AD1和 AD2? 根据您提供的图片,看起来像是一个有效的地址传输,后跟一个NAK。 

,

zhang chunyi:

是的,AD0-AD2分别是010

,

Cherry Zhou:

您好,

看起来好像显示了7个 MSB,且该列中的十六进制结果向左移动以考虑 R/W 位。 

Address (Hex)" Column显示包括 R/W 位,它实际上不是地址的一部分。 它们显示的 i2c 地址(A6-A0)为0x22。 您应该在 I2CSA 中使用0x22。 

赞(0)
未经允许不得转载:TI中文支持网 » I2C的操作问题
分享到: 更多 (0)