打印
[PIC®/AVR®/dsPIC®产品]

PIC32MZ的硬件I2C

[复制链接]
10099|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
强仔00001|  楼主 | 2014-8-2 15:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我现在调到PIC32MZ的I2C,本来想用PIC官方的harmony库函数来写一个初始化MPU6050的程序。但试了两三天也不行,无奈之下看了PIC32MZ的I2C参考手册的那部分。写了一个寄存器版的读取MPU6050的程序。当还是有问题。
我的代码是:

void I2C1_Init()
{
    uint32_t actualClock;
    PLIB_I2C_BaudRateSet ( MY_I2C_ID, MY_CLOCK_FREQUENCY, MY_BAUD_RATE);
    actualClock = PLIB_I2C_BaudRateGet ( MY_I2C_ID, MY_CLOCK_FREQUENCY );
    if(abs(actualClock-MY_BAUD_RATE) > MY_BAUD_RATE/10);
    {
        while(1);
    }
    I2C1CONbits.A10M = 0;
    I2C1CONbits.SMEN = 0;
    I2C1CONbits.ON = 1;

}

void I2C1_Start()
{
    I2C1CONbits.SEN = 1;
    while(I2C1STATbits.P);
}
void I2C1_SendData(uint8_t Data)
{
    I2C1TRNbits.I2CTRN = Data;
    while(I2C1STATbits.TBF);
}

void I2C1_Stop()
{
    I2C1CONbits.PEN = 1;
}
#define OAR1_ADD0_Set ((uint16_t)0x0001)
#define OAR1_ADD0_Reset ((uint16_t)0xFFFE)
void Send7bitsAddress(uint8_t Address,uint8_t I2C_Direction)
{
    if(I2C_Direction == 0)
    {
        Address |= OAR1_ADD0_Set;
    }
    else
    {
        Address &= OAR1_ADD0_Reset;
    }
    I2C1TRNbits.I2CTRN = Address;
}

void I2C_Byte_Write(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data)
{
    I2C1_Start();
    Send7bitsAddress(SlaveAddress,1);
    while(I2C1STATbits.R_W);
    while(I2C1STATbits.TBF);
    I2C1_SendData(REG_Address);
    while(I2C1STATbits.TBF);
    I2C1_SendData(REG_data);
    while(I2C1STATbits.TBF);
    I2C1_Stop();

}

void MPU_6050_Init(void)
{
    I2C_Byte_Write(MPU6050_SlaveAddress,PWR_MGMT_1,0x00);
    delay(50000);
    I2C_Byte_Write(MPU6050_SlaveAddress,SMPLRT_DIV,0x07);
    delay(50000);
    I2C_Byte_Write(MPU6050_SlaveAddress,MPU6050_CONFIG,0x06);
    delay(50000);
    I2C_Byte_Write(MPU6050_SlaveAddress,GYRO_CONFIG,0x08);
    delay(50000);
    I2C_Byte_Write(MPU6050_SlaveAddress,ACCEL_CONFIG,0x08);
}

int main ( void )
{
    SYS_DEVCON_PerformanceConfig(SYS_CLK_FREQUENCY);
    I2C1_Init();
    while(1)
    {
       MPU_6050_Init();
    }

  /*
   Initialize the application. */
/* SYS_Initialize(NULL);

    while (true)
    {
        // Maintain the application's state machine.
        SYS_Tasks();
    }
*/
    /* Should not come here during normal operation */
    PLIB_ASSERT(false, "leaving main");
   
    return (EXIT_FAILURE);
}
但总是卡死在了while(1)的那句话,我想也想不明白我已经设置了100K的SCL频率,但还是有超过10%的误差。
第二个问题是卡在了while(I2C1STATbits.TBF);这句话,就是得不到应答。
同样的问题,问题一般都是很快会得较满意的回复。
希望有大神的解救,希望我的问题能得到解决。:'(
沙发
donghailao| | 2014-8-4 18:37 | 只看该作者
你这是高档机芯,我没用过,还要向你学习。

根据我在中、低档芯片里I2C的经验,问题多数出在底层初始化时序,没有严格按照 I2C 器件手册里要求的来。
可以考虑先给脉冲加入延时等待,成功后,逐步紧俏底层的延时,以提高效率。

使用特权

评论回复
板凳
yewuyi| | 2014-8-5 08:21 | 只看该作者
你先回答:以前弄过IIC吗?如果以前弄过,请问以前调通了吗?

使用特权

评论回复
地板
强仔00001|  楼主 | 2014-8-6 16:30 | 只看该作者
donghailao 发表于 2014-8-4 18:37
你这是高档机芯,我没用过,还要向你学习。

根据我在中、低档芯片里I2C的经验,问题多数出在底层初始化时 ...

硬件I2C怎样加延时??

使用特权

评论回复
5
donghailao| | 2014-8-13 10:43 | 只看该作者
本帖最后由 donghailao 于 2014-8-13 11:11 编辑

先用普通 I/O口,自己编写软件 模拟 IIC的时序(主机),底层可以添加延时。
用芯片自带的、现成的硬件口资源时,芯片底层的时序我只能调整波特率和一些位设置,实际上我没了延时的权利。在这种情况下如果通信不成功,感觉检查IIC口的初始化设置,如地址位数、应答位设置等什么参数。
32位的我没用过。

兼顾汇报给3#yewuyi版:
我以前在PIC18系用片上硬件资源 主机,驱动成功 PCF8583时钟成功
在PIC16、pic18片上普通I/O模拟成功了主机,也是驱动的8583芯片
R:\858300.jpg

不会上图我,顺便问问怎么上图,笨啊。  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

799

帖子

8

粉丝