查看: 3955|回复: 3

[已解决] 【求助】KL26硬件I2C通信问题,各位大佬看过来~~~

[复制链接]
  • TA的每日心情
    开心
    2020-7-22 16:18
  • 签到天数: 77 天

    连续签到: 1 天

    [LV.6]常住居民II

    6

    主题

    242

    帖子

    5

    高级会员

    Rank: 4

    积分
    816
    最后登录
    2023-12-22
    发表于 2017-7-26 10:04:49 | 显示全部楼层 |阅读模式

    以前用过K64的硬件I2C来读取MPU6050,现在需要用KL26的I2C来读取另外一款六轴传感器ICM20608(跟MPU6050基本一样),但是现在死活调不通I2C。用的是官方SDK2.2版本的库,各位大佬帮忙看一下,下面是相关代码。


    1. //i2c回调函数
    2. static void i2c_master_callback(I2C_Type *base, i2c_master_handle_t *handle, status_t status, void *userData)
    3. {
    4.     /* Signal transfer success when received success status. */
    5.     if (status == kStatus_Success)
    6.     {
    7.         completionFlag = true;
    8.     }
    9.     /* Signal transfer success when received success status. */
    10.     if ((status == kStatus_I2C_Nak) || (status == kStatus_I2C_Addr_Nak))
    11.     {
    12.         nakFlag = true;
    13.     }
    14. }

    15. //i2c写寄存器
    16. static bool I2C_WriteReg(I2C_Type *base, uint8_t device_addr, uint8_t reg_addr, uint8_t value)
    17. {
    18.     i2c_master_transfer_t masterXfer;
    19.     memset(&masterXfer, 0, sizeof(masterXfer));

    20.     masterXfer.slaveAddress = device_addr;
    21.     masterXfer.direction = kI2C_Write;
    22.     masterXfer.subaddress = reg_addr;
    23.     masterXfer.subaddressSize = 1;
    24.     masterXfer.data = &value;
    25.     masterXfer.dataSize = 1;
    26.     masterXfer.flags = kI2C_TransferDefaultFlag;

    27.     /*  direction=write : start+device_write;cmdbuff;xBuff; */
    28.     /*  direction=recive : start+device_write;cmdbuff;repeatStart+device_read;xBuff; */

    29.     I2C_MasterTransferNonBlocking(I2C_BASEADDR, &g_m_handle, &masterXfer);

    30.     /*  wait for transfer completed. */
    31.     while ((!nakFlag) && (!completionFlag))
    32.     {
    33.     }

    34.     nakFlag = false;

    35.     if (completionFlag == true)
    36.     {
    37.         completionFlag = false;
    38.         return true;
    39.     }
    40.     else
    41.     {
    42.         return false;
    43.     }
    44. }

    45. //i2c读寄存器
    46. static bool I2C_ReadRegs(I2C_Type *base, uint8_t device_addr, uint8_t reg_addr, uint8_t *rxBuff, uint32_t rxSize)
    47. {
    48.     i2c_master_transfer_t masterXfer;
    49.     memset(&masterXfer, 0, sizeof(masterXfer));
    50.     masterXfer.slaveAddress = device_addr;
    51.     masterXfer.direction = kI2C_Read;
    52.     masterXfer.subaddress = reg_addr;
    53.     masterXfer.subaddressSize = 1;
    54.     masterXfer.data = rxBuff;
    55.     masterXfer.dataSize = rxSize;
    56.     masterXfer.flags = kI2C_TransferDefaultFlag;

    57.     /*  direction=write : start+device_write;cmdbuff;xBuff; */
    58.     /*  direction=recive : start+device_write;cmdbuff;repeatStart+device_read;xBuff; */

    59.     I2C_MasterTransferNonBlocking(I2C_BASEADDR, &g_m_handle, &masterXfer);

    60.     /*  wait for transfer completed. */
    61.     while ((!nakFlag) && (!completionFlag))
    62.     {
    63.     }

    64.     nakFlag = false;

    65.     if (completionFlag == true)
    66.     {
    67.         completionFlag = false;
    68.         return true;
    69.     }
    70.     else
    71.     {
    72.         return false;
    73.     }
    74. }

    75. //i2c引脚复用设置
    76. void I2C_ConfigurePins(void)
    77. {
    78.   PORT_SetPinMux(PORTB, 0U, kPORT_MuxAlt2);                                                 /* PORTB0 (pin 35) is configured as I2C0_SCL */
    79.   PORTB->PCR[0] = ((PORTB->PCR[0] &
    80.     (~(PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK)))    /* Mask bits to zero which are setting */
    81.       | PORT_PCR_PS(0x01u)                                                 /* Pull Select: Internal pullup resistor is enabled on the corresponding pin, if the corresponding PE field is set. */
    82.       | PORT_PCR_PE(0x01U)                                                /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin, if the pin is configured as a digital input. */
    83.     );
    84.   PORT_SetPinMux(PORTB, 1U, kPORT_MuxAlt2);                /* PORTB1 (pin 36) is configured as I2C0_SDA */
    85.   PORTB->PCR[1] = ((PORTB->PCR[1] &
    86.     (~(PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_ISF_MASK))) /* Mask bits to zero which are setting */
    87.       | PORT_PCR_PS(0x01u)                                              /* Pull Select: Internal pullup resistor is enabled on the corresponding pin, if the corresponding PE field is set. */
    88.       | PORT_PCR_PE(0x01u)                                              /* Pull Enable: Internal pullup or pulldown resistor is enabled on the corresponding pin, if the pin is configured as a digital input. */
    89.     );

    90. int icm_init(void)
    91. {
    92.     unsigned char data[6];

    93.     I2C_ConfigurePins();

    94.     I2C_MasterTransferCreateHandle(I2C_BASEADDR, &g_m_handle, i2c_master_callback, NULL);
    95.     i2c_master_config_t masterConfig;
    96.     /*
    97.      * masterConfig.baudRate_Bps = 100000U;
    98.      * masterConfig.enableStopHold = false;
    99.      * masterConfig.glitchFilterWidth = 0U;
    100.      * masterConfig.enableMaster = true;
    101.    */
    102.     I2C_MasterGetDefaultConfig(&masterConfig);
    103.     I2C_MasterInit(I2C_BASEADDR, &masterConfig, CLOCK_GetFreq(I2C0_CLK_SRC));
    104.    
    105.     /* Reset device. */
    106.     data[0] = BIT_RESET;
    107.     if(I2C_WriteReg(I2C_BASEADDR,st.hw->addr,st.reg->pwr_mgmt_1,data[0]))
    108.       return -1;
    109.     delay_ms(100);

    110.     /* Wake up chip. */
    111.     data[0] = 0x00;
    112.    
    113.     if (I2C_WriteReg(I2C_BASEADDR,st.hw->addr, st.reg->pwr_mgmt_1, data[0]))
    114.         return -1;

    115.     /* ICM20608 has no DMP therefore no need to share memory */
    116.     data[0] = BIT_FIFO_SIZE_4096;
    117.    
    118.     if (I2C_WriteReg(I2C_BASEADDR,st.hw->addr, st.reg->accel_cfg2, data[0]))
    119.         return -1;

    120.     /* Set to invalid values to ensure no I2C writes are skipped. */
    121.     st.chip_cfg.sensors = 0xFF;
    122.     st.chip_cfg.gyro_fsr = 0xFF;
    123.     st.chip_cfg.accel_fsr = 0xFF;
    124.     st.chip_cfg.gyro_lpf = 0xFF;
    125.     st.chip_cfg.accel_lpf = 0xFF;
    126.     st.chip_cfg.sample_rate = 0xFFFF;
    127.     st.chip_cfg.fifo_enable = 0xFF;
    128.     st.chip_cfg.bypass_mode = 0xFF;
    129.    
    130.     /* icm_set_sensors always preserves this setting. */
    131.     st.chip_cfg.clk_src = INV_CLK_PLL;
    132.     /* Handled in next call to icm_set_bypass. */
    133.     st.chip_cfg.active_low_int = 1;
    134.     st.chip_cfg.latched_int = 0;
    135.     st.chip_cfg.int_motion_only = 0;
    136.     st.chip_cfg.lp_accel_mode = 0;
    137.     memset(&st.chip_cfg.cache, 0, sizeof(st.chip_cfg.cache));

    138.     if (icm_set_gyro_fsr(2000))
    139.         return -1;
    140.     if (icm_set_accel_fsr(2))
    141.         return -1;
    142.     if (icm_set_gyro_lpf(50))
    143.         return -1;
    144.     if (icm_set_accel_lpf(50))
    145.         return -1;
    146.     if (icm_set_sample_rate(50))
    147.         return -1;
    148.     if (icm_configure_fifo(0))
    149.         return -1;

    150.     if (icm_set_bypass(0))
    151.         return -1;

    152.     icm_set_sensors(0);
    153.     return 0;
    154. }
    复制代码
    全速运行起来,代码第一次运行到I2C写入的地方,也就是下面这句后,会进入到I2C_WriteReg函数,然后就停在
        /*  wait for transfer completed. */
        while ((!nakFlag) && (!completionFlag))
        {
        }
    这个死循环里。
    1. I2C_WriteReg(I2C_BASEADDR,st.hw->addr,st.reg->pwr_mgmt_1,data[0]
    复制代码

    各位大佬帮小弟看看,到底是哪里有问题呢。这个代码是以前K64上能成功读取MPU6050的。


    最佳答案

    楼主啊,你这洋洋洒洒代码会让其他小伙伴望而却步的,我的建议是你可以用示波器或逻辑分析仪捕捉一下KL26和K64与slave target通信时的波形,这样不是一目了然了吗?! ...
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

    该用户从未签到

    712

    主题

    6371

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    24874
    最后登录
    2025-7-18
    发表于 2017-7-26 16:41:57 | 显示全部楼层
    楼主啊,你这洋洋洒洒代码会让其他小伙伴望而却步的,我的建议是你可以用示波器或逻辑分析仪捕捉一下KL26和K64与slave target通信时的波形,这样不是一目了然了吗?!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-7-22 16:18
  • 签到天数: 77 天

    连续签到: 1 天

    [LV.6]常住居民II

    6

    主题

    242

    帖子

    5

    高级会员

    Rank: 4

    积分
    816
    最后登录
    2023-12-22
     楼主| 发表于 2017-7-28 22:46:00 | 显示全部楼层
    小恩GG 发表于 2017-7-26 16:41
    楼主啊,你这洋洋洒洒代码会让其他小伙伴望而却步的,我的建议是你可以用示波器或逻辑分析仪捕捉一下KL26和 ...

    谢谢,找到问题了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2021-1-28 20:09
  • 签到天数: 317 天

    连续签到: 1 天

    [LV.8]以坛为家I

    61

    主题

    1582

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    9277
    最后登录
    2022-5-12
    发表于 2017-7-29 00:20:07 | 显示全部楼层
    学习了           
    好好
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-20 05:04 , Processed in 0.096423 second(s), 25 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表