程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值?

开发过程中遇到使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值的问题如何解决?下面主要结合日常开发的经验,给出你关于使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值的解决方法建议,希望对你解决使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值有所启发或帮助;

我正在尝试通过 I2C 协议从连接到 MSP430FR5969 MCU [1] 的 TMP117 传感器 [2] 读取温度值。传感器结果寄存器中的数据为二进制补码格式,数据宽度为16位,分辨率为0.0078125℃。我使用 Code Composer studio 对 MCU 进行编程,并附上了以下代码:

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

#define SLAVE_ADDR  0x48
#define CONVERSION_READY  0x10
#define TMP117_TEMP_REG  0x00
#define TMP117_CONfig_REG  0x01
#define TMP117_RESolUTION 0.0078125f

#define CMD_TYPE_0_SLAVE      0
#define CMD_TYPE_1_SLAVE      1
#define CMD_TYPE_2_SLAVE      2

#define CMD_TYPE_0_MASTER      3
#define CMD_TYPE_1_MASTER      4
#define CMD_TYPE_2_MASTER      5

#define TYPE_0_LENGTH   1
#define TYPE_1_LENGTH   2
#define TYPE_2_LENGTH   6

#define MAX_BUFFER_SIZE     20

char temperature[] = "Temperature is: ";
char dot[] = ".";
char celcuis[] = " degree Celcius\r\n";

int i;
char text[] = " I am an MSP430FR5969\r\n";

char rx_char[5];

volatilE int rx_val = 0;

voID clockSetup();
voID gpioSetup();
voID uartSetup();
voID i2cSetup();
voID ser_output(char *str);

uint8_t MasterType1 [TYPE_1_LENGTH] = {0x02,0x20};

uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};

typedef enum I2C_ModeEnum{
    IDLE_MODE,NACK_MODE,TX_REG_ADDRESS_MODE,RX_REG_ADDRESS_MODE,TX_DATA_MODE,RX_DATA_MODE,SWITCH_TO_RX_MODE,SWITHC_TO_TX_MODE,TIMEOUT_MODE
} I2C_Mode;

I2C_Mode MasterMode = IDLE_MODE;

/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;

uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmiTindex = 0;

I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr,uint8_t reg_addr,uint8_t *reg_data,uint8_t count);

I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr,uint8_t count);
voID copyArray(uint8_t *source,uint8_t *dest,uint8_t count)
{
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmiTindex = 0;

    UCB0I2CSA = dev_addr;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG);
    UCB0IE &= ~UCRXIE;
    UCB0IE |= UCTXIE;

    UCB0CTLW0 |= UCTR + UCTXSTT;
    __bis_SR_register(LPM0_bits + GIE);

    return MasterMode;
}

I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr,uint8_t count)
{
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;

    copyArray(reg_data,TransmitBuffer,count);

    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmiTindex = 0;

    UCB0I2CSA = dev_addr;
    UCB0IFG &= ~(UCTXIFG + UCRXIFG);
    UCB0IE &= ~UCRXIE;
    UCB0IE |= UCTXIE;

    UCB0CTLW0 |= UCTR + UCTXSTT;
  __bis_SR_register(LPM0_bits + GIE);

    return MasterMode;
}

voID copyArray(uint8_t *source,uint8_t count)
{
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
        dest[copyIndex] = source[copyIndex];
    }
}

voID main(voID)
{
    WDTCTL = WDTPW | WDTHolD;

    clockSetup();
    gpioSetup();
    uartSetup();
    i2cSetup();

    __bis_SR_register(GIE);


    while (1)
    {
           _delay_cycles(500000);
            I2C_Master_ReadReg(SLAVE_ADDR,0x00,TYPE_1_LENGTH);
            copyArray(ReceiveBuffer,SlaveType1,TYPE_1_LENGTH);

            if(ReceiveBuffer[1] & CONVERSION_READY)
            {
                I2C_Master_ReadReg(SLAVE_ADDR,TYPE_1_LENGTH);
                copyArray(ReceiveBuffer,TYPE_1_LENGTH);
                _no_operation();
            }

    ltoa(rx_val,rx_char,10);
    ser_output(temperaturE);
    ser_output(rx_char);
    ser_output(dot);
    ser_output(celcuis);
    }
}

