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.

[参考译文] MSP430FR4133:使用ADC和I2C连接到外部DAC以进行模拟输出

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1092197/msp430fr4133-using-adc-and-i2c-to-connect-to-an-external-dac-for-analogue-output

部件号:MSP430FR4133

我一直在使用ADC,它可以从外部源转换电压读数。 我从ADCMEMM0中得到的数值范围是20到120。 我尝试使用I2C传输这些值,但由于某些原因,它们不起作用。

我已经尝试实施了一些示例,例如TI提供的一个示例文件eusci_b_i2c_ex3_masterTxMultiple.c. 按其原由实施会导致程序卡在eusci_b_i2c.c中的第318行,我不明白为什么,因为处理中断的方式非常复杂。 我也使用 了这个资源 ,但它用于另一个MSP430模型,它的中断是不同的,我也不知道如何实施。  

另一个问题是,我是否一次发送一个字节的ADC结果? 或者,我是否指定MSP430读取并存储数据然后传输数据的特定时间量?

下面是第二个资源的代码:

//i2c implementation using the TI_I2C functions, gets stuck in the 
//interrupt at the end of the definitions file



#include <msp430.h>
#include <driverlib.h>
#include "TI_USCI_I2C_master.h"
#include <stdio.h>
#include <math.h>

unsigned int ADC_Result = 0;
unsigned char SlaveAddress = 0xC0;
unsigned char char_ADC_result[1] = {0};
unsigned long long numbin_watch,numbin = 0;
int length = 0;
int numbinArray[10];
int count = 0;



long long convert(int num) {
  long long numbin = 0;
  int rem;
  long long i = 1;
  
  while (num!=0) {
    rem = num % 2;
    num /= 2;
    numbin += rem * i;
    i *= 10;
  }
  
  return numbin;
}

int lengthOfInt(unsigned long long numbin){
  
  int count = 0;
  
  while (numbin != 0)
  {
    numbin /= 10;
    count++;
  }
  return count;
}

int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
  
  // Configure GPIO
  P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
  P1OUT &= ~BIT0;                                          // P1.0 LED off
  
  // Configure ADC A9 pin
  SYSCFG2 |= ADCPCTL9;
  
  
  // Configure Pins for I2C
  //P5SEL0 |= BIT2 | BIT3;                                    // I2C pins, select pin P5.2 for SDA and pin P5.3 for SCL
  
  // Disable the GPIO power-on default high-impedance mode to activate
  // previously configured port settings
  PM5CTL0 &= ~LOCKLPM5;
  
  __enable_interrupt(); //worked without this, uncomment to test with it
  
  // Configure ADC10
  ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks----ADCSHTx : 0000b = 4 ADCCLK cycles 0001b = 8 ADCCLK cycles 0010b = 16 ADCCLK cycles 0011b = 32 ADCCLK cycles
  ADCCTL1 |= ADCSHP | ADCSSEL_0 | ADCCONSEQ_2;             // ADCCLK = MODOSC; sampling timer   ADCCONSEQ_2 = Repeat-single-channel ---- remove it for single channel
  ADCCTL2 |= ADCRES_1 ;                                    // 10/8-bit conversion results ADCRES_1 = 10 bit////ADCRES_0 = 8 bit
  ADCMCTL0 |= ADCINCH_9 | ADCSREF_0;                       // A9 ADC input select; pin 8.1 use this for mic setup
  
  ADCIFG &= ~0x01;                                         //clear interrupt flag
  
  
  ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt
  
  
//  // Configure USCI_B0 for I2C mode
//  UCB0CTLW0 |= UCSWRST;                                   // put eUSCI_B in reset state
//  UCB0CTLW0 |= UCMODE_3 | UCMST;                          // I2C master mode, SMCLK
//  //UCB0CTLW0 |= UCSLA10 | UCSSEL_2;                      // slave has 7 bit address, source clock is SMCLK
//  UCB0BRW = 0x8;                                          // baudrate = SMCLK / 8
//  UCB0CTLW0 &=~ UCSWRST;                                  // clear reset register
//  UCB0IE |= UCTXIE0 | UCNACKIE;                           // transmit and NACK interrupt enable
     
     
    TI_USCI_I2C_transmitinit(SlaveAddress,0x01);  // init transmitting with USCI and config

  
  while(1)
  {
    ADCCTL0 |= ADCENC | ADCSC;                          // Sampling and conversion start, could use ACCTL0 = 0x03
    __bis_SR_register(LPM0_bits | GIE);               // LPM0, ADC_ISR will force exit LOW POWER MODE 0
    //__no_operation();                                 // For debug only
    if (ADC_Result < 0x00F){
      P1OUT &= ~BIT0;                                 // Clear P1.0 LED off
    }
    else{
      P1OUT |= BIT0;                                   // Set P1.0 LED on
    }
    
    

    char_ADC_result[0] = ADC_Result;

    __delay_cycles(5000);
    
    while ( TI_USCI_I2C_notready() );         // wait for bus to be free
    //if ( TI_USCI_I2C_slave_present(SlaveAddress) )    // slave address may differ from
    //{                                         // initialization
      //while ( TI_USCI_I2C_notready() );         // wait for bus to be free
      TI_USCI_I2C_transmit(1,char_ADC_result);       // start transmitting 
    //}
    
    //__bic_SR_register_on_exit(LPM0_bits);         // Exit LPM0
    //LPM0;                                                     // Remain in LPM0 until all data is TX'd
  }
}

// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
  {
  case ADCIV_NONE:
    break;
  case ADCIV_ADCOVIFG:
    break;
  case ADCIV_ADCTOVIFG:
    break;
  case ADCIV_ADCHIIFG:
    break;
  case ADCIV_ADCLOIFG:
    break;
  case ADCIV_ADCINIFG:
    break;
  case ADCIV_ADCIFG:
    ADC_Result = ADCMEM0;
    __bic_SR_register_on_exit(LPM0_bits);          // Clear CPUOFF bit from LPM0
    break;
  default:
    break;
  }  
}

下面是TI提供的示例代码:

//uses TI board-specific i2c example, gets stuck in an interrupt again, line 318 in esci_b_i2c.c


#include <msp430.h>
#include <driverlib.h>
#include "Board.h"

#define SLAVE_ADDRESS 0xC0
#define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ   1000 //Target frequency for SMCLK in kHz
#define CS_SMCLK_FLLREF_RATIO   30 //SMCLK/FLLRef Ratio



unsigned int ADC_Result = 0;

// Pointer to TX data
uint8_t TXData = 0;
uint8_t TXByteCtr;


