你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

cube生成的i2c通讯不正常,望专家帮忙看下

[复制链接]
@@@义 提问时间:2017-6-25 15:38 /
今天调了一天,一开始地址写0x1c,i2c出错。之后改成0x38.就没问题了。但是读出的数据有问题,所有的都是ff。一直找不到问题。望各位帮看看。
/*                               MMA8451.c
*
*
//******************************************************************************
#include "i2c.h"
#include "gpio.h"
#include "include.h"
#include "math.h"

#define I2C1_WRITE_ADDRESS 0x38
#define I2C1_READ_ADDRESS  0x38
unsigned char  Stop = 0;
unsigned char  MMA845x_flag = 0;

unsigned char  ReadOutData[6];                // Read out from MMA845x
signed   int   Gx, Gy, Gz;           // X, Y, Z

/*******************************************************************************
**                           I2C Configeration
******************************************************************************/



void I2C_RegWrite(unsigned char Reg, unsigned char data)
{
          uint8_t TxData[2] = {Reg,data};
    while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)
   {
        if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
        {
            Error_Handler();
        }

    }

}
unsigned char I2C_RegRead(uint8_t REG_Address)
{
          uint8_t RxBuffer;
          while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,&REG_Address,1,500) != HAL_OK)
     {
          if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
                 {
                   Error_Handler();
                 }
     }
   
     if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,&RxBuffer,1,500) != HAL_OK)
     {
         if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
                 {
                   Error_Handler();
                 }
     }
     return RxBuffer;

}

void I2C_MultiRegsRead(unsigned char Reg, unsigned char *data)
{
                 data[0] = I2C_RegRead(0x01);
                 data[1] = I2C_RegRead(0x02);
                 data[2] = I2C_RegRead(0x03);
                 data[3] = I2C_RegRead(0x04);
                 data[4] = I2C_RegRead(0x05);
                 data[5] = I2C_RegRead(0x06);
}

/*******************************************************************************
**                        MMA845x Configeration
******************************************************************************/
#define   WHO_AM_I     0x0D
#define   DATA_CFG     0x0E
#define   HP_FILTER    0x0F
#define   CTRL_REG1    0x2A
#define   CTRL_REG2    0x2B
#define   CTRL_REG3    0x2C
#define   CTRL_REG4    0x2D
#define   CTRL_REG5    0x2E

void MMA845x_Reset(void)
{
     unsigned char RST = 1 << 6;
     
     I2C_RegWrite(CTRL_REG2, RST);
     HAL_Delay(500);  
         //__delay_cycles(10000);
}

void MMA845x_Standby(void)
{
     unsigned char ACTIVE = 0x01;
     
     I2C_RegWrite(CTRL_REG1, (I2C_RegRead(CTRL_REG1) & ~ACTIVE));
}

void MMA845x_OutputDataRate(void)
{
     unsigned char DR = 6 << 3;                // DR[2:0] = 110, 6.25Hz
     
     I2C_RegWrite(CTRL_REG1, (I2C_RegRead(CTRL_REG1) | DR));
}

void MMA845x_OverSamplingMode(void)
{
     unsigned char MODS = 0x01;                // MODS[1:0] = 01, Low Power
     
     I2C_RegWrite(CTRL_REG2, (I2C_RegRead(CTRL_REG2) | MODS));
}

void MMA845x_FilterCutoff(void)
{
     unsigned char HPF_BYP = 1 << 5;
     unsigned char LPF_EN  = 1 << 4;
     
     I2C_RegWrite(HP_FILTER, (I2C_RegRead(HP_FILTER) | HPF_BYP));
     I2C_RegWrite(HP_FILTER, (I2C_RegRead(HP_FILTER) | LPF_EN));
}

void MMA845x_InterruptPolarity(void)
{
     unsigned char PP_OD = 0x01;               // Open-Drain on interrupt pad

     I2C_RegWrite(CTRL_REG2, (I2C_RegRead(CTRL_REG2) | PP_OD));
}

void MMA845x_InterruptEnable(void)
{
     unsigned char INT_EN_DRDY = 0x01;         // Data Ready interrupt enable
     
     I2C_RegWrite(CTRL_REG4, (I2C_RegRead(CTRL_REG4) | INT_EN_DRDY));
}

void MMA845x_InterruptConfig(void)
{
     unsigned char INT_CONFIG_DRDY = 0x01;     // Interrupt is routed to INT1 pin
     
     I2C_RegWrite(CTRL_REG5, (I2C_RegRead(CTRL_REG5) | INT_CONFIG_DRDY));
}

void MMA845x_Active(void)
{
     unsigned char ACTIVE = 0x01;
     
     I2C_RegWrite(CTRL_REG1, (I2C_RegRead(CTRL_REG1) | ACTIVE));
}

