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.

[参考译文] 编译器/TM4C123GH6PM:TM4C123GH6PMI/I2C 和 HMC5883L

Guru**** 2473260 points
Other Parts Discussed in Thread: TM4C123GH6PM

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/681501/compiler-tm4c123gh6pm-tm4c123gh6pmi-i2c-and-hmc5883l

器件型号:TM4C123GH6PM

工具/软件:TI C/C++编译器

大家好,我想让 HMC5883L 正常工作,但我的代码卡在检查总线是否在 while (ROM_I2CMasterBusy (I2C1_base)第一次出现时占线;,我是不是在搞什么,请帮助


#define target_in_blizzard_RB1
#define PART_TM4C123GH6PM


#include //移位
#include
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "inc/tm4c123gh6m.h"
#include "inc/hw_i2c.h"

void send_start (int a、int b、int c){
   
   ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、false);
   
   ROM_I2CMasterDataPut (I2C1_base、a);

ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_START);

while (ROM_I2CMasterBusy (I2C1_base));
   
   
   ROM_I2CMasterDataPut (I2C1_base、b);

ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_CONT);

while (ROM_I2CMasterBusy (I2C1_base));
   
   
   
   ROM_I2CMasterDataPut (I2C1_base、c);
   
ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_FINISH);

while (ROM_I2CMasterBusy (I2C1_base));
   

void send_start2 (int a、int b){
   
   ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、false);
   
   ROM_I2CMasterDataPut (I2C1_base、a);

ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_START);

while (ROM_I2CMasterBusy (I2C1_base));
   
   
   ROM_I2CMasterDataPut (I2C1_base、b);
   
ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_FINISH);

while (ROM_I2CMasterBusy (I2C1_base));
   



void ReadByteArray (int *arr, int cnt);
int data[6]={1、2、3、4、5、6};
int main (空)

   ROM_SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);

   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_I2C1);
   
   ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
   
   
   ROM_GPIOPinTypeI2CSCL (GPIO_Porta_base、GPIO_PIN_6);
   ROM_GPIOPinTypeI2C (GPIO_Porta_base、GPIO_PIN_7);
   
   ROM_I2CMasterInitExpClk (I2C1_base、SysCtlClockGet ()、false);
   
   //“连续测量模式(HMC5883L)的初始化过程第18页
   
   //(8平均值、默认值15Hz、正常测量)
   SEND_START (0x3C、0x00、0x70);
   //(gain=5、或任何其他所需的增益)
   SEND_START (0x3C、0x01、0xA0);
 //(连续测量模式)
   SEND_START (0x3C、0x02、0x00);
   
   ROM_SysCtlDelay (5500000);//写入时间
   
   
   
   while (1){
      SEND_start2 (0x3D、0x03);// 1.
      ReadByteArray (数据、1);
      
   }
   



空 ReadByteArray (int *arr、int cnt){
int i=1;
   
   
   
ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、false);


ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_Receive_start);

while (ROM_I2CMasterBusy (I2C1_base));

ARR[0]= ROM_I2CMasterDataGet (I2C1_base);//test
   

对于(i=1 <cnt;i++)

ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_Receive_CONT);
//
while (ROM_I2CMasterBusy (I2C1_base));

