工具与软件:
我设置两个 MSP430g2553之间的 I2C 通信。 我的从器件 MSP430g2553处于传输模式。 从设备执行 ADC 过程、在该过程中、电位器连接到其中一个通道。 主器件处于接收模式、从从器件获取该数据并通过 UART 发送。 我所面临的问题是、当我在示波器上进行检查时、SCL 和 SDA 信号仍然为高电平。 我在此处包含了我的主代码和从代码。
MASTERCODE (码)...
#include <msp430.h> unsigned char RXData[2]; unsigned int RXADCValue; // Variable to store the reconstructed 10-bit ADC value void configure_uart(void); // Function to configure UART void uart_print(char *str); // Function to print a string over UART void uart_print_number(unsigned char num); // Function to print a number over UART int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT // ** UART Configuration ** configure_uart(); // Initialize UART for serial communication P1OUT &= ~BIT0; // P1.0 = 0 (Turn off LED) P1DIR |= BIT0; // P1.0 set as output // ** I2C Configuration ** P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2 |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x048; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt // RXCompare = 0; // Used to check incoming data // UCB0CTL1 |= UCTXSTT; // Print initial message to UART uart_print("Starting I2C Master and UART Communication...\r\n"); while (1) { while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 &= ~UCTR; // Put it in recieve mode UCB0CTL1 |= UCTXSTT; // I2C start condition while (UCB0CTL1 & UCTXSTT); // Wait for start condition to be sent // UCB0CTL1 |= UCTXSTP; // I2C stop condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts RXADCValue = (RXData[0] << 2) | (RXData[1] >> 6); // Combine high and low bytes // Print received data to UART uart_print("Received ADC Value: "); uart_print_number(RXADCValue); uart_print("\r\n"); // if (RXData != RXCompare) // Trap CPU if data is not as expected // { // P1OUT |= BIT0; // Turn on LED (P1.0) to indicate error // while (1); // Trap CPU // } // // RXCompare++; // Increment correct RX value } } // Function to configure UART for 9600 baud rate at 1 MHz clock void configure_uart(void) { P1SEL |= BIT1 + BIT2; // Set P1.1 = RXD, P1.2 = TXD P1SEL2 |= BIT1 + BIT2; UCA0CTL1 |= UCSWRST; // Put state machine in reset UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 104; // 1MHz 9600 (N = 1MHz/9600) UCA0BR1 = 0; UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt } // Function to print a string over UART void uart_print(char *str) { while (*str != '\0') // Loop until end of string { while (!(IFG2 & UCA0TXIFG)); // Wait until the TX buffer is ready UCA0TXBUF = *str++; // Send each character } } // Function to print a number over UART as a string void uart_print_number(unsigned char num) { char buf[5]; // Buffer to hold ASCII string of the number (0-255) char *str = &buf[4]; *str = '\0'; do { *--str = (num % 10) + '0'; // Get the last digit and convert to ASCII num /= 10; // Remove the last digit } while (num); uart_print(str); // Print the resulting number string } // USCI_B0 Data ISR #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void) #else #error Compiler not supported! #endif { static unsigned char rx_byte_count = 0; RXData[rx_byte_count++] = UCB0RXBUF; // Read received byte into buffer if (rx_byte_count >= 2) // If two bytes have been received { rx_byte_count = 0; // Reset counter for next transmission __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 after two bytes are received } }
从代码...
// //****************************************************************************** #include <msp430.h> unsigned char TXData[2] = {0,0}; // Variable to hold TX data (ADC value) unsigned int adc_values[16]; // Buffer to hold 16 ADC samples (for the ADC reference code structure) //unsigned int *adc_ptr = adc_values; // Pointer to iterate through ADC buffer void configure_adc(void); // Function to configure ADC int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog // Configure LED on P1.0 for indication P1DIR |= BIT0; // Set P1.0 as output (LED) P1OUT &= ~BIT0; // Turn off LED initially // Configure I2C pins P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2 |= BIT6 + BIT7; // Configure I2C Slave UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode UCB0I2COA = 0x048; // Own Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0I2CIE |= UCSTTIE; // Enable Start condition interrupt IE2 |= UCB0TXIE; // Enable TX interrupt configure_adc(); // Configure the ADC for reading // Infinite loop to keep the code running while (1) { __bis_SR_register(CPUOFF + GIE); // Enter LPM0 with interrupts enabled } } // Function to configure ADC for multi-channel sampling as in the reference code void configure_adc(void) { ADC10CTL1 = INCH_5 + CONSEQ_2; // A2 repeat CHANNEL CONVERSION ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE; // Sample and Hold Time + Multi-Sample Conversion + ADC on + Enable Interrupt ADC10AE0 = BIT5; // Enable analog input P1.5 ADC10DTC1 = 1; // 16 conversions (reference code) } // ADC10 interrupt service routine to handle ADC conversion completion #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { unsigned int adc_value = ADC10MEM; TXData[0] = (unsigned char)((adc_value >> 2) & 0xFF); // Read the lower8 bits of ADC value TXData[1] = (unsigned char)((adc_value & 0x03) << 6); P1OUT ^= BIT0; // Toggle LED to indicate ADC conversion __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } // USCI_B0 Data ISR to transmit data to the I2C master #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void) #else #error Compiler not supported! #endif { static unsigned char byte_counter = 0; // Send the high byte first, followed by the low byte UCB0TXBUF = TXData[byte_counter++]; // Load TX buffer with the current byte to send to master if (byte_counter >= 2) // If both bytes have been sent { byte_counter = 0; // Reset counter for next transmission } __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } // USCI_B0 State ISR for handling start condition #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCIAB0RX_ISR (void) #else #error Compiler not supported! #endif { UCB0STAT &= ~UCSTTIFG; // Clear start condition interrupt flag // Trigger ADC sampling when I2C start condition is detected ADC10CTL0 &= ~ENC; // Disable ADC before starting new conversion while (ADC10CTL1 & ADC10BUSY); // Wait if ADC is busy ADC10CTL0 |= ENC + ADC10SC; // Enable and start ADC sampling }
I ma 通过10k 上拉电阻器连接 SDA 和 SCL。 我有一个公共接地和电源。