void MMA845x_Init(void)
{
//                MX_I2C1_Init();
                 MMA845x_Reset();
         //        MMA845x_Standby();
                 //MMA845x_OutputDataRate();
         //        MMA845x_OverSamplingMode();
                 MMA845x_FilterCutoff();
                 MMA845x_InterruptPolarity();
                 MMA845x_InterruptConfig();
                 MMA845x_InterruptEnable();
                 MMA845x_Active();
//        Single_Write(MMA845x_IIC_ADDRESS,CTRL_REG1,ASLP_RATE_20MS+DATA_RATE_5MS);
//        Single_Write(MMA845x_IIC_ADDRESS,XYZ_DATA_CFG_REG, FULL_SCALE_2G);
//        Single_Write(MMA845x_IIC_ADDRESS,CTRL_REG1, ACTIVE_MASK);
//          I2C_RegWrite(CTRL_REG1, 0x10);
//                I2C_RegWrite(0x0E, 0x00);
//          MMA845x_Active();
//                //I2C_RegWrite(CTRL_REG1, 0x10);

}


void MMA845x_ReadXYZ(void)
{
     I2C_MultiRegsRead(0x01, ReadOutData);
   
     Gx = (ReadOutData[0] << 8) | ReadOutData[1];
     Gy = (ReadOutData[2] << 8) | ReadOutData[3];
     Gz = (ReadOutData[4] << 8) | ReadOutData[5];

}


收藏 评论9 发布时间:2017-6-25 15:38

举报

9个回答
霹雳之火 回答时间:2017-6-25 22:25:26
建议在读数据之前 先只读一下设备的id 如果id可以读出来 说明i2c通信正常 然后再读数据 调试设备的初始化 中断 都出来的数据   仅供参考

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

@@@义 回答时间:2017-6-26 08:50:22
霹雳之火 发表于 2017-6-25 22:25
建议在读数据之前 先只读一下设备的id 如果id可以读出来 说明i2c通信正常 然后再读数据 调试设备的初始化  ...

老兄,我读id了。好像也不正常。但是写函数正常啊。真是不懂哪出的问题。我要是把mma8451的地址改成非0x38,写的这个指令都过不去,地址用0x38就能通过i2c写指令,但读出的数据就一直不对。真是弄不清啊 。老兄,帮看看代码又没问题吧。
@@@义 回答时间:2017-6-26 09:04:16
霹雳之火 发表于 2017-6-25 22:25
建议在读数据之前 先只读一下设备的id 如果id可以读出来 说明i2c通信正常 然后再读数据 调试设备的初始化  ...

读出的设备id也不对也是ff。证明没有通讯么?但很奇怪,我只有把地址id设置038,程序才能过i2cwrite函数,这第一步是不是证明已经mma8451有应答了呢 ?
霹雳之火 回答时间:2017-6-27 08:45:52
@@@义 发表于 2017-6-26 09:04
读出的设备id也不对也是ff。证明没有通讯么?但很奇怪,我只有把地址id设置038,程序才能过i2cwrite函数 ...

HAL_I2C_Master_Transmit 是发送函数,HAL_I2C_Master_Receive是接收函数
I2C_RegWrite 是写寄存器,只要调用HAL_I2C_Master_Transmit就可以了
I2C_RegRead 是读寄存器,一般先调用HAL_I2C_Master_Transmit 写要读的寄存器的地址,然后调用HAL_I2C_Master_Receive函数来读
如果id的寄存器地址是0,调用  ret= I2C_RegRead(0) 就可以了,ret即是id的值,这个值确保正确,才能证明i2c通信正常  请参考

评分

参与人数 1ST金币 +6 收起 理由
MrJiu + 6

查看全部评分

@@@义 回答时间:2017-6-27 08:55:08
程序能读出来了,但用的是  HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x01, 1, &data[0], 1, 35);
                HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x02, 1, &data[1], 1, 35);
                HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x03, 1, &data[2], 1, 35);
                HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x04, 1, &data[3], 1, 35);
                HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x05, 1, &data[4], 1, 35);
                HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x06, 1, &data[5], 1, 35);
          //HAL_I2C_Mem_Read(&hi2c1, I2C1_READ_ADDRESS, 0x01, 0x06, data, 6, 3500);
这个函数。用那个hal-i2ctransmit 和个hal-i2crecive函数怎么也不行.还有就是我用HAL_I2C_Mem_Read这个函数一起读6个寄存器也读不出(见最后一行)。真是搞不明白。
MrJiu 回答时间:2017-6-27 09:31:44
虽然我都是用的模拟的,硬件I2C基本不怎么用,但是呢,最好用示波器看一下波形!!!!如果输出波形不匹配,就看配置函数有哪些问题。。。
@@@义 回答时间:2017-6-27 10:49:32
霹雳之火 发表于 2017-6-27 08:45
HAL_I2C_Master_Transmit 是发送函数,HAL_I2C_Master_Receive是接收函数
I2C_RegWrite 是写寄存器,只 ...

我用其它的函数读出来了。见楼下。我还得仔细琢磨琢磨之前的函数为什么不成。谢谢老兄。
@@@义 回答时间:2017-6-28 08:25:04
MrJiu 发表于 2017-6-27 09:31
虽然我都是用的模拟的,硬件I2C基本不怎么用,但是呢,最好用示波器看一下波形!!!!如果输出波形不匹配 ...

我觉得还是用本身的i2c更好,出问题基本原因都是都mcu本身的理解不够到位造成的。
brightsm 回答时间:2019-4-22 22:29:50
我也遇到这种情况,HAL_I2C_Master_Receive这个函数是不是有问题呀,接收时通过逻辑分析仪查看波形不对。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版