野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12153|回复: 3

F429模拟I2C通信问题

[复制链接]
发表于 2016-4-10 23:44:49 | 显示全部楼层 |阅读模式
我用模拟I2C与ZLG7290通信,无法接收到正确的数据,收到的数据经常是0xff;下面是我的代码,请大神们帮忙解决一下,小弟万分感激!!!!   


问题:读出的数据不正确,有时候会有变化,有时候没有。小弟考虑硬件没什么大问题,主要是F429这个速率会不会影响模拟I2C的通信,这个问题我卡了半个月,一直没有解决,求大神帮忙


//定义SCL SDA管脚
#define SCL_H           GPIOH->BSRRL = GPIO_Pin_4
#define SCL_L           GPIOH->BSRRH = GPIO_Pin_4  
#define SDA_H           GPIOA->BSRRL = GPIO_Pin_5
#define SDA_L           GPIOH->BSRRH  = GPIO_Pin_5

#define SCL_read         GPIOH->IDR  & GPIO_Pin_4  
#define SDA_read         GPIOH->IDR  & GPIO_Pin_5

//IO口初始化
void I2C_GPIO_Config(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);//使能按键使用的引脚时钟               
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;//配置SCL引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStru cture.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOH,&GPIO_InitStructure);
     
    SCL_H;
    SDA_H;
}

//函数调用 这部分在网上download的 以前开发项目可以使用(在STM32107开发过)

void IIC_Delay(u16 times)
{
                        u16 loop,loop1;
                        for(loop=0;loop<times;loop++)
                        for(loop1=times;loop1>0;loop1--);
}

void IIC_SetSclPin(void)
{
                                SCL_H;
}

void IIC_ClrSclPin(void)
{
                                SCL_L;
}

void IIC_SetSdaPin(void)
{
    //GPIO_WriteBit(GPIOB,GPIO_Pin_9,Bit_SET);
                                SDA_H;
}

void IIC_ClrSdaPin(void)
{
    //GPIO_WriteBit(GPIOB,GPIO_Pin_9,Bit_RESET);
                                SDA_L;
}

bool IIC_GetSdaStus(void)
{
    bool tmp;
    /*if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)&0x01) tmp=TRUE;
    else tmp=FALSE;*/
    if (SDA_read)
                        tmp=1;
    else tmp=0;   
    return tmp;
}

bool IIC_CheckACK(void)
{
    return IIC_GetSdaStus();
}

void IIC_SetScl(bool HLow)
{
    HLow?IIC_SetSclPin():IIC_ClrSclPin();
}

void IIC_SetSda(bool HLow)
{
    HLow?IIC_SetSdaPin():IIC_ClrSdaPin();
}


void IIC_Start(void)
{
    IIC_SetScl(LOW);
    //  Delay(DelayTime);
    IIC_Delay(IIC_DELAYTIME);
    //  SDA(Hight);
    IIC_SetSda(HIGHT);
    //  Delay(DelayTime);
    IIC_Delay(IIC_DELAYTIME);
    // SCL(Hight);
    IIC_SetScl(HIGHT);
    //  Delay(DelayTime);
    IIC_Delay(IIC_DELAYTIME);
    //   SDA(Low);
    IIC_SetSda(LOW);
    //  Delay(DelayTime);
    IIC_Delay(IIC_DELAYTIME);
    //  SCL(Low);
    IIC_SetScl(LOW);
}

void IIC_Stop(void)
{

          IIC_SetSda(LOW);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetScl(HIGHT);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetSda(HIGHT);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetScl(LOW);
}
bool IIC_Send(u8 ucVal)  //I2C发送一个字节
{   
                   
          bool Ack;
    u16 AckLoop;
    u8 i;
    for(i=0;i<8;i++)
    {
        IIC_SetScl(LOW);
        IIC_Delay(IIC_DELAYTIME);
        IIC_SetSda((ucVal & 0x80)?TRUE:FALSE);
        IIC_Delay(IIC_DELAYTIME);
        IIC_SetScl(HIGHT);
        IIC_Delay(IIC_DELAYTIME);
        ucVal<<= 1;
    }
    IIC_SetScl(LOW);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetSda(HIGHT);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetScl(HIGHT);
    Ack = IIC_NOACK;
    for(AckLoop=0;AckLoop<ACKCHECKTIME;AckLoop++) //260us
    {
        if(!IIC_GetSdaStus())
        {
                Ack = IIC_ACK;
                break;
        }
        IIC_Delay(IIC_DELAYTIME);
    }
    IIC_SetScl(LOW);
    return Ack;                        //return success=0 / failure=1
}

