This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
期间用了msp430提供的历程 ,下载运行也会停在while (!(UCB0IFG & UCTXIFG)),用超时机制跳过,重新开始 ,抓取到的波形如下:
只要发起开始信号,SCL就自然变为低电平。
附件是源码
GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P5, GPIO_PIN2 + GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION ); /* * Disable the GPIO power-on default high-impedance mode to activate * previously configured port settings */ PMM_unlockLPM5(); __delay_cycles(1000); UCB0CTLW0 |= UCSWRST;// Software reset enabled UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync UCB0CTLW0 |= UCSSEL_2 ; // Use SMCLK, keep SW reset UCB0BRW = 10; // fSCL = SMCLK/10 = ~100kHz UCB0I2CSA = slaveAddress; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation void I2C_write(unsigned char *TX_buffer, int writeLength) { int i = 0; /* Clear USCI_B0 TX interrupt flag */ UCB0IFG &= ~UCTXIFG; // while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent // Set UCB0 as I2C's TX mode, and send a START condition // This will also send out the slave address UCB0CTL1 |= UCTR | UCTXSTT; //Send the number of "writeLength" bytes out for (i = 0; i < writeLength; i++) { /* Wait for TX buffer to empty */ while (!(UCB0IFG & UCTXIFG)); /* Send pointer byte */ UCB0TXBUF = *TX_buffer++; } while (!(UCB0IFG & UCTXIFG)); /* Generate Stop condition */ UCB0CTL1 |= UCTXSTP; /* Wait for Stop to finish */ while (UCB0CTL1 & UCTXSTP); }
’
#include <msp430.h> #include <stdio.h> #include <stdint.h> #include <math.h> #include "driverlib.h" uint8_t RXData[5] = {0}; void i2c_initMaster(char slaveAddress) { GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_P5, GPIO_PIN2 + GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION ); /* * Disable the GPIO power-on default high-impedance mode to activate * previously configured port settings */ PMM_unlockLPM5(); __delay_cycles(1000); UCB0CTLW0 |= UCSWRST;// Software reset enabled UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync UCB0CTLW0 |= UCSSEL_2 ; // Use SMCLK, keep SW reset UCB0BRW = 10; // fSCL = SMCLK/10 = ~100kHz UCB0I2CSA = slaveAddress; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation // EUSCI_B_I2C_initMasterParam param = {0}; // param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK; // param.i2cClk = CS_getSMCLK(); // param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS; // param.byteCounterThreshold = 0; // param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP; // EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, ¶m); // // EUSCI_B_I2C_enable(EUSCI_B0_BASE); // EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,slaveAddress); } void I2C_write(unsigned char *TX_buffer, int writeLength) { int i = 0; /* Clear USCI_B0 TX interrupt flag */ UCB0IFG &= ~UCTXIFG; // while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent // Set UCB0 as I2C's TX mode, and send a START condition // This will also send out the slave address UCB0CTL1 |= UCTR | UCTXSTT; //Send the number of "writeLength" bytes out for (i = 0; i < writeLength; i++) { /* Wait for TX buffer to empty */ while (!(UCB0IFG & UCTXIFG)); /* Send pointer byte */ UCB0TXBUF = *TX_buffer++; } while (!(UCB0IFG & UCTXIFG)); /* Generate Stop condition */ UCB0CTL1 |= UCTXSTP; /* Wait for Stop to finish */ while (UCB0CTL1 & UCTXSTP); } void I2C_read(unsigned char *RX_buffer, int readLength) { int i; /* Clear USCI_B0 TX interrupt flag */ UCB0IFG &= ~UCRXIFG; /* Set UCB0 as I2C Reciever mode */ UCB0CTL1 &= ~UCTR; /* Generate Start condition Read mode * This sends out the slave address and continues to read * until you issue a STOP */ UCB0CTL1 |= UCTXSTT; if (readLength == 1) { //要在读最后一个字节前发停止信号 while (UCB0CTL1 & UCTXSTT); // Has Start condition been sent? UCB0CTL1 |= UCTXSTP; // Send I2C stop condition immediately, since we only need to send 1 byte /* Wait for Stop to finish */ while (UCB0CTL1 & UCTXSTP); *RX_buffer = UCB0RXBUF; } else if (readLength > 1) { for (i = 0; i < (readLength - 1); i++) { /* Wait for RX buffer to fill */ while (!(UCB0IFG & UCRXIFG)) ; /* Read from I2C RX register */ *RX_buffer++ = UCB0RXBUF; } /* Generate Stop condition */ UCB0CTL1 |= UCTXSTP; /* Wait for Stop to finish */ while (UCB0CTL1 & UCTXSTP); *RX_buffer = UCB0RXBUF; //save the last byte } } unsigned char I2C_RegRead(unsigned char regAddr,unsigned char *RX_buffer, int readLength) { int i; /* Clear USCI_B0 TX interrupt flag */ UCB0IFG &= ~UCTXIFG; // while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE)); UCB0CTL1 |= UCTR + UCTXSTT; while (!(UCB0IFG & UCTXIFG)) { //if(UCB0IFG & UCNACKIFG) //UCB0IFG& UCNACKIFG //return 0; } /* Send pointer byte */ UCB0TXBUF = regAddr; while (!(UCB0IFG & UCTXIFG)) { //if(UCB0IFG & UCNACKIFG) //UCB0IFG& UCNACKIFG //return 0; } /* Clear USCI_B0 TX interrupt flag */ UCB0IFG &= ~UCRXIFG; /* Set UCB0 as I2C Reciever mode */ UCB0CTL1 &= ~UCTR; UCB0CTL1 |= UCTXSTT; if (readLength == 1) { //要在读最后一个字节前发停止信号 while (UCB0CTL1 & UCTXSTT); // Has Start condition been sent? UCB0CTL1 |= UCTXSTP; // Send I2C stop condition immediately, since we only need to send 1 byte /* Wait for Stop to finish */ while (UCB0CTL1 & UCTXSTP); *RX_buffer = UCB0RXBUF; } else if (readLength > 1) { for (i = 0; i < (readLength - 1); i++) { /* Wait for RX buffer to fill */ while (!(UCB0IFG & UCRXIFG)) ; /* Read from I2C RX register */ *RX_buffer++ = UCB0RXBUF; } /* Generate Stop condition */ UCB0CTL1 |= UCTXSTP; /* Wait for Stop to finish */ while (UCB0CTL1 & UCTXSTP); *RX_buffer = UCB0RXBUF; //save the last byte } return 1; } //------------------------------------------------------------------------------ // unsigned char I2C_Call_slave_present(unsigned char slave_address) // // This function is used to look for a slave address on the I2C bus. // // IN: unsigned char slave_address => Slave Address // OUT: unsigned char => 0: address was not found, // 1: address found //------------------------------------------------------------------------------ unsigned char I2C_Call_slave_present(unsigned char slave_address) { //UCB0STAT&=~UCNACKIFG; unsigned char slaveadr_bak, ucb0ie, returnValue;//ie2_bak ucb0ie = UCB0IE; // store old UCB0IE(中断开关寄存器) //ie2_bak = IE2; // store IE2 register slaveadr_bak = UCB0I2CSA; // store old slave address UCB0IE &= ~ UCNACKIE; // no NACK interrupt UCB0I2CSA = slave_address; // set slave address UCB0IE &= ~(UCTXIE0 + UCTXIE0); // no RX or TX interrupts __disable_interrupt(); UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP; // I2C TX, start condition while (UCB0CTL1 & UCTXSTP); /*{ UCB0TXBUF=0X89; // wait for STOP condition }*/ //返回呼叫从机的结果 returnValue = !(UCB0IFG & UCNACKIFG); // __enable_interrupt(); //IE2 = ie2_bak; // restore IE2 UCB0I2CSA = slaveadr_bak; // restore old slave address UCB0IE = ucb0ie; // restore old UCB0CTL1 return returnValue; // return whether or not // a NACK occured } unsigned char i =0; void main(void) { WDT_A_hold(WDT_A_BASE); //Set DCO FLL reference = REFO CS_initClockSignal( CS_FLLREF, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1 ); //Set Ratio and Desired MCLK Frequency and initialize DCO CS_initFLLSettle( 1000, 30 ); //Set ACLK = VLO with frequency divider of 1 CS_initClockSignal( CS_ACLK, CS_VLOCLK_SELECT, CS_CLOCK_DIVIDER_1 ); //Set SMCLK = DCO with frequency divider of 1 CS_initClockSignal( CS_SMCLK, CS_DCOCLKDIV_SELECT, CS_CLOCK_DIVIDER_1 ); //Set MCLK = DCO with frequency divider of 1 CS_initClockSignal( CS_MCLK, CS_DCOCLKDIV_SELECT, CS_CLOCK_DIVIDER_1 ); i2c_initMaster(0x4C); __bis_SR_register( GIE); // Enter LPM0 w/ interruptsCPUOFF + while(1) { __delay_cycles(1000); //I2C_RegRead(0x01,RXData,1); i=I2C_Call_slave_present(0xB8); if(i) { i = 0; } } }