int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
  
  // Configure GPIO
  P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
  P1OUT &= ~BIT0;                                          // P1.0 LED off
  
  // Configure ADC A9 pin
  SYSCFG2 |= ADCPCTL9;
   
  //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(
                   CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ,
                   CS_SMCLK_FLLREF_RATIO
                     );
  
  //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
                       );
  
  // Configure Pins for I2C , SCL 5.3, SDA 5.2
  GPIO_setAsPeripheralModuleFunctionInputPin(
                                             GPIO_PORT_UCB0SCL,
                                             GPIO_PIN_UCB0SCL,
                                             GPIO_FUNCTION_UCB0SCL
                                               );
  GPIO_setAsPeripheralModuleFunctionInputPin(
                                             GPIO_PORT_UCB0SDA,
                                             GPIO_PIN_UCB0SDA,
                                             GPIO_FUNCTION_UCB0SDA
                                               );
  
  /*
  * Disable the GPIO power-on default high-impedance mode to activate
  * previously configured port settings
  */
  PMM_unlockLPM5();
  
  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, &param);
  
  //Specify slave address
  EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,
                              SLAVE_ADDRESS
                                );
  
  //Set Master in receive mode
  EUSCI_B_I2C_setMode(EUSCI_B0_BASE,
                      EUSCI_B_I2C_TRANSMIT_MODE
                        );
  
  //Enable I2C Module to start operations
  EUSCI_B_I2C_enable(EUSCI_B0_BASE);
  
  EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
                             EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
                               EUSCI_B_I2C_NAK_INTERRUPT
                                 );
  //Enable master Receive interrupt
  EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
                              EUSCI_B_I2C_TRANSMIT_INTERRUPT0 +
                                EUSCI_B_I2C_NAK_INTERRUPT
                                  );
  
  // Configure ADC10
  ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks----ADCSHTx : 0000b = 4 ADCCLK cycles 0001b = 8 ADCCLK cycles 0010b = 16 ADCCLK cycles 0011b = 32 ADCCLK cycles
  ADCCTL1 |= ADCSHP | ADCSSEL_0 | ADCCONSEQ_2;             // ADCCLK = MODOSC; sampling timer   ADCCONSEQ_2 = Repeat-single-channel ---- remove it for single channel
  ADCCTL2 |= ADCRES_1 ;                                    // 10/8-bit conversion results ADCRES_1 = 10 bit////ADCRES_0 = 8 bit
  ADCMCTL0 |= ADCINCH_9 | ADCSREF_0;                       // A9 ADC input select; pin 8.1 use this for mic setup
  ADCIFG &= ~0x01;                                         //clear interrupt flag
  ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt  
  
  while(1)
  {
    ADCCTL0 |= ADCENC | ADCSC;                          // Sampling and conversion start, could use ACCTL0 = 0x03
    __bis_SR_register(LPM0_bits | GIE);               // LPM0, ADC_ISR will force exit LOW POWER MODE 0
    //__no_operation();                                 // For debug only
    if (ADC_Result < 0x00F){
      P1OUT &= ~BIT0;                                 // Clear P1.0 LED off
    }
    else{
      P1OUT |= BIT0;                                   // Set P1.0 LED on
    }
    __delay_cycles(1000);                   // Delay between transmissions
    TXByteCtr = 1;                          // Load TX byte counter
    TXData = ADC_Result;
    
    while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
    
    EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData++);
    
    //__bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
    // Remain in LPM0 until all data
    // is TX'd
    // Increment data byte
    
  }
} 



// ADC interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = ADC_VECTOR
__interrupt void ADC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
  {
  case ADCIV_NONE:
    break;
  case ADCIV_ADCOVIFG:
    break;
  case ADCIV_ADCTOVIFG:
    break;
  case ADCIV_ADCHIIFG:
    break;
  case ADCIV_ADCLOIFG:
    break;
  case ADCIV_ADCINIFG:
    break;
  case ADCIV_ADCIFG:
    ADC_Result = ADCMEM0;
    __bic_SR_register_on_exit(LPM0_bits);          // Clear CPUOFF bit from LPM0
    break;
  default:
    break;
  }  
}


//------------------------------------------------------------------------------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
{
    switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
  {
        case USCI_NONE:             // No interrupts break;
            break;
        case USCI_I2C_UCALIFG:      // Arbitration lost
            break;
        case USCI_I2C_UCNACKIFG:    // NAK received (master only)
            //resend start if NACK
            EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
            break;
        case USCI_I2C_UCTXIFG0:     // TXIFG0
            // Check TX byte counter
            if (TXByteCtr)
            {
                EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData++);
                // Decrement TX byte counter
                TXByteCtr--;
            }
            else
            {
                EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
                // Exit LPM0
                __bic_SR_register_on_exit(CPUOFF);
            }
            break;
        default:
            break;
  }
}

