工具与软件:
我设置两个 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。 我有一个公共接地和电源。