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.

[参考译文] MSP432P401R:存在 DAC121C085 I2C 问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/750107/msp432p401r-with-dac121c085-i2c-problem

器件型号:MSP432P401R

我尝试 将 DAC121C081与 msp432p401R 搭配使用。 但在调试模式下、while (I2C_isBusBusy (EUSCI_B3_base))处的软件桩模块;

int main(){

init_i2C_gpio();
I2C_init();
I2C_setSlave (0x0C);
I2C_write16 (0x0、4096);
}

const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
48000000、 // SMCLK = 48MHz
EUSCI_B_I2C_SET_DATA_RATE 400KBPS、 //所需的100kHz I2C 时钟
0、 //无字节计数器阈值
EUSCI_B_I2C_NO_AUTO_STOP //无自动停止
};

void Init_I2C_GPIO()
{
/*为 I2C_SCL (P6.7)和 I2C_SDA (P6.6)选择 I2C 功能*/
GPIO_setPeripheralModuleFunctionOutputPin (
GPIO_PORT_P6、
GPIO_PIN7、
GPIO_PRIMARY_MODULE_FUNCTION);

GPIO_setPeripheralModuleFunctionOutputPin (
GPIO_PORT_P6、
GPIO_PIN6、
GPIO_PRIMARY_MODULE_FUNCTION);
}


/************* //**
*@brief 配置 I2C
*@param none
*@return none (无)
/

void I2C_init (void)
{
/*初始化 USCI_B3和 I2C 主设备以与从属设备通信*/
I2C_initMaster (EUSCI_B3_base、&i2cConfig);

/*禁用 I2C 模块进行更改*/
I2C_DisableModule (USCI_B3_base);

/*启用 I2C 模块以启动操作*/
I2C_enableModule (EUSCI_B3_base);

返回;
}


/************* //**
*@简要从传感器读取数据
*@param writeByte 寄存器地址以读取
*@返回寄存器内容
/

int I2C_read16 (unsigned char writeByte)
{
volatile int val = 0;
volatile int valScratch = 0;

/*将主设备设置为发送模式 PL */
I2C_setMode (EUSCI_B3_base、
EUSCI_B_I2C_Transmit 模式);

/*清除任何现有的中断标志 PL */
I2C_clearInterruptFlag (EUSCI_B3_base、
EUSCI_B_I2C_Transmit INTERRUPT0);

/*等待准备好写入 PL */
while (I2C_isBusBusy (EUSCI_B3_base));

/*启动开始并发送第一个字符*/
I2C_masterSendMultiByteStart (EUSCI_B3_base、writeByte);

/*等待 TX 完成*/
while (!(I2C_getInterruptStatus (EUSCI_B3_base、
EUSCI_B_I2C_Transmit INTERRUPT0)));

/*仅启动停止*/
I2C_masterSendMultiByteStop (EUSCI_B3_base);

/*等待 Stop 完成*/
while (!I2C_getInterruptStatus (EUSCI_B3_base、
EUSCI_B_I2C_STOP_INTERRUPT));

/*
*生成开始条件并将其设置为接收模式。
*这会发出从器件地址并继续读取
*直到您发出停止
*
I2C_masterReceiveStart (EUSCI_B3_base);

/*等待 RX 缓冲区填充*/
while (!(I2C_getInterruptStatus (EUSCI_B3_base、
EUSCI_B_I2C_Receive_INTERRUPT0)));

/*从 I2C RX 寄存器读取*/
Val = I2C_masterReceiveMultiByteNext (EUSCI_B3_base);

/*接收第二个字节、然后发送停止条件*/
valScratch = I2C_masterReceiveMultiByteFinish (EUSCI_B3_base);

/*将 val 移动到顶部 MSB */
Val =(val << 8);

/*从 I2C RX 寄存器读取并写入 val 的 LSB */
Val |= valScratch;

/*返回温度值*/
返回(int16_t) val;
}


/************* //**
*@


@brief 将数据写入传感器*@param 指针要修改的寄存器地址*@param writeByte Data 要写入指定寄存器*返回任何一个都不返回
/

void I2C_write16 (unsigned char 指针、unsigned int writeByte)
{
/*将主设备设置为发送模式 PL */
I2C_setMode (EUSCI_B3_base、
EUSCI_B_I2C_Transmit 模式);

/*清除任何现有的中断标志 PL */
I2C_clearInterruptFlag (EUSCI_B3_base、
EUSCI_B_I2C_Transmit INTERRUPT0);