欢迎提出其他解决方案的建议,或者我应该阅读的任何其他资源将会非常有帮助,以使其发挥作用。 提前感谢您的参与和阅读。

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

    您使用的是什么DAC?

    > #define slaver_address 0xC0

    我可以通过看这个来判断它是不正确的,因为I2C地址只有7位。 也许应该是0x60? 应在DAC数据表中说明。

    DAC数据表还应说明您应该如何调整数据的速度-它是否具有内部时钟来生成固定的输出速率,或者您是否需要在程序中使用计时器来执行此操作。

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

    我正在使用 这个分路板 (BOB-1.2918万),它已经具有上拉电阻器,只是使DAC ( MCP4725)的使用更容易

    地址位是1 0 0 A2 A1 A0 0,其中A2和A1默认为0,A0接地,最后0是R/wbar位。 如果我忽略R/wbar位,它是0x60,这是对的,我不知道应该忽略它。 SCL线是否也是处理DAC中数据的时钟?

    非常感谢您花时间阅读并回复我的帖子。 如有任何进一步的帮助,我们将不胜感激。

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

    是的,地址看起来像是0x60。 (R/W位不是地址的一部分。)  

    根据DAC数据表[图6-1],您需要发送两个字节(ESCI发送第一个字节,您发送另两个字节),12位值右对齐。 当最后一个字节完成时,DAC输出将立即更新[注释2]。 这意味着您的计划需要完成进度。 您的__delay_cycles(5000)将启动(~200Hz),但长期而言,您可能需要计时器。  

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

    因此,对于每12位数据,我将发送2个字节。 根据数据表,第一个字节将有0 PD1 PD0 4个数据位,然后另一个字节将有剩余的8位数据? 那么,对于下一批数据,这两个字节会重复出现吗?

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

    是的。 理论上,您只需直接发送ADCMEM值(PD=0),但您可能需要缩放10位值(左移2),以从DAC中获得完全缩放。

    图6-1还提到了在同一事务中发送两个额外字节的选项,这将(我认为?) 覆盖前两个字节。 我不确定他们对该功能的想法;我怀疑您不想这样做。

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

    再次感谢您花时间回答我的初学者问题。 如果我设法弄清楚,我会将帖子标记为已解决,但如果不能,我会将所有内容保留在一个帖子中。

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

    您好,Yiannis,

    此问题是否已解决? 或者您是否仍需要一些支持?

    谢谢!

    此致

    强生

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

    我今天用主板测试了我的电路,但它仍然不工作。 我是发布新帖子还是在此处回复评论?

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

    我会在这里回复我的问题,以节省一些时间。

    //uses TI board-specific i2c example, gets stuck in an interrupt again, line 318 in esci_b_i2c.c, multibyte
    
    
    #include "project_definitions.h"
    
    
    int order2 = 0;
    
    
    int main(void)
    {
      WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
      
      // Configure GPIO
      P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
      P1OUT &= ~BIT0;                                          // P1.0 LED off
      P5REN |= BIT0;
      P5OUT |= BIT0;
      
      // Configure ADC A9 pin
      SYSCFG2 |= ADCPCTL9;
      
      //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(CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ, CS_SMCLK_FLLREF_RATIO);
      
      //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);
      
      // Configure Pins for I2C , SCL 5.3, SDA 5.2
      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SCL, GPIO_PIN_UCB0SCL, GPIO_FUNCTION_UCB0SCL);
      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SDA, GPIO_PIN_UCB0SDA, GPIO_FUNCTION_UCB0SDA);
      
      /*
      * Disable the GPIO power-on default high-impedance mode to activate
      * previously configured port settings
      */
      PMM_unlockLPM5();
      
      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 = 255;
      param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
      EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
      
      //Specify slave address
      EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,SLAVE_ADDRESS);
      
      //Set Master in receive mode
      EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
      
      //Enable I2C Module to start operations
      EUSCI_B_I2C_enable(EUSCI_B0_BASE);
      EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
      
      //Enable master Receive interrupt
      EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
      
      //set a timeout for 34ms
      EUSCI_B_I2C_setTimeout(EUSCI_B0_BASE,EUSCI_B_I2C_TIMEOUT_34_MS);
      
      // Configure ADC10
      ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks----ADCSHTx : 0000b = 4 ADCCLK cycles 0001b = 8 ADCCLK cycles 0010b = 16 ADCCLK cycles 0011b = 32 ADCCLK cycles
      ADCCTL1 |= ADCSHP | ADCSSEL_0 | ADCCONSEQ_2;             // ADCCLK = MODOSC; sampling timer   ADCCONSEQ_2 = Repeat-single-channel ---- remove it for single channel
      ADCCTL2 |= ADCRES_1 ;                                    // 10/8-bit conversion results ADCRES_1 = 10 bit////ADCRES_0 = 8 bit
      ADCMCTL0 |= ADCINCH_9 | ADCSREF_0;                       // A9 ADC input select; pin 8.1 use this for mic setup
      ADCIFG &= ~0x01;                                         //clear interrupt flag
      ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt  
      
      
      
      while(1)
      {
        ADCCTL0 |= ADCENC | ADCSC;                          // Sampling and conversion start, could use ACCTL0 = 0x03
        __bis_SR_register(LPM0_bits | GIE);               // LPM0, ADC_ISR will force exit LOW POWER MODE 0
        //__no_operation();                                 // For debug only
        if (ADC_Result < 0x00F){
          P1OUT &= ~BIT0;                                 // Clear P1.0 LED off
        }
        else{
          P1OUT |= BIT0;                                   // Set P1.0 LED on
        }
        __delay_cycles(5000);                   // Delay between transmissions
    
        //convert the adc result to binary
        numbin = convertIntToBin(ADC_Result);
        
        //add the binary number to the numbinArray
        ptr_numbinArray = addToArray(numbin);
        i = 0;
        for (i = 0;i<=10; i++){ //to shift the binary 2 to the left make i = 2; and i<= 12;
          numbinArray[i] = *(ptr_numbinArray + i); 
        }
        
        //split numbinArray up to the two required bytes
        //byte 1
        i = 8;
        c = 7;
        for (i = 8; i<=11; i++){
          byte1[c] = numbinArray[i];
          c--;
        }
        
        //byte 2
        i = 0;
        c = 7;
        for (i = 0; i<=7; i++){ 
          byte2[c] = numbinArray[i];
          c--;
        }
        
        data1 = convertBinToInt(ptr_byte1);
        data2 = convertBinToInt(ptr_byte2);
        
        TXByteCtr = 1000;                          // Load TX byte counter
        
        if (order == 1){
          TXData = data1;
          order = 2;
          byteNum++;
          data1 = 0;
        }
        else if (order == 2){
          TXData = data2;
          order = 1;
          byteNum++;
          data2 = 0;
        }
        
        
        while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
        
        if(order2 == 0){
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData);
        order2++;
        }
        else if (order2 == 1){
        EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData);
        }
        else if (byteNum == 900){
        EUSCI_B_I2C_masterSendMultiByteFinish(EUSCI_B0_BASE, TXData);
        byteNum = 0;
        }
        
        //__bis_SR_register(LPM0_bits | GIE);        // Enter LPM0 w/ interrupts, changed from CPUOFF + GIE
        // Remain in LPM0 until all data
        // is TX'd
        // Increment data byte
      }
    }
    
    
    
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
      {
      case ADCIV_NONE:
        break;
      case ADCIV_ADCOVIFG:
        break;
      case ADCIV_ADCTOVIFG:
        break;
      case ADCIV_ADCHIIFG:
        break;
      case ADCIV_ADCLOIFG:
        break;
      case ADCIV_ADCINIFG:
        break;
      case ADCIV_ADCIFG:
        ADC_Result = ADCMEM0;
        __bic_SR_register_on_exit(LPM0_bits);          // Clear CPUOFF bit from LPM0
        break;
      default:
        break;
      }  
    }
    
    
    //------------------------------------------------------------------------------
    // The USCIAB0TX_ISR is structured such that it can be used to transmit any
    // number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
    // points to the next byte to transmit.
    //------------------------------------------------------------------------------
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_B0_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_B0_VECTOR)))
    #endif
    void USCIB0_ISR(void)
    {
      switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
      {
      case USCI_NONE:             // No interrupts break;
        break;
      case USCI_I2C_UCALIFG:      // Arbitration lost
        break;
      case USCI_I2C_UCNACKIFG:    // NAK received (master only)
        //resend start if NACK
        EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
        break;
      case USCI_I2C_UCTXIFG0:     // TXIFG0
        // Check TX byte counter
        if (TXByteCtr)
        {
          EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData);
          // Decrement TX byte counter
          TXByteCtr--;
        }
        else
        {
          EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
          // Exit LPM0
          __bic_SR_register_on_exit(LPM0_bits);
        }
        break;
      default:
        break;
      }
    }
    
    

    这是我目前为止拥有的代码。 这些值进入TXBUF,但我在"EUSCI_B_I2C_masterSendMultiByteNext"函数中被此中断(在While循环中)卡住。

        //If interrupts are not used, poll for flags
        if (!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE)){
            //Poll for transmit interrupt flag.
            while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
        }
    

    它过去在此时被卡在“EUSCI_B_I2C_masterSendMultiByteStart”中:

        //Poll for transmit interrupt flag.
        while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
    

    这一点与之前相同,但位于在另一个函数之后调用的函数。 第144行和第148行。

    项目定义.h:

    #include <msp430.h>
    #include <driverlib.h>
    #include "Board.h"
    #include <math.h>
    
    
    #define SLAVE_ADDRESS 0xC0
    #define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ   1000 //Target frequency for SMCLK in kHz
    #define CS_SMCLK_FLLREF_RATIO   30 //SMCLK/FLLRef Ratio
    
    int c = 0, i = 0;
    int order = 1, byteNum = 1;
    unsigned int ADC_Result = 0;
    long long numbin = 0;
    
    // Pointer to TX data
    uint8_t TXData = 0;
    uint16_t TXByteCtr;
    
    uint8_t* ptr_numbinArray;
    uint8_t numbinArray[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
    
    uint8_t byte1[8] = {0,0,0,0,0,0,0,0};  //postions 5,6,7,8 are 0 for PD0, PD1, C2, C1 respectively
    uint8_t byte2[8] = {0,0,0,0,0,0,0,0};
    uint8_t* ptr_byte1 = byte1;
    uint8_t* ptr_byte2 = byte2;
    
    uint8_t data1 = 0;
    uint8_t data2 = 0;
    
    long long convertIntToBin(int num) {
      long long numbin = 0;
      int rem;
      long long i = 1;
      
      while (num!=0) {
        rem = num % 2;
        num /= 2;
        numbin += rem * i;
        i *= 10;
      }
      return numbin;
    }
    
    uint8_t* addToArray(long long numbin){
      int pos = 0;  
      static uint8_t numbinArray[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
      while (numbin != 0){
        numbinArray[pos] = numbin % 10;
        numbin /= 10;
        pos++;
      }    
      return numbinArray;
    }
    
    uint8_t convertBinToInt(uint8_t bin[8]){
      uint8_t num = 0;
      int i = 7;
      int c = 0;
      for(i = 7; i>=0; i--){
        num += bin[i] * pow(2,c);
        c++;
      }
      return num;
    }
    

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

    如果您想进一步帮助我,我发布了更多代码。 谢谢你。

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

    1)只需看一下,您似乎在事务中发送1000字节,而设备需要2。 数据表没有说明如果你发送4个以上的邮件会发生什么--一个nack是一种可能性。

    2) SendMultiByte函数设计为在没有中断的情况下正常运行。 我认为您的操作可能非常简单(未经测试!):

    unsigned dacval;
    unsigned char dachi, daclo;
    dacval = ADCMEM0;
    dacval <<= 2;  // (optional) 10-bit->12-bit range
    dachi = (dacval >> 8) & 0xFF; // high byte (first)
    daclo = (dacval >> 0) & 0xFF; // low byte (second)
    EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, dachi);
    EUSCI_B_I2C_masterSendMultiByteFinish(EUSCI_B0_BASE, daclo);

    然后不要启用任何中断。SendMultiByte函数不能很好地处理nacks,因此如果出现问题,您也可以尝试"WithTimeout"变体。

    [编辑:FIXED B1->B0]

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

    我知道我正在发送两个以上的字节,但这是因为我正在处理不断变化的ADC值。 输入来自麦克风电路的输出,DAC的输出驱动扬声器电路。 这两个电路都经过测试,它们工作正常,因此问题在于代码。 我如何继续不断地发送数值,以便从DAC获得电压,并可能从扬声器获得声音? 同样,扬声器系统工作正常,因此主要问题是持续发送数据。

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

    您不想"连续"更新DAC -您想为每个ADC样本更新一次DAC。 然后调整(增加) ADC采样率以获得所需的保真度。

    因此,循环包括:(1)从ADC获取一个样本(2)将该值写入DAC [见上文](3)暂停计时(根据需要)(4)重复。 有一些方法可以简化此过程,但我建议您首先运行此过程。

    使用400kHz I2C时钟时,最大(理论) DAC更新速率为400k/(3*9位)=14.8ksps,您不应指望在这附近找到任何位置。 4ksps可能是可行的,如果你小心的话,甚至可能是6-8 ksps。

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

    但这不会在每次有新示例时发送一个地址字节吗? 或者,由于数据发生变化,没有办法解决这一问题吗?

    编辑:EUSCI_B_I2C_masterSendMultiByteNext函数又如何? 还是因为DAC一次只接受两个字节而不需要这样做?

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

    图6-1表示每个DAC更新是一个单独的I2C事务(1个地址+2个数据字节)。

    由于您只发送两个(数据)字节,因此不会使用"下一个"函数。

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

    再次感谢您的帮助。 我的代码是现在

    #include "project_definitions.h"
    
    
    unsigned DACval;
    unsigned char data_1, data_2;
    
    
    int main(void)
    {
      WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
      
      // Configure GPIO
      P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
      P1OUT &= ~BIT0;                                          // P1.0 LED off
      P5REN |= BIT0;
      P5OUT |= BIT0;
      
      // Configure ADC A9 pin
      SYSCFG2 |= ADCPCTL9;
      
      //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(CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ, CS_SMCLK_FLLREF_RATIO);
      
      //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);
      
      // Configure Pins for I2C , SCL 5.3, SDA 5.2
      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SCL, GPIO_PIN_UCB0SCL, GPIO_FUNCTION_UCB0SCL);
      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SDA, GPIO_PIN_UCB0SDA, GPIO_FUNCTION_UCB0SDA);
      
      /*
      * Disable the GPIO power-on default high-impedance mode to activate
      * previously configured port settings
      */
      PMM_unlockLPM5();
      
      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 = 255;
      param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
      EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
      
      //Specify slave address
      EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,SLAVE_ADDRESS);
      
      //Set Master in receive mode
      EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
      
      //Enable I2C Module to start operations
      EUSCI_B_I2C_enable(EUSCI_B0_BASE);
      EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
      
      //Enable master Receive interrupt
      EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
      
      //set a timeout for 34ms
      EUSCI_B_I2C_setTimeout(EUSCI_B0_BASE,EUSCI_B_I2C_TIMEOUT_34_MS);
      
      // Configure ADC10
      ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks----ADCSHTx : 0000b = 4 ADCCLK cycles 0001b = 8 ADCCLK cycles 0010b = 16 ADCCLK cycles 0011b = 32 ADCCLK cycles
      ADCCTL1 |= ADCSHP | ADCSSEL_0 | ADCCONSEQ_2;             // ADCCLK = MODOSC; sampling timer   ADCCONSEQ_2 = Repeat-single-channel ---- remove it for single channel
      ADCCTL2 |= ADCRES_1 ;                                    // 10/8-bit conversion results ADCRES_1 = 10 bit////ADCRES_0 = 8 bit
      ADCMCTL0 |= ADCINCH_9 | ADCSREF_0;                       // A9 ADC input select; pin 8.1 use this for mic setup
      ADCIFG &= ~0x01;                                         //clear interrupt flag
      ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt  
      
      
      
      while(1)
      {
        ADCCTL0 |= ADCENC | ADCSC;                          // Sampling and conversion start, could use ACCTL0 = 0x03
        __bis_SR_register(LPM0_bits | GIE);               // LPM0, ADC_ISR will force exit LOW POWER MODE 0
        //__no_operation();                                 // For debug only
        if (ADC_Result < 0x00F){
          P1OUT &= ~BIT0;                                 // Clear P1.0 LED off
        }
        else{
          P1OUT |= BIT0;                                   // Set P1.0 LED on
        }
        __delay_cycles(5000);                   // Delay between transmissions
        
        DACval = ADC_Result;
        DACval <<= 2;  // (optional) 10-bit->12-bit range
        data_1 = (DACval >> 8) & 0xFF; // high byte (first)
        data_2 = (DACval >> 0) & 0xFF; // low byte (second)
        
        //while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
        
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, data1);
        EUSCI_B_I2C_masterSendMultiByteFinish(EUSCI_B0_BASE, data2);
        
      }
    }
    
    
    
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
      {
      case ADCIV_NONE:
        break;
      case ADCIV_ADCOVIFG:
        break;
      case ADCIV_ADCTOVIFG:
        break;
      case ADCIV_ADCHIIFG:
        break;
      case ADCIV_ADCLOIFG:
        break;
      case ADCIV_ADCINIFG:
        break;
      case ADCIV_ADCIFG:
        ADC_Result = ADCMEM0;
        __bic_SR_register_on_exit(LPM0_bits);          // Clear CPUOFF bit from LPM0
        break;
      default:
        break;
      }  
    }
    
    
    //#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    //#pragma vector=USCI_B0_VECTOR
    //__interrupt
    //#elif defined(__GNUC__)
    //__attribute__((interrupt(USCI_B0_VECTOR)))
    //#endif
    //void USCIB0_ISR(void)
    //{
    //  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
    //  {
    //  case USCI_NONE:             // No interrupts break;
    //    break;
    //  case USCI_I2C_UCALIFG:      // Arbitration lost
    //    break;
    //  case USCI_I2C_UCNACKIFG:    // NAK received (master only)
    //    //resend start if NACK
    //    EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
    //    break;
    //  case USCI_I2C_UCTXIFG0:     // TXIFG0
    //    // Check TX byte counter
    //    if (TXByteCtr)
    //    {
    //      EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData);
    //      // Decrement TX byte counter
    //      TXByteCtr--;
    //    }
    //    else
    //    {
    //      EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
    //      // Exit LPM0
    //      __bic_SR_register_on_exit(LPM0_bits);
    //    }
    //    break;
    //  default:
    //    break;
    //  }
    //}
    //

    我将很快测试它,如果有任何问题,我会及时与您取得回复。

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

    > EUSCI_B_I2C_enableInterrupt (EUSCI_B0_BBASE,EUSCI_B_I2C_Transmit_INTERRUPT0 + EUSCI_B_I2C_NAK_interrupt);

    删除此项。 ISR将会妨碍您的发展。

    --------

    此外,您是否修复了slaver_address? 在头文件中它看起来仍然不正确。

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

    我移除了它,现在我就修复了它。 再次感谢。 明天我会测试一下,然后回复给你。

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

    此处是否有任何测试更新?

    此致

    强生

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

    我今天上午测试了它。 如果我在eusci_b_i2c.c中注释以下部分,那么我可以从SDA引脚在示波器上看到一些内容:

    void EUSCI_B_I2C_masterSendMultiByteStart (uint16_t baseAddress,
        uint8_t txData
        )
    {
        //Store current transmit interrupt enable
        uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE;
    
        //Disable transmit interrupt enable
        HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
    
        //Send start condition.
        HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR +  UCTXSTT;
    
        //Poll for transmit interrupt flag.
        //while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
    
        //Send single byte data.
        HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
    
        //Reinstate transmit interrupt enable
        HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;
    }
    

    void EUSCI_B_I2C_masterSendMultiByteFinish (uint16_t baseAddress,
        uint8_t txData
        )
    {
        //If interrupts are not used, poll for flags
    //    if (!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE)){
    //        //Poll for transmit interrupt flag.
    //        while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
    //    }
    
        //Send single byte data.
        HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
    
        //Poll for transmit interrupt flag.
        //while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
    
        //Send stop condition.
        HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
    }
    
    

    要总结上述要点,在我正在使用的两个函数(代码粘贴在我的注释末尾)中,即"EUSSCI_B_I2C_masterSendMultiByteStart"和"EUSSCI_B_I2C_masterSendMultiByteFinish",始终会卡住它所说的位置:

        //Poll for transmit interrupt flag.
        //while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;
    

    我真的不明白。 但至少数据是通过SDA引脚发送的,并且可以被检测到。 尽管DAC正在接收数据,但它没有电压输出。 如何测试DAC的问题? 格式正确,所以我不知道该怎么做。 我正在考虑购买另一个DAC芯片,如果可以的话,只需使用MSP430的上拉电阻器,但我想让它发挥作用,因为我已经花了很多时间在它上了。

    project_definitions.h (由于新的主代码,此处的大多数代码未使用)

    #include <msp430.h>
    #include <driverlib.h>
    #include "Board.h"
    #include <math.h>
    
    
    #define SLAVE_ADDRESS 0x60
    #define CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ   1000 //Target frequency for SMCLK in kHz
    #define CS_SMCLK_FLLREF_RATIO   30 //SMCLK/FLLRef Ratio
    
    int c = 0, i = 0;
    int order = 1, byteNum = 1;
    unsigned int ADC_Result = 0;
    long long numbin = 0;
    
    // Pointer to TX data
    uint8_t TXData = 0;
    uint16_t TXByteCtr;
    
    uint8_t* ptr_numbinArray;
    uint8_t numbinArray[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
    
    uint8_t byte1[8] = {0,0,0,0,0,0,0,0};  //postions 5,6,7,8 are 0 for PD0, PD1, C2, C1 respectively
    uint8_t byte2[8] = {0,0,0,0,0,0,0,0};
    uint8_t* ptr_byte1 = byte1;
    uint8_t* ptr_byte2 = byte2;
    
    uint8_t data1 = 0;
    uint8_t data2 = 0;
    
    long long convertIntToBin(int num) {
      long long numbin = 0;
      int rem;
      long long i = 1;
      
      while (num!=0) {
        rem = num % 2;
        num /= 2;
        numbin += rem * i;
        i *= 10;
      }
      return numbin;
    }
    
    uint8_t* addToArray(long long numbin){
      int pos = 0;  
      static uint8_t numbinArray[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
      while (numbin != 0){
        numbinArray[pos] = numbin % 10;
        numbin /= 10;
        pos++;
      }    
      return numbinArray;
    }
    
    uint8_t convertBinToInt(uint8_t bin[8]){
      uint8_t num = 0;
      int i = 7;
      int c = 0;
      for(i = 7; i>=0; i--){
        num += bin[i] * pow(2,c);
        c++;
      }
      return num;
    }
    

    主多字节send.c

    #include "project_definitions.h"
    
    
    unsigned DACval;
    unsigned char data_1, data_2;
    
    
    int main(void)
    {
      WDTCTL = WDTPW | WDTHOLD;                                // Stop WDT
      
      // Configure GPIO
      P1DIR |= BIT0;                                           // Set P1.0/LED to output direction
      P1OUT &= ~BIT0;                                          // P1.0 LED off
      //P5REN |= BIT0;
      //P5OUT |= BIT0;
      
      // Configure ADC A9 pin
      SYSCFG2 |= ADCPCTL9;
      
      //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(CS_SMCLK_DESIRED_FREQUENCY_IN_KHZ, CS_SMCLK_FLLREF_RATIO);
      
      //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);
      
      // Configure Pins for I2C , SCL 5.3, SDA 5.2
      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SCL, GPIO_PIN_UCB0SCL, GPIO_FUNCTION_UCB0SCL);
      GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SDA, GPIO_PIN_UCB0SDA, GPIO_FUNCTION_UCB0SDA);
      
      /*
      * Disable the GPIO power-on default high-impedance mode to activate
      * previously configured port settings
      */
      PMM_unlockLPM5();
      
      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 = 255;
      param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
      EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
      
      //Specify slave address
      EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE,SLAVE_ADDRESS);
      
      //Set Master in receive mode
      EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
      
      //Enable I2C Module to start operations
      EUSCI_B_I2C_enable(EUSCI_B0_BASE);
      EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
      
      //Enable master Receive interrupt
      //EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
      
      //set a timeout for 34ms
      //EUSCI_B_I2C_setTimeout(EUSCI_B0_BASE,EUSCI_B_I2C_TIMEOUT_34_MS);
      
      // Configure ADC10
      ADCCTL0 |= ADCSHT_2 | ADCON;                             // ADCON, S&H=16 ADC clks----ADCSHTx : 0000b = 4 ADCCLK cycles 0001b = 8 ADCCLK cycles 0010b = 16 ADCCLK cycles 0011b = 32 ADCCLK cycles
      ADCCTL1 |= ADCSHP | ADCSSEL_0 | ADCCONSEQ_2;             // ADCCLK = MODOSC; sampling timer   ADCCONSEQ_2 = Repeat-single-channel ---- remove it for single channel
      ADCCTL2 |= ADCRES_1 ;                                    // 10/8-bit conversion results ADCRES_1 = 10 bit////ADCRES_0 = 8 bit
      ADCMCTL0 |= ADCINCH_9 | ADCSREF_0;                       // A9 ADC input select; pin 8.1 use this for mic setup
      ADCIFG &= ~0x01;                                         //clear interrupt flag
      ADCIE |= ADCIE0;                                         // Enable ADC conv complete interrupt  
      
      
      
      while(1)
      {
        ADCCTL0 |= ADCENC | ADCSC;                          // Sampling and conversion start, could use ACCTL0 = 0x03
        __bis_SR_register(LPM0_bits | GIE);               // LPM0, ADC_ISR will force exit LOW POWER MODE 0
        //__no_operation();                                 // For debug only
        if (ADC_Result < 0x00F){
          P1OUT &= ~BIT0;                                 // Clear P1.0 LED off
        }
        else{
          P1OUT |= BIT0;                                   // Set P1.0 LED on
        }
        __delay_cycles(5000);                   // Delay between transmissions
        
        DACval = ADC_Result;
        DACval <<= 2;  // (optional) 10-bit->12-bit range
        data_1 = (DACval >> 8) & 0xFF; // high byte (first)
        data_2 = (DACval >> 0) & 0xFF; // low byte (second)
        
        //while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
        
    //        //convert the adc result to binary
    //    numbin = convertIntToBin(ADC_Result);
    //    
    //    //add the binary number to the numbinArray
    //    ptr_numbinArray = addToArray(numbin);
    //    i = 0;
    //    for (i = 0;i<=10; i++){ //to shift the binary 2 to the left make i = 2; and i<= 12;
    //      numbinArray[i] = *(ptr_numbinArray + i); 
    //    }
    //    
    //    //split numbinArray up to the two required bytes
    //    //byte 1
    //    i = 8;
    //    c = 7;
    //    for (i = 8; i<=11; i++){
    //      byte1[c] = numbinArray[i];
    //      c--;
    //    }
    //    
    //    //byte 2
    //    i = 0;
    //    c = 7;
    //    for (i = 0; i<=7; i++){ 
    //      byte2[c] = numbinArray[i];
    //      c--;
    //    }
    //    
    //    data1 = convertBinToInt(ptr_byte1);
    //    data2 = convertBinToInt(ptr_byte2);
        
            
        //while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
        
            //while(EUSCI_B_I2C_SENDING_START == EUSCI_B_I2C_masterIsStartSent(EUSCI_B0_BASE));
    
        
        
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, data_1);
        EUSCI_B_I2C_masterSendMultiByteFinish(EUSCI_B0_BASE, data_2);
        byteNum++;
      }
    }
    
    
    
    // ADC interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = ADC_VECTOR
    __interrupt void ADC_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(ADC_VECTOR))) ADC_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
      {
      case ADCIV_NONE:
        break;
      case ADCIV_ADCOVIFG:
        break;
      case ADCIV_ADCTOVIFG:
        break;
      case ADCIV_ADCHIIFG:
        break;
      case ADCIV_ADCLOIFG:
        break;
      case ADCIV_ADCINIFG:
        break;
      case ADCIV_ADCIFG:
        ADC_Result = ADCMEM0;
        __bic_SR_register_on_exit(LPM0_bits);          // Clear CPUOFF bit from LPM0
        break;
      default:
        break;
      }  
    }
    
    
    //#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    //#pragma vector=USCI_B0_VECTOR
    //__interrupt
    //#elif defined(__GNUC__)
    //__attribute__((interrupt(USCI_B0_VECTOR)))
    //#endif
    //void USCIB0_ISR(void)
    //{
    //  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
    //  {
    //  case USCI_NONE:             // No interrupts break;
    //    break;
    //  case USCI_I2C_UCALIFG:      // Arbitration lost
    //    break;
    //  case USCI_I2C_UCNACKIFG:    // NAK received (master only)
    //    //resend start if NACK
    //    EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
    //    break;
    //  case USCI_I2C_UCTXIFG0:     // TXIFG0
    //    // Check TX byte counter
    //    if (TXByteCtr)
    //    {
    //      EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TXData);
    //      // Decrement TX byte counter
    //      TXByteCtr--;
    //    }
    //    else
    //    {
    //      EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
    //      // Exit LPM0
    //      __bic_SR_register_on_exit(LPM0_bits);
    //    }
    //    break;
    //  default:
    //    break;
    //  }
    //}
    //
    

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

    你好,Johnson。 我回复了Bruce,结果如下。 感谢您对我的帖子表示关注。

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

    您能描述一下您在SDA上看到的内容吗? 如果您的示波器只有一个探头,那么SCL目前可能会更有趣。

    在事务开始时未能看到TXIFG通常表示某些非常基本的总线故障,从而阻止主控制器生成启动。 通常的可疑情况是(1)总线上拉--你可以检查主板底部的"上拉"桥是否损坏(2)从属设备保持SCL和/或SDA低--在这种情况下,尝试对从属设备进行电源循环(只需断开/重新连接Vcc引脚)。

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

    今天上午我尝试重复昨天的测试。 不幸的是,结果并不相同。 它一直被卡在上

       //传送中断标志轮询。
       同时(!(HWREG16(basAddress + OFS_UCBxIFG)& UCTXIFG));

    对于这两种功能,示波器上都没有可用读数。 我会再次尝试连接所有设备,以便稍后进行更多测试,我会告诉您。

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

    今天下午的进一步试验得出结论,它已经过去了

        //Poll for transmit interrupt flag.
        while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;

    在第一个周期中,在“EUSCI_B_I2C_masterSendMultiByteStart”函数中,但在“EUSCI_B_I2C_masterSendMultiByteFinish”函数中,它被卡在相同的代码处。 如果我注释掉第二个函数中的代码,那么它就会粘在第一个函数中的同一个代码中。 因此,开始条件可能会被发送,但它不能继续到第二个字节? 然后我猜是因为没有发送停止条件,它使程序混乱,因为它试图再次发送启动条件。 您认为有什么解决方法?

    我进行了电源循环并检查从属设备是否有任何错误或问题,一切看起来都很好,或者像往常一样。

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

    我是否应该针对我的较新问题制定更具体的新线程? 还是保留此邮件并回复评论?

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

    您能否描述示波器跟踪(甚至不可用的跟踪)。 首先要关注的是:SCL是高还是低? SDA怎么样?

    当您陷入其中一个循环时,在“寄存器”视图中查看USI_B0状态可能很有用。 UCB0CTL0/1,UCB0IFG和UCB0STAT是兴趣点。

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

    今天做了更多的测试。 示波器上的SCL和SDA处于DAC电源电压下的相同电平。 在这种情况下,它是4 V。它们似乎根本没有摆动,而且一直在那种荣誉。 但是当我放大SDA并对着麦克风讲话时,我可以看到一些小事情发生。 但是,我不知道这是不是来自电路其他部分的随机噪音,我会将其相互干扰,但似乎正在发生小幅波动。

    我现在将介绍今天发生的情况。 我记录了您提到的内存寄存器,并记下了它被卡住的位置。

    程序启动
    完成一个成功的循环,同时通过两个功能
    下一个循环,卡在

        //Poll for transmit interrupt flag.
        while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) ;

    在"EUSCI_B_I2C_masterSendMultiByteFinish"函数的第401行。
    如果我将其注释掉并重新运行,则会发生相同的情况,但它会被粘在第408行的相同代码上。
    如果我将其注释掉并重新运行它,它将在第三个周期中被卡在同一代码片段中,但却被卡在“EUSCI_B_I2C_masterSendMultiByteStart”中。
    如果我对所有有问题的区域进行注释,MSP430 ADC将正确采样,但在某个时刻,这些值始终显示在监视列表上的0处。 断开并重新连接SDA和SCL可解决此问题。

    当它停留在while循环时,内存寄存器的功放如下:
    UCB0CTL0:0x0F
    UCB0CTL1:0x92
    UCB0STAT:错误
    UCBxTXBUF:错误
    UCB0IFG:10.

    当所有内容都被注释并重复时,它们是:
    (其他都是一样的)
    UCB0IFG:8.

    再次感谢您抽出宝贵时间来帮助我们。

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

    我认为您成功完成第一笔交易非常重要。  我看到的唯一的起搏限制是Tbuf [表7-1],最坏的情况是<5微秒,看起来你给它的时间大于5毫秒。 我也想知道为什么你看不到你的范围内有任何公共汽车活动。

    一种相当标准的调试技术是降低总线速度。 我没有假设,但这可以减轻长线等的影响。  请尝试使用[...]100KB来代替EUSCI_B_I2C_SET_DATA_RATE_400KBPS。 (这被定义为数字10万,所以你可以,例如,如果你选择用5万代替50kHz。)

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

    好的,我会尝试一下,并在几天后向您提供最新信息,因为大学已关闭。

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

    你好,Bruce。 降低数据速率后没有任何变化。 我应该尝试使用字节计数器还是超时? 有时它会重复一次,有时会在第一次迭代时卡住 ,而不管它接收到什么读数。 它与前面讨论的While循环相同。 UCBxTXBUF仍显示错误。

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

    很遗憾,我没有您的设备,所以我只能猜测。

    听起来好像第一笔交易(某种程度)使总线处于不适当的状态。 如果您在每次运行之前关闭并重新启动从属设备,您是否始终成功处理第一个事务? 您的范围显示在两者之间的什么范围?

    我想另一个实验是发送(根据图6-1)前两个字节,然后作为单个事务重复这两个字节(共4个)。 正如我所说的,我不确定这种替代形式应该为您做什么,但这是一种尝试。

    您所指的名称"UCBxTXBUF"(通常不存在)。 您是否从“寄存器”视图中获得这些值? (UCB0TXBUF确实存在,但在这种情况下通常不是很有用。)

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

    你好,Bruce。 我最终选择了自己的路线,并签署了一些其他的功能。 我可以看到现在SDA在示波器上发生了一些波形。 我结束了使用以下代码完全手动发送数据的操作:

        EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
        EUSCI_B_I2C_slavePutData(EUSCI_B0_BASE, data_0);   
        EUSCI_B_I2C_slavePutData(EUSCI_B0_BASE, data_2);
        EUSCI_B_I2C_slavePutData(EUSCI_B0_BASE, data_1);
        HWREG16(EUSCI_B0_BASE + OFS_UCBxCTLW0) |= UCTXSTP; //send stop sondition

    我有一些问题,如果可以的话,我希望澄清一下。 我是否必须手动发送带地址和R/W位的字节? 起始位与片段中的第1行一起发送。 在第2行中,DATA_0为0xC0,表示必须发送至DAC的第一个数据字节(图6-1),其中还包括地址和R/W位。 是否有必要这样做? 第3行和第4行是C0,C1,PD1和PD0的其余数据。 最后一行应为停止条件。

    另一个问题是,如何处理每个字节后发送的ACK? 我是否可以通过某种方式检查是否收到? 我可以用它做些什么吗?

    DAC没有输出,所以我猜它与发送方式有关。

    再次感谢您的帮助。

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

    我又看了一下DAC数据表,注意到表5-3,它表明,当DAC第一次通电时,它应该输出Vcc/2 ,或大约1.7V。 您说您看不到输出,我认为这意味着0伏。 如果是这样,则表明发生了与I2C通信不同的事情。 Vout连接到什么?

    slavePutData函数不会检查TXIFG,因此,如果TXIFG未出现,它不会挂起,但字节很有可能丢失。

    要回答您的问题:

    1)您不发送地址+ R/W (SLA)字节,ESCI为您生成该字节。

    2)您没有得到明确的ACK指示。 如果设备 发送nack (实际上只是缺少ACK),则设置UCNACKIFG。 [参考用户指南(SLAU445I)图24-12,大致位于中间]

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

    感谢您回答我的问题,它澄清了很多事情。 为UCNACKIFG设置中断是否是一个好主意? 我可以通过这种方式更好地了解DAC的情况。 是的,输出为~Vcc/2,抱歉,我想说Vout中没有电压波动/活动。 明天我将再次测试并告知您。

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

    您可以启用(仅限) UCNACKIE,并在ISR中捕获它。 考虑到程序的其余部分,您将无法修复任何问题,但您可以在此处设置断点,看看您是否看到了错误。 您之前的报告未指示已设置UCNACKIFG (0x20)。

    您是否能够发布任何示波器波形?

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

    我尝试将您的代码与我为另一个项目编写的非常简单的I2C从属设备(在另一个Launchpad上运行)连接起来。 在这个实验中,你的代码似乎运行良好--我在1200多笔交易后停止了。

    这似乎也指向代码本身之外的内容。  您最近是否检查过接线? 设置的照片可能会很有用。

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

    感谢您连接并完成所有这些操作。 您使用过EUSCI_B_I2C_slavePutData函数还是我们之前使用过的其他函数? 我可以发送一张设置图片,现在我们正忙于焊接电路的PCB,一旦我完成了,我就可以将其再次连接到MSP430并通知您!

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

    你好,Bruce。 幸运的是,我有一个使用超时的想法,因为我注意到它会影响程序所滞留的代码部分。 因此,超时后,它似乎在某种程度上起作用。 我有来自DAC的一些电压,它位于下面示波器的图片中。

    从下面的图片中,您可以看到设置。 所有设备都由电池组供电(以前使用过可变电源电压)。

    电线:
    白色电线为SDA (从DAC的5.2 到SDA)
    黑色电线为SCL (从DAC的PSCL到5.3)
    棕色是来自麦克风电路的声音(进入MSP的接地)
    红色是来自麦克风电路的输入电压(进入ADC的8.1)
    黄色为来自DAC的电压输出(连接到示波器探头)
    橙色表示DAC电压供应
    其余两根电线为接地线

    我不确定为什么超时有效而不是putData函数,我猜是因为它会对中断执行其他操作? 但我不是在使用中断,所以我不能这样做。 是否需要超时,数据未按周期正确发送?  您认为是否存在技术限制? 我猜我们不会听到我们在麦克风中说话的声音,但某些输出可能会使另一侧发出一些噪音。

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

    putData函数不检查TXIFG,因此您"放入"的部分或全部字节将丢失。

    当您说"timeout"时,您是指"masterSendMultiByteXXXwithTimeout"变体吗?  

    在Vout上看到一些东西令人鼓舞,但很难知道它是否正确。 一个实验是对代码进行小幅更改,以忽略ADC结果,每次只发送一个常量(可能是409/4,即Vcc/4),并查看Vout是否反映了这一点。 您还可以考虑完全断开麦克风电路,看看这是否会对I2C造成一些电干扰。

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

    是的,这些是我正在使用的变体,我从其中获得了输出。 我将检查哪种声音在星期二结束发言,并尝试Vcc/4测试你肯定. 谢谢你。

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

    问题的最终更新。

    提交了项目,所以我真的不能再做更多了。 在扬声器端未检测到电压的原因是读取的值太小,并且DAC未为扬声器电路产生足够的电压。 为了解决这个问题,我将读取值乘以5,得出了一些电压输出。 总是需要超时,我猜这与MSP430FR4133的内部时钟和中断有关,它们无法同时处理ADC输入和I2C输出。 或者,我没有为正确的目的设置正确的时钟。 我不是很清楚,但这个项目的一般概念现在已经奏效了。 所以我会将我的帖子标记为已解决。