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.

[参考译文] MSP430FR5969:主 I2C 至 UART

Guru**** 2538930 points
Other Parts Discussed in Thread: MSP430FR5969

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1016553/msp430fr5969-master-i2c-to-uart

器件型号:MSP430FR5969

您好!

我尝试从通过 I2C 协议连接到 MSP430FR5969 MCU 的 TM117温度传感器读取数据、然后希望通过 UART 将数据传输到 CPU (运行 PuTTY)。 我已经按照 [1]中提供的代码进行了操作 、并为 MSP430FR5969 MCU 对其进行了修改、但它无法正常工作。  我已附上 以下代码、请告诉我它有什么问题。 谢谢你。

//******************************************************************************
//   MSP430FR59xx Demo - eUSCI_B0, I2C Master multiple byte TX/RX
//
//   Description: I2C master communicates to I2C slave sending and receiving
//   3 different messages of different length. I2C master will enter LPM0 mode
//   while waiting for the messages to be sent/receiving using I2C interrupt.
//   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
//
//                                     /|\ /|\
//                   MSP430FR5969      4.7k |
//                 -----------------    |  4.7k
//            /|\ |             P1.7|---+---|-- I2C Clock (UCB0SCL)
//             |  |                 |       |
//             ---|RST          P1.6|-------+-- I2C Data (UCB0SDA)
//                |                 |
//                |                 |
//                |                 |
//                |                 |
//                |                 |
//                |                 |
//
//   Nima Eskandari
//   Texas Instruments Inc.
//   April 2017
//   Built with CCS V7.0
//******************************************************************************

#include <stdio.h>
#include <msp430.h>
#include <stdint.h>
#include <stdbool.h>

void convert(int i2c_byte, int index);              // convert each i2c byte to string
void load_uart(int index);                          // Load string into uart buffer

unsigned char *PRxData;                             // Pointer to RX data
unsigned char RXByteCtr;                            // Initialized line 73
volatile unsigned char RxBuffer[128];               // Allocate 128 byte of RAM
volatile unsigned char i2c_storage[128];            // Allocate 128
volatile unsigned char uart_storage[6][6];          // Each data will have 'xxxxx' values
volatile unsigned int ii = 0, slaveBytes = 0;

#define SLAVE_ADDR  0x48
#define TMP117_TEMP_REG  0x00
#define TMP117_CONFIG_REG  0x01
#define TMP117_RESOLUTION 0.0078125f

#define MAX_BUFFER_SIZE     20
#define CONVERSION_READY  0x10

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;                  // Stop watchdog timer

    // Configure GPIO
    P1OUT   &= ~BIT0;                             // Clear P1.0 output latch
    P1DIR   |= BIT0;                              // For LED
    P1SEL1  |= BIT6 | BIT7;                      // I2C pins
    P2SEL1  |= BIT0 | BIT1;                      // USCI_A0 UART operation
    P2SEL0  &= ~(BIT0 | BIT1);
    PM5CTL0 &= ~LOCKLPM5;                       // Disable the GPIO power-on default high-impedance mode to activate
                                                    // previously configured port settings

    // Configure one FRAM waitstate as required by the device datasheet for MCLK
    // operation beyond 8MHz _before_ configuring the clock system.
    FRCTL0 = FRCTLPW | NWAITS_1;
    // Clock System Setup
    CSCTL0_H = CSKEY >> 8;                                  // Unlock CS registers
    CSCTL1 = DCORSEL | DCOFSEL_4;                           // Set DCO to 16MHz
    CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;                   // Set all dividers
    CSCTL0_H = 0;

    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST;                            // Put eUSCI in reset
    UCA0CTLW0 |= UCSSEL__SMCLK;                     // CLK = SMCLK
    UCB0BRW = 160;                                  // fSCL = SMCLK/160 = ~100kHz
    UCA0MCTLW |= UCOS16 | UCBRF_1;
    UCA0CTLW0 &= ~UCSWRST;                          // Initialize eUSCI
    //UCA0IE |= UCRXIE;                             // Enable USCI_A0 RX interrupt

    // Configure USCI_B0 for I2C mode
    UCB0CTLW0  |= UCSWRST;                          // Software reset enabled
    UCB0CTLW0  |= UCMODE_3 | UCMST | UCSYNC;        // I2C mode, Master mode, sync
    UCB0CTLW1  |= UCSSEL_2;                         // Automatic stop generated
    UCB0BRW   = 0x0008;                             // baudrate = SMCLK / 8
    UCB0TBCNT = 0x0002;                             // number of bytes to be received
    UCB0I2CSA = 0x0048;                             // Slave address
    UCB0CTLW0  &= ~UCSWRST;

    UCA0IE |= UCRXIE;                               // Enable USCI_A0 RX interrupt
    UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE;         // Enable USCI_B0 RX interrupt

  __bis_SR_register(LPM0_bits | GIE);             // Enter LPM0 w/ interrupts

    while (1)
    {
       __delay_cycles(2000);
       while (UCB0CTL1 & UCTXSTP);                   // Ensure stop condition got sent
       UCB0CTL1 |= UCTXSTT;                          // I2C start condition

       __bis_SR_register(LPM0_bits | GIE);            // Enter LPM0 w/ interrupt
       __no_operation();

     }
}

