我这边在调试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;
}
}