u8 IIC_Read(bool bACK)   
{   
         
    u8 Data;
    u8 i;
    Data = 0;
    for(i=0;i<8;i++)
    {
        Data <<= 1;
        IIC_SetScl(LOW);
        IIC_Delay(IIC_DELAYTIME);
        IIC_SetSda(HIGHT);
        IIC_Delay(IIC_DELAYTIME);
        IIC_SetScl(HIGHT);
        IIC_Delay(IIC_DELAYTIME);
        if(IIC_GetSdaStus())
            Data |= 1;
        else
            Data &= 0xfe;
    }
    IIC_SetScl(LOW);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetSda(bACK);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetScl(HIGHT);
    IIC_Delay(IIC_DELAYTIME);
    IIC_SetScl(LOW);
    return Data;
}


bool IIC_ByteWrite(u8 DeviceAdd,u8 address,u8 ucVal)
{
       
                    
//          I2C_SDA_OUT();
   IIC_Start();
    if(IIC_Send(DeviceAdd|((address>>7)&0x0e)))//NACK
    {
        return IIC_NOACK;
    }
    IIC_Send((u8)(address&0xff));
    IIC_Send(ucVal);
    IIC_Stop();
    IIC_Delay(IIC_DELAYTIME);
    IIC_Delay(IIC_DELAYTIME);
    IIC_Delay(20*IIC_DELAYTIME);
    return IIC_ACK;
}

u8 IIC_ByteRead(u8 DeviceAdd,u8 address)
{
       
    u8 value;
    IIC_Start();
    IIC_Send(DeviceAdd|((address>>7)&0x0e));
    IIC_Send((u8)(address&0xff));
    IIC_Stop();
    IIC_Start();
    IIC_Send(DeviceAdd|0x01);
    value=IIC_Read(IIC_NOACK);
    IIC_Stop();
    IIC_Delay(IIC_DELAYTIME);
    IIC_Delay(IIC_DELAYTIME);
    IIC_Delay(IIC_DELAYTIME);
    return value;
}  

bool IIC_BytesWrite(u8 DeviceAdd,u8 address,u8 *buf,u16 nByte)   //
{
              
int lp=0;
    for(lp=0;lp<nByte;lp++)
    {
        IIC_ByteWrite(DeviceAdd,lp+address,*buf++);
    }
    return TRUE;
}

bool IIC_BytesRead(u8 DeviceAdd,u8 address,u8 *buf,u16 nByte)  //  从器件读地址 从器件内存单元地址 要写的数据地址 要写的数据字节 返回0 写数据成功 1在写数据过程中从器件回响NAK
{
              
    int lp=0;
    for(lp=0;lp<nByte;lp++)
    {
        *buf++=IIC_ByteRead(DeviceAdd,lp+address);
    }
    return TRUE;
}
//读取数据

   gKey.KeyVar = IIC_ByteRead(0x70, 0x01);


问题:读出的数据不正确,有时候会有变化,有时候没有。小弟考虑硬件没什么大问题,主要是F429这个速率会不会影响模拟I2C的通信,这个问题我卡了半个月,一直没有解决,求大神帮忙
回复

使用道具 举报

发表于 2016-4-11 08:40:06 | 显示全部楼层
速率会影响。直接用硬件iic吧,我们的例程都用硬件的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-4-11 12:45:27 | 显示全部楼层
那我如何改变通信的速率呢?我想把模拟I2C的问题解决了,谢谢  我现在读IO的时候就是有问题,是不是太快了,抓不到信号
回复 支持 反对

使用道具 举报

发表于 2016-4-11 19:51:10 | 显示全部楼层
爱莫能助,帮顶
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 19:07 , Processed in 0.026309 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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