/*等待准备好写入 PL */
while (I2C_isBusBusy (EUSCI_B3_base));

/*启动开始并发送第一个字符*/
I2C_masterSendMultiByteStart (EUSCI_B3_base、
指针);

/*将 MSB 发送到传感器*/
I2C_masterSendMultiByteNext (EUSCI_B3_base、
(unsigned char)(writeByte>>8));

I2C_masterSendMultiByteFinish (EUSCI_B3_base、
(unsigned char)(writeByte&0xFF));

}


void I2C_setslave (unsigned int slaveAddr)
{
/*指定 I2C 的从器件地址*/
I2C_setSlaveAddress (EUSCI_B3_base、
slaveAddr);

/*启用和清除中断标志*/
I2C_clearInterruptFlag (EUSCI_B3_base、
EUSCI_B_I2C_Transmit INTERRUPT0 + EUSCI_B_I2C_Receive_INTERRUPT0);
返回;
} 

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

    遗憾的是、I2C_isBusBusy 函数上的逻辑反相
    因此正确使用
    while (I2C_isBusBusy (EUSCI_B3_base)== EUSCI_B_I2C_BUS_BUS_BUSY);

    另请参阅 I2C 驱动程序库函数的文档:

    //
    //! 指示 I2C 总线是否繁忙。
    //!
    //! \param moduleInstance 是 eUSCI B (I2C)模块的实例。 有效
    //! 参数因器件而异、但可能包括:
    //! -\b EUSCI_B0_BASE}
    //! -\b EUSCI_B1_BASE}
    //! -\b EUSCI_B2_base
    //! -\b EUSCI_B3_base
    //!
    必须注意的是、对于 eUSCI 模块、只有"B"模块、例如
    //! 可以使用 EUSCI_B0。 诸如 EUSCI_A0的"A"模块不支持
    //! I2C 模式。
    //!
    //!
    //! 此函数返回 I2C 总线是否为的指示
    //! 忙.这个函数通过中的 UCBBUSY 位检查总线的状态
    //! UCBxSTAT 寄存器。
    //!
    //! 如果 I2C 主设备忙、\return 返回 EUSCI_B_I2C_BUS_BUS_BUSY;否则、
    //! 返回 EUSCI_B_I2C_BUS_INT_BUSY。
    //
    //

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

    谢谢你。 现在、它在 I2C_masterSendMultiByteStart (EUSCI_B3_base、指针);函数中的"while"处再次出现残桩。

    while (BITBAND_peri (EUSCI_B_CMSIS (模态)->CTLW0、
    EUSCI_B_CTLW0_TXSTT_OFS)
    ||!BITBAND_peri (EUSCI_B_CMSIS (模态)->IFG、
    EUSCI_B_IFG_TXIFG0_OFS)); 

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

    您是否可以选择探测 I2C (SDA 和 SCL)的两条线路、并在此处发送此启动序列的示波器屏幕截图。

    此外、通过查看 DAC 数据表、可以看到、访问 DAC 时、只应传输两个数据字节。 此处提到的地址是 I2C 地址。 在代码中、您始终发送3个字节:指针和 writeByte (低字节和高字节)

    此致、
    Stefan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在 Init_I2C_GPIO ()之后;两个引脚在该函数之前变为0.04V、它们处于1.2V。 这是奇怪的吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    没错、这很奇怪、但也澄清了问题。
    I2C 功能是该引脚上的辅助功能。 因此、您必须致电:
    空 Init_I2C_GPIO ()

    /*为 I2C_SCL (P6.7)和 I2C_SDA (P6.6)选择 I2C 功能*/
    GPIO_setPeripheralModuleFunctionOutputPin (
    GPIO_PORT_P6、
    GPIO_PIN7、
    GPIO_secondary 模块功能);

    GPIO_setPeripheralModuleFunctionOutputPin (
    GPIO_PORT_P6、
    GPIO_PIN6、
    GPIO_secondary 模块功能);


    此致、
    Stefan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    现在、引脚始终为1.2V、但仍在相同代码处残桩。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、小步进、但会继续。
    因此、1.2V 肯定会很低。 它显示上升至电源电压。
    您能否首先检查一下、3.3V 时的电源电压是否正常、如原理图所示。
    接下来,您可以在复位后以及在单步执行初始化期间检查 I2C 引脚上的电压电平。

    此致、
    Stefan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    3.3V 正常。 就像原理图一样。 电阻器的其他引脚为3.3V、但 i2c 引脚为1.2V、在 Init_I2C_GPIO ()之后不会改变;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    因此、您可能需要检查电路板
    ->在初始化端口引脚之前、引脚配置为输入。 因此、MSP432侧的引脚上没有负载。 但是、使用给定的值、它看起来像一个2.7k 欧姆(实际或虚拟)、它会根据原理图上的4.7K 将 I2C 线路拉低。

    此致、
    Stefan

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

    好的、我发现了问题。 现在引脚为3.3V、起初它不会卡住、但输出为 stil 0。 现在、它再次出现问题。 我没有编写此代码。 这是你的一个。 尝试适应 dac121c085、但我认为我失败了。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在器件初始化之前、MSP432上的引脚为输入引脚、不会给引脚带来任何负载。
    但是、您可以看到1.2V 的线路上拉电阻为4.7K、因此必须在~ 2.8k 欧姆的电阻器上有另一个负载接地

    RX = 4k7欧姆/(3.3V - 1.2V)* 1.2V

    这必须在您的板上的某个位置。

    此致、
    Stefan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、现在没有问题了。 代码工作正常。 但输出不会改变。 我认为命令是错误的。 您能帮我解决这个问题吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、I2C 似乎起作用-朝着正确的方向迈出了一大步。

    查看 DAC 数据表、我认为您的发送例程应该与此类似(另请参阅 http://www.ti.com/lit/ds/symlink/dac121c085.pdf 中的 DAC 寄存器一章)

    void I2C_write16 (unsigned char 指针、unsigned int writeByte)
    {
    /*将主设备设置为发送模式 PL */
    I2C_setMode (EUSCI_B3_base、
    EUSCI_B_I2C_Transmit 模式);
    
    /*清除任何现有的中断标志 PL */
    I2C_clearInterruptFlag (EUSCI_B3_base、
    EUSCI_B_I2C_Transmit INTERRUPT0);
    
    /*等待准备好写入 PL */
    while (I2C_isBusBusy (EUSCI_B3_base));
    
    /*启动开始并发送第一个字符*/
    I2C_masterSendMultiByteStart (EUSCI_B3_base、
    (unsigned char)((((writeByte>>8)& 0x0F)|(指针<< 4)& 0x30)));
    
    
    I2C_masterSendMultiByteFinish (EUSCI_B3_base、
    (unsigned char)(writeByte & 0xFF));
    
    }
    
    注1:数据和指针的格式被合并为16位。

    注3:4096大于12位-最大值为4095 (0 - 4095 = 4096步长)

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

    正常代码工作正常、我可以更改输出、但我随机使用 I2C_write16 (15、12);

    /*启动开始并发送第一个字符*/
    I2C_masterSendMultiByteStart (eUSCI_B3_base、(unsigned char)(((writeByte>>8)& 0x0F)|((指针<< 4)& 0x30)));
    
    I2C_unsigned SendMultiByteFinish (eUSCI_B3_base、(writechar)(writeFF & writeByte); 

    这使我感到困惑。 我想控制 ADC 输入的输出 acoring、因此使用2个变量(指针和写入字节)非常困难

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    注意:指针给出了 PD 值(PD0和 PD1)、该值只能为0-3。
    而 writeByte 提供12位 DAC 值(D0 -D 11)(0-4095)(更改名称会很好、因为这不是字节)。
    我建议您研究 DAC 数据表、例如、第页 ( www.ti.com/.../dac121c085.pdf 中的 DAC 寄存器一章)

    此致、
    Stefan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的 PD 为0、writebyte 为400、但输出仍然为0
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    只需确保提供244mV。

    上面提到:"正常代码工作正常、我可以更改输出、但非常随机"
    您能详细说明一下吗:您会得到什么电压? 这是稳定的还是浮动的? 与设定值有任何关联吗?

    此致、
    Stefan
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为它提供的电压很低、如0.244mV、或者根本不提供。 我最初以为它能正常工作、但现在我确定我对它没有控制权。 只是在我更改 PD 时行为不同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    那么、会发生什么情况
    I2C_write16 (0x0、4000);
    这将提供2.44V 的电压

    PD 的变化有何不同?

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

    如果我使 PD 1或2的输出变化为0.1mV、这是不会的。 如果 PD 为3、则其行为就像悬空。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否确认 Vref_2.5V 为 DAC 提供了2.5V 基准电压、并且该电压确实存在。 我只想确保我的假设基于您的原理图或确定。

    此致、
    Stefan