ARR[i]= ROM_I2CMasterDataGet (I2C1_base);//接收


ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_Receive_finish);
//
while (ROM_I2CMasterBusy (I2C1_base));


   



  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在分析代码之前、让您使用示波器检查 I2C 总线。 请验证您具有正确的 SCL 和 SDA 信号、并查看从器件是否正在发送应答。 如果没有、请验证 SCL 和 SDA 上是否有上拉电阻。 如果您不确定 I2C 总线应该是什么样子、此参考资料可能有助于:
    www.ti.com/.../slva704.pdf
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    除了供应商 Bob 的声音建议-遵循"kiss"是明智的-这会将您引导至(开始)更简单的 I2C 从设备。   (如小容量、基于 I2C、EEPROM 设备... 也可用于您的项目。)    另一个主要优势-由"kiss"提供-您、"构建您的理解"-同时 "添加新功能" 到您的"技巧包"。

    您选择的器件-需要"多字节传输"-这 "大大提高了您 对 I2C 的掌握和编码的需求...   

    事实证明、如果器件非常复杂(在您建立了经验和信心之后)、它"可以"到"结束"、 但很少"明智"-可以"开始"这样(复杂)的器件...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的回复,
    我从24c04 EEPROM 开始,根据我所学的内容,我尝试使计算正常工作,尽管我使用的代码几乎相同(只是更改了地址),但计算却失败了。

    在执行一些搜索后、我将函数 send_start2替换为 i2CAN send、但通过比较这两个函数、我仍然无法确定为什么它在 send_start2中失败

    可以帮帮我吗?



    #define target_in_blizzard_RB1
    #define PART_TM4C123GH6PM

    #include
    #include //移位
    #include
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "inc/hw_i2c.h"
    #include "driverlib/i2c.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/pin_map.h"
    #include "inc/tm4c123gh6m.h"
    #include "inc/hw_i2c.h"

    void send_start (int a、int b、int c){

    ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、false);

    ROM_I2CMasterDataPut (I2C1_base、a);

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_START);

    while (ROM_I2CMasterBusy (I2C1_base));


    ROM_I2CMasterDataPut (I2C1_base、b);

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_CONT);

    while (ROM_I2CMasterBusy (I2C1_base));



    ROM_I2CMasterDataPut (I2C1_base、c);

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_FINISH);

    while (ROM_I2CMasterBusy (I2C1_base));


    void send_start2 (int a、int b){

    ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、false);

    ROM_I2CMasterDataPut (I2C1_base、a);

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_START);

    while (ROM_I2CMasterBusy (I2C1_base));


    ROM_I2CMasterDataPut (I2C1_base、b);

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_FINISH);

    while (ROM_I2CMasterBusy (I2C1_base));




    void ReadByteArray (uint32_t *arr、uint8_t cnt);
    void I2CSend (uint8_t slave_addr、uint8_t num_for_args、...);
    uint32_t data[6]={1、2、3、4、5、6};
    int8_t x、y、z;
    int main (空)

    ROM_SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);

    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_I2C1);
    ROM_SysCtlPeripheralReset (SYSCTL_Periph_I2C1);

    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    ROM_GPIOPinConfigure (GPIO_PA6_I2C1SCL);
    ROM_GPIOPinConfigure (GPIO_PA7_I2C1SDA);
    ROM_GPIOPinTypeI2CSCL (GPIO_Porta_base、GPIO_PIN_6);
    ROM_GPIOPinTypeI2C (GPIO_Porta_base、GPIO_PIN_7);

    ROM_I2CMasterInitExpClk (I2C1_base、SysCtlClockGet ()、false);

    //HWREG (I2C1_base + I2C_1_FIFOCTL)= 80008000;

    //“连续测量模式(HMC5883L)的初始化过程第18页


    I2CSend (0x1E、2、0x02、0x00);






    while (1){
    //I2CSend (0x1E、4、0x3D、0x06、0x3C、0x03);
    I2CSend (0x1E、1、0x03);//TODO:删除此行
    ReadByteArray (数据、6);
    X=(DATA[0][<8)|DATA[1];
    y=(data[2]<<8)|data[3];
    z=(data[4]<<8)|data[5];

    ROM_SysCtlDelay (5500000);//写入时间





    void ReadByteArray (uint32_t * arr、uint8_t cnt){
    int i=1;


    ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、false);

    ROM_I2CMasterDataPut (I2C1_base、0x03);//地址0x11

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_SINGLE_SEND);

    while (ROM_I2CMasterBusy (I2C1_base));

    //
    ROM_I2CMasterSlaveAddrSet (I2C1_base、0x1E、true);

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_Receive_start);

    while (ROM_I2CMasterBusy (I2C1_base));

    ARR[0]= ROM_I2CMasterDataGet (I2C1_base);//test


    对于(i=1 <cnt;i++)

    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_Receive_CONT);
    //
    while (ROM_I2CMasterBusy (I2C1_base));

    ARR[i]= ROM_I2CMasterDataGet (I2C1_base);//接收


    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_Receive_finish);
    //
    while (ROM_I2CMasterBusy (I2C1_base));





    void I2CSend (uint8_t slave_addr、uint8_t num_for_args、...)

    //告诉主模块何时将在总线上放置什么地址
    //与从设备通信。
    ROM_I2CMasterSlaveAddrSet (I2C1_base、slave_addr、false);

    //存储变量数量的参数列表
    va_list vargs;

    //将 va_list 指定为"open"和最后一个固定参数
    //so vargs 知道从何处开始查找
    va_start (vargs、num_of _args);

    //将要发送的数据放入 FIFO 中
    ROM_I2CMasterDataPut (I2C1_base、va_arg (vargs、uint32_t));

    //如果只有一个参数,我们只需要使用
    //单发送 I2C 函数
    if (num_of _args == 1)

    //从 MCU 发起数据发送
    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_SINGLE_SEND);

    //等待 MCU 完成传输。
    while (I2CMasterBusy (I2C1_base));

    //"close"变量参数列表
    va_end (vargs);


    //否则,我们开始在上传输多个字节
    //I2C 总线
    其他

    //从 MCU 发起数据发送
    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_START);

    //等待 MCU 完成传输。
    while (I2CMasterBusy (I2C1_base));

    //send num_of _args-2数据片段、使用
    ///burse_send_contt 命令的 I2C 模块
    for (uint8_t i = 1;i <(num_of _args - 1);i++)

    //将下一段数据放入 I2C FIFO 中
    ROM_I2CMasterDataPut (I2C1_base、va_arg (vargs、uint32_t));
    //发送刚刚放置到 FIFO 中的下一个数据
    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_CONT);

    //等待 MCU 完成传输。
    while (I2CMasterBusy (I2C1_base));


    //将最后一段数据放入 I2C FIFO 中
    ROM_I2CMasterDataPut (I2C1_base、va_arg (vargs、uint32_t));
    //发送刚刚放置到 FIFO 中的下一个数据
    ROM_I2CMasterControl (I2C1_base、I2C_MASTER_CMD_BURST_SEND_FINISH);
    //等待 MCU 完成传输。
    while (I2CMasterBusy (I2C1_base));

    //"Close"变量 args 列表
    va_end (vargs);

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

    主席先生,你是少数几个通过 "改进"而"遵循"亲吻"和建立能力和理解的人。   我赞扬你的这一努力。

    您之前注意到:

    [引用 USER="Mohammad El Sherbini"]我的代码在 while (ROM_I2CMasterBusy (I2C1_base))第一次出现时被卡住,检查总线是否繁忙;[/引用]

    您现在注意到"I2Csend"成功-而 Send Start2"失败。     您的代码包括 "Send Start"和 "Send Start2"- 应该保留"Send Start"吗?

    事实证明(非常)很难清楚地识别 "I2Csend" (两者之一)的起始或结束位置- "I2Csend"的多个"出现"分散在整个代码列表中...