#if Defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYstemS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt voID USCI_B0_ISR(voID)
#elif Defined(__GNUC__)
voID __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (voID)
#else
#error Compiler not supported!
#endif
{
  //Must read from UCB0RXBUF
 //// uint8_t rx_val = 0;
  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
      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
        rx_val = UCB0RXBUF;
        if (RXByteCtr)
        {
          ReceiveBuffer[ReceiveIndex++] = rx_val;
          RXByteCtr--;
        }
        if (RXByteCtr == 1)
        {
          UCB0CTLW0 |= UCTXSTP;
        }
        else if (RXByteCtr == 0)
        {
          UCB0IE &= ~UCRXIE;
          MasterMode = IDLE_MODE;
          __bic_SR_register_on_exit(cpuOFF);      // Exit LPM0
        }
        break;
    case USCi_i2C_UCTXIFG0:                 // Vector 24: TXIFG0
        switch (MasterModE)
        {
          case TX_REG_ADDRESS_MODE:
              UCB0TXBUF = TransmitRegAddr;
              if (RXByteCtr)
                  MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving Now
              else
                  MasterMode = TX_DATA_MODE;        // ConTinue to transmision with the data in Transmit Buffer
              break;

          case SWITCH_TO_RX_MODE:
              UCB0IE |= UCRXIE;              // Enable RX interrupt
              UCB0IE &= ~UCTXIE;             // disable TX interrupt
              UCB0CTLW0 &= ~UCTR;            // Switch to receiver
              MasterMode = RX_DATA_MODE;    // State state is to receive data
              UCB0CTLW0 |= UCTXSTT;          // Send repeated start
              if (RXByteCtr == 1)
              {
                  //Must send stop since this is the N-1 byte
                  while((UCB0CTLW0 & UCTXSTT));
                  UCB0CTLW0 |= UCTXSTP;      // Send stop condition
              }
              break;

          case TX_DATA_MODE:
              if (TXByteCtr)
              {
                  UCB0TXBUF = TransmitBuffer[TransmiTindex++];
                  TXByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB0CTLW0 |= UCTXSTP;     // Send stop condition
                  MasterMode = IDLE_MODE;
                  UCB0IE &= ~UCTXIE;                       // disable TX interrupt
                  __bic_SR_register_on_exit(cpuOFF);      // Exit LPM0
              }
              break;

          default:
              __no_operation();
              break;
        }
        break;
    default: break;
  }
}

    voID ser_output(char *str)
    {
        while(*str !=0)
        {
            while(!(UCA0IFG&UCTXIFG));
            UCA0TXBUF = *str++;
        }
    }

    voID gpioSetup()
    {
         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;
    }

    voID clockSetup()
    {
        FRCTL0 = FRCTLPW | NWAITS_1;
        CSCTL0_H = CSKEY >> 8;
        CSCTL1 = DCORSEL | DCOFSEL_0;
        CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
        CSCTL3 = divA__1 | divS__1 | divM__1;
        CSCTL0_H = 0;
    }

    voID uartSetup()
    {
        UCA0CTL1 |= UCSWRST;
        UCA0CTL1 |= UCSSEL_2;
        UCA0BR0 = 6;
        UCA0BR1 = 0;
        UCA0MCTLW = 0xAA;
        UCA0MCTLW |= UCOS16 | UCBRF_1;
        UCA0CTL1 &= ~UCSWRST;
        UCA0IE |= UCRXIE;
    }

    voID i2cSetup()
    {
        UCB0CTLW0  |= UCSWRST;
        UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNc;
        UCB0CTLW1  |= UCSSEL_2;
        UCB0BRW   = 10;
        UCB0I2CSA = 0x0048;
        UCB0CTLW0  &= ~UCSWRST;
        UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE;
    }

我得到以下数据:

Temperature values in ReceviedBuffer,and transmitted value to PuTTY terminal

(i) 我的第一个问题是为什么我在终端上得到 RecevIEBuffer1 值和 RecevIEBuffer[0] 的缺失值。

(ii) 我的第二个问题是如何将 16 位原始数据转换为摄氏值。

非常感谢

解决方法

要从字节缓冲区中获取 16 位值,您需要将每个字节转换为 16 位值,将第二个字节移位 8 位,然后将两者进行或运算。在一行中,它看起来像这样

int16_t value = int16_t(buffer[0]) | int16_t(buffer[1]) << 8;

根据您读取的 0x0aaf 值,我猜您使用的温度传感器可能会输出以 celsius*100 为单位的值,以保持其为整数并且仍然具有 100 度的精度。因此,要获得以摄氏度为单位的值,您必须将其转换为浮点数或双精度数并除以 100.0。所以 0x0aaf 是 2735,意思是 27.35 摄氏度。

大佬总结

以上是大佬教程为你收集整理的使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值全部内容,希望文章能够帮你解决使用 MSP430FR5969 MCU 从 TMP117 传感器读取温度值所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。