// Convert each byte to ASCII Char Values so it can be sent via UART
void convert(int i2c_val, int ii)
{
    volatile unsigned int jj = 0, temp = 0, bit_position = 10000;
    for (jj = 0; jj<slaveBytes; jj++)
    {
        temp = i2c_val/bit_position;
        i2c_val -= temp*bit_position;
        bit_position /= 10;
        temp += 0x30;
        uart_storage[ii][jj] = temp;
    }
}

//Load data onto UART
void load_uart(int ii)
{
    volatile unsigned int jj = 0;
    for(jj = 0; jj<slaveBytes; jj++)
    {
        while (!(UCA0IFG&UCTXIFG0));                 // UART TX buffer ready?
        UCA0TXBUF = uart_storage[ii][jj];           // load buffer one character at a time
    }                                               // Load buffer character by character
}

#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      UCB0CTL1 |= UCTXSTT;                  // I2C start condition
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
     // RXData = UCB0RXBUF;                   // Get RX data
      RXByteCtr--;                                    // Initialized on line 73
       if (RXByteCtr)
       {
           if (ii == 0)
           {
               slaveBytes = UCB0RXBUF;                 // Byte# fits 1st Slave Byte
               RXByteCtr = slaveBytes-1;
           }

           i2c_storage[ii] = UCB0RXBUF;                // Move each I2C byte to storage
           convert(i2c_storage[ii],ii);                // Convert byte to string
           load_uart(ii);
           //      while (!(IFG2&UCA0TXIFG));          // UART TX buffer ready?
           //      UCA0TXBUF = 'x';                    // Test Buffer
           ii++;
       }

       else
       {
           ii = slaveBytes-1;                          // Unclear to team, why necessary
           i2c_storage[ii] = UCB0RXBUF;                // Move final RX data to PRxData
           convert(i2c_storage[ii],ii);
           load_uart(ii);

                   while (!(UCA0IFG&UCTXIFG));         // USCI_A0 TX buffer ready?
                   UCA0TXBUF ='\n';                    // format easier reading
                   UCB0CTL1 & UCTXSTP;                 // Generate I2C stop condition
           ii = 0;

           __bic_SR_register_on_exit(CPUOFF);          // Exit LPM0
       }

      //__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
      break;
    case USCI_I2C_UCTXIFG0:  break;         // Vector 24: TXIFG0
    case USCI_I2C_UCBCNTIFG:                // Vector 26: BCNTIFG
      P1OUT ^= BIT0;                        // Toggle LED on P1.0
      break;
    case USCI_I2C_UCCLTOIFG: break;         // Vector 28: clock low timeout
    case USCI_I2C_UCBIT9IFG: break;         // Vector 30: 9th bit
    default: break;
  }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它到底是如何不起作用的?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 David:

    感谢你的答复。 代码运行时没有任何错误、但我在 PuTTY 终端上看不到任何已传输的值。 我还在示波器上检查了 I2C 信号波形、但 CLK 和 SDA 线上没有时钟和数据。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    因为您不执行任何操作、所以不会有 I2C 活动。 在设置硬件之后、在主循环之前、您进入 LPM0。 因为没有任何东西可以唤醒它、所以就结束了

    哦、UART 接收中断可能会执行该操作。 不同之处在于、当您启用该中断时、我看不到 ISR。

    修复此问题应该很容易。 从简单开始、然后从那里构建。 第一件事是验证 UART 是否可以传输数据。 您还可以使用调试器来跟踪程序流并查看其工作情况。 学习使用它。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 David:

    感谢你的答复。 我移除了 LPM0、现在可以看到 USCI B0接收缓冲器和 USCI A0发送缓冲器中的值。 但在 PuTTY 上、我只能看到如下所示的括号符号。 我不确定如何解决此问题。  

    如果我删除"convert (i2c_storage[i]、ii);//将字节转换为字符串"函数、则我将获得以下字符。