野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11144|回复: 5

硬件IIC Init后一直卡在bus busy

[复制链接]
发表于 2017-7-25 17:46:41 | 显示全部楼层 |阅读模式
各位大神,本人写了一份硬件IIC   启动后一直卡在while(I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY));这里  如果注释掉以后也不能够初始化成功,哪位高手麻烦指导下谢谢,调了一整天了。。。
下面是代码部分:

#include "bsp_iic.h"
#include "bsp_usart.h"

static __IO uint32_t  I2CTimeout;

void IIC_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB1PeriphClockCmd(IIC_CLK, ENABLE);       // ¿aÆôIIC¸′óÃê±Öó
    RCC_APB2PeriphClockCmd(IIC_GPIO_CLK, ENABLE);  // ¿aÆôGPIOê±Öó

    GPIO_InitStructure.GPIO_Pin   = IIC_GPIO_PIN_SCL;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = IIC_GPIO_PIN_SDA;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IIC_GPIO_PORT, &GPIO_InitStructure);
}

void IIC_TypeDef_Init(void)
{
    I2C_InitTypeDef IIC_InitStructure;

    IIC_InitStructure.I2C_ClockSpeed            = IIC_CLK_Speed;
    IIC_InitStructure.I2C_Mode                  = I2C_Mode_I2C;
    IIC_InitStructure.I2C_DutyCycle             = I2C_DutyCycle_16_9;
    IIC_InitStructure.I2C_OwnAddress1           = IIC_OWNADDRESS;
    IIC_InitStructure.I2C_Ack                   = I2C_Ack_Enable;
    IIC_InitStructure.I2C_AcknowledgedAddress   = I2C_AcknowledgedAddress_7bit;

    I2C_Init(IICx, &IIC_InitStructure);
    I2C_Cmd (IICx, ENABLE);
}

void IIC_Init(void)
{
    IIC_GPIO_Init();
    IIC_TypeDef_Init();
}

static uint8_t IIC_TIMEOUT_USERCALLBACK(uint8_t errcode)
{
    printf(" IIC wait timeout! errcode = %d\n",errcode);
    return 0;
}

uint8_t IIC_Byte_Write(uint8_t DeviceAddr, uint8_t WriteAddr, uint8_t* wpBuffer)
{
    while(I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY));
    // IIC start
    I2C_GenerateSTART(IICx, ENABLE);

    // IIC sendDeviceAddr  EV5 set
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(0);
    }
    I2C_Send7bitAddress(IICx, DeviceAddr, I2C_Direction_Transmitter);

    // IIC sendRegisterAddr  EV6 set
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(1);
    }
    I2C_SendData(IICx, WriteAddr);

    // IIC sendData  EV8
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(2);
    }
    I2C_SendData(IICx, *wpBuffer);

    // IIC Stop  EV8_2
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(3);
    }
    I2C_GenerateSTOP(IICx, ENABLE);

    return 1;
}


uint8_t IIC_Byte_Read(uint8_t DeviceAddr, uint8_t ReadAddr, uint8_t* rpBuffer)
{
    while(I2C_GetFlagStatus(IICx, I2C_FLAG_BUSY));
    // IIC start
    I2C_GenerateSTART(IICx, ENABLE);

    // IIC sendDeviceAddr  EV5 set
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_MODE_SELECT))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(4);
    }
    I2C_Send7bitAddress(IICx, DeviceAddr, I2C_Direction_Transmitter);

    // IIC sendRegisterAddr  EV6 set
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(5);
    }
    I2C_SendData(IICx, ReadAddr);

    // IIC sendData  EV7
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(6);
    }
    *rpBuffer = I2C_ReceiveData(IICx);

    // IIC Stop  EV7_1/EV7
    I2CTimeout = I2CT_FLAG_TIMEOUT;
    while(!I2C_CheckEvent(IICx, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
        if((I2CTimeout--) == 0)
            return IIC_TIMEOUT_USERCALLBACK(7);
    }
    I2C_GenerateSTOP(IICx, ENABLE);

    return 1;
}

//------------------------IIC_EEPROM_test----------------------------
void IIC_EEPROM_test(void)
{
    uint8_t ReadRegAddr  = 0x01;
    uint8_t WriteRegAddr = 0x01;
    uint8_t ReadData;
    uint8_t WriteData = 0x23;

    IIC_Byte_Write(EEPROM_ADDRESS, WriteRegAddr, &WriteData);
    IIC_Byte_Read(EEPROM_ADDRESS, ReadRegAddr, &ReadData);

    printf("WriteData = 0x%x\n",WriteData);
    printf("ReadData = 0x%x\n",ReadData);
}



int main(void)
{
    Usart_Init();
    IIC_Init();
//    IIC_EEPROM_test();

    printf("This is a IIC_test!!!\n");
    while(1)
    {
        IIC_EEPROM_test();
    }
}

回复

使用道具 举报

 楼主| 发表于 2017-7-25 17:48:01 | 显示全部楼层
Init之后SCL一直处于高电平状态!
回复 支持 反对

使用道具 举报

发表于 2017-7-25 18:02:02 | 显示全部楼层
确认外部电路、引脚正确这程序还卡的话,改用软件IIC
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-25 18:32:10 来自手机 | 显示全部楼层
flyleaf 发表于 2017-7-25 18:02
确认外部电路、引脚正确这程序还卡的话,改用软件IIC

外部电路正确,已经用demo验证过。我想先把硬件弄清楚,模拟的先不管     但是硬件不知道拉在哪里
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-26 10:19:06 | 显示全部楼层
现在重启电脑后可以跑一次 IIC_Byte_Write(); 函数    第二次再写或者读就卡到  I2C_Send7bitAddress(IICx, DeviceAddr, I2C_Direction_Transmitter);这个函数了
回复 支持 反对

使用道具 举报

发表于 2019-4-24 00:56:33 | 显示全部楼层
你好  请问搞定了么  我和你UI到一样的 情况但是我不是卡在 地址发送 我是卡在 一直检测不到BUS空闲 ,但是烧写一下又不行了   软件IIC没问题 确定不是 板子硬件问题  然后在重新烧录硬件IIC的时候 就通讯成功了  但是板子复位一下  就又不行了  
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-16 16:47 , Processed in 0.035726 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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