OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 22353|回复: 14

stm32f407 IIC 死在while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));!!!

[复制链接]

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
发表于 2013-1-6 16:05:55 | 显示全部楼层 |阅读模式
程序很简单,就是先初始化GPIO,然后模式设置,结果程序就卡在while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));一直不出来。麻烦大家帮我分析一下!
#include <stm32f4xx.h>
static void IIC1_GPIO_Configuration(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;
        //打开B口的时钟,PB6->SCL,PB7->SDA
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
        //先将对应寄存器配置为缺省值
        GPIO_StructInit(&GPIO_InitStructure);
        //选中6,7管脚
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
        //复用功能
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
        //IIC最大速度为400K
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        //开漏输出
        GPIO_InitStructure.GPIO_OType=GPIO_OType_OD;
        //不带上拉
        GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
        //将IO配置应用于对应寄存器
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        //管脚映射
        GPIO_PinAFConfig(GPIOB,GPIO_Pin_6,GPIO_AF_I2C1);
        GPIO_PinAFConfig(GPIOB,GPIO_Pin_7,GPIO_AF_I2C1);
}
static void IIC1_MODE_Configuration(void)
{
        I2C_InitTypeDef                I2C_InitStrycture;
        //打开IIC1时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
        //典型IIC速度为100K
        I2C_InitStrycture.I2C_ClockSpeed=100000;
        //IIC模式
        I2C_InitStrycture.I2C_Mode=I2C_Mode_I2C;
        //
        I2C_InitStrycture.I2C_DutyCycle=I2C_DutyCycle_2;
        //在STM32作为从机时的应答地址,做主机时不需理会
        I2C_InitStrycture.I2C_OwnAddress1=0x00;
        //使能IIC应答
        I2C_InitStrycture.I2C_Ack=I2C_Ack_Enable;
        //应答地址为7位(从机)
        I2C_InitStrycture.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
        //使能IIC
        I2C_Cmd(I2C1,ENABLE);
        //配置寄存器
        I2C_Init(I2C1,&I2C_InitStrycture);
        //允许一字节一应答的时序
        I2C_AcknowledgeConfig(I2C1, ENABLE);
}
void IIC1_Init(void)
{
        IIC1_GPIO_Configuration();
        IIC1_MODE_Configuration();
}
主程序很简单(串口程序就不贴出来了)
        USART1_Init();
        IIC1_Init();
        printf("\r\n 开始测试        \n\r");
        while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
        printf("写入数据\n\r");
就这么简短的几句话,卡在那里了。配置检查了很久都没有看出问题来!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
 楼主| 发表于 2013-1-6 16:10:53 | 显示全部楼层
经过初始化以后SCL和SDA就都被拉低了
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-1-8
在线时间
0 小时
发表于 2013-1-8 10:01:24 | 显示全部楼层
回复【2楼】304301959:
---------------------------------
楼主问题解决了没有,我的也是经过初始化后,SCL和SDA都被拉低了,但在发数据时SCL正常了,有波形,但SDA一直为低,总线没有释放。
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
 楼主| 发表于 2013-1-8 18:25:30 | 显示全部楼层
回复【3楼】parallax:
---------------------------------
还没有找出原因来
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-1-8
在线时间
0 小时
发表于 2013-1-9 14:28:25 | 显示全部楼层
回复【4楼】304301959:
回复【3楼】parallax: --------------------------------- 还没有找出原因来
---------------------------------
麻烦楼主找出来后公布一下原因,我也正在找原因在。
库函数I2C.C中的说明
                How to use this driver
  *          ===================================================================
  *          1. Enable peripheral clock using RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2Cx, ENABLE)
  *             function for I2C1, I2C2 or I2C3.
  *
  *          2. Enable SDA, SCL  and SMBA (when used) GPIO clocks using 
  *             RCC_AHBPeriphClockCmd() function. 
  *
  *          3. eripherals alternate function: 
  *                 - Connect the pin to the desired peripherals' Alternate 
  *                   Function (AF) using GPIO_PinAFConfig() function
  *                 - Configure the desired pin in alternate function by:
  *                   GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF
  *                 - Select the type, pull-up/pull-down and output speed via 
  *                   GPIO_PuPd, GPIO_OType and GPIO_Speed members
  *                 - Call GPIO_Init() function
  *                 Recommended configuration is ush-Pull, ull-up, Open-Drain.
  *                 Add an external pull up if necessary (typically 4.7 KOhm).      
  *        
  *          4. rogram the Mode, duty cycle , Own address, Ack, Speed and Acknowledged
  *             Address using the I2C_Init() function.
  *
  *          5. Optionally you can enable/configure the following parameters without
  *             re-initialization (i.e there is no need to call again I2C_Init() function):
  *              - Enable the acknowledge feature using I2C_AcknowledgeConfig() function
  *              - Enable the dual addressing mode using I2C_DualAddressCmd() function
  *              - Enable the general call using the I2C_GeneralCallCmd() function
  *              - Enable the clock stretching using I2C_StretchClockCmd() function
  *              - Enable the fast mode duty cycle using the I2C_FastModeDutyCycleConfig()
  *                function.
  *              - Configure the NACK position for Master Receiver mode in case of 
  *                2 bytes reception using the function I2C_NACKPositionConfig().  
  *              - Enable the EC Calculation using I2C_CalculatePEC() function
  *              - For SMBus Mode: 
  *                   - Enable the Address Resolution rotocol (ARP) using I2C_ARPCmd() function
  *                   - Configure the SMBusAlert pin using I2C_SMBusAlertConfig() function
  *
  *          6. Enable the NVIC and the corresponding interrupt using the function 
  *             I2C_ITConfig() if you need to use interrupt mode. 
  *
  *          7. When using the DMA mode 
  *                   - Configure the DMA using DMA_Init() function
  *                   - Active the needed channel Request using I2C_DMACmd() or
  *                     I2C_DMALastTransferCmd() function.
  *              @note When using DMA mode, I2C interrupts may be used at the same time to
  *                    control the communication flow (Start/Stop/Ack... events and errors).
  * 
  *          8. Enable the I2C using the I2C_Cmd() function.
  * 
  *          9. Enable the DMA using the DMA_Cmd() function when using DMA mode in the 
  *             transfers.  


的第3条的最后一句话,Recommended configuration is ush-Pull, ull-up, Open-Drain.这个地方到底应该怎么配置,又是Push-Pull,又是 Open-Drain?
我按照库文件的说明一项一项的来配置,还是只要是把IO初始化完后,SDA就拉低了
回复 支持 反对

使用道具 举报

260

主题

809

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1895
金钱
1895
注册时间
2012-10-28
在线时间
357 小时
发表于 2013-1-9 15:46:47 | 显示全部楼层
回复【楼主位】304301959:
---------------------------------
你这个好像没有打开i2c的时钟吧
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
 楼主| 发表于 2013-1-9 16:17:45 | 显示全部楼层
回复【6楼】hpdell:
---------------------------------
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
这句话已经开了
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
 楼主| 发表于 2013-1-9 16:19:18 | 显示全部楼层
回复【5楼】parallax:
---------------------------------
看来你和我遇到的问题一样啊。我今天早上还是没有找出来。先用软件模拟算了。
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-1-8
在线时间
0 小时
发表于 2013-1-9 16:48:38 | 显示全部楼层
回复【8楼】304301959:
---------------------------------
有没有ST的FAE的联系方式啊,初始化很简单的过程,就是配置几个寄存器而已,不知道为什么会出问题,用F103的用同样的步骤配置,是正常的,F407就不行,不知道什么原因。
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-1-8
在线时间
0 小时
发表于 2013-1-9 16:49:47 | 显示全部楼层
回复【6楼】hpdell:
---------------------------------
有打开I2C时钟的语句
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
 楼主| 发表于 2013-1-10 10:40:52 | 显示全部楼层
回复【9楼】parallax:
---------------------------------
没有哦
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-1-8
在线时间
0 小时
发表于 2013-1-11 14:06:18 | 显示全部楼层
回复【2楼】304301959:
---------------------------------
你用下面的初始化步骤试一下,我的I2C现在正常了


void  I2CMasterInit(void)
{
        
 //   I2C_DeInit(I2C_MASTER);
    
    I2CMaster_RCC_Configuration();
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,  ENABLE);// enable GPIOB CLOCK
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
      /* Reset sEE_I2C IP */
    RCC_APB1PeriphResetCmd(I2C_MASTER_CLK, ENABLE);
  /* Release reset signal of sEE_I2C IP */
    RCC_APB1PeriphResetCmd(I2C_MASTER_CLK, DISABLE);//非常重要,没有这句RESER语句会导致总线不能释放
    I2CMaster_GPIO_Configuration();
           
        
   // I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost;//;I2C_Mode_I2C, very importan ,or I2C can not be work
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//for fast model
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = I2C_MSATER_SPEED;
    
    // I2CMaster_NVIC_Configuration();
    /*!< Enable SMBus EVT interrupt */

    I2C_Cmd(I2C_MASTER, ENABLE);
    I2C_Init(I2C_MASTER, &I2C_InitStructure);
    I2CMaster_NVIC_Configuration();//必须放在I2C_Init(I2C_MASTER, &I2C_InitStructure)函数后面,放在前面就不正常。2013.1.10 cheng yun
    I2C_ITConfig(I2C_MASTER, I2C_IT_EVT | I2C_IT_ERR| I2C_IT_BUF, ENABLE);//| I2C_IT_ERR very importan ,or I2C can not be work 
}

void I2CMaster_RCC_Configuration(void)
{
    /* Enable peripheral clocks --------------------------------------------------*/
    RCC_APB1PeriphClockCmd(I2C_MASTER_CLK, ENABLE);   

}
void I2CMaster_GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure; 
    // I2C I0口初始化.
    // Configure I2C1 pins: SCL and SDA ---------------------------------------
    
  //  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6|GPIO_PinSource9, GPIO_AF_I2C1);//非常重要,一定不能这么写,否则SCL SDA都拉低,一定要分开写,见下面。2013.1.10 cheng yun
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);

   // GPIO_InitStructure.GPIO_Pin =  I2C_MASTER_SCL | I2C_MASTER_SDA;
   
//CONFIG scl
    GPIO_InitStructure.GPIO_Pin =  I2C_MASTER_SCL;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_MASTER_GPIO, &GPIO_InitStructure);
//CONFIG SDA

    GPIO_InitStructure.GPIO_Pin =  I2C_MASTER_SDA;
    //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
   //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
   //GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
   //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_MASTER_GPIO, &GPIO_InitStructure);

}
void I2CMaster_NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 1 bit for pre-emption priority, 3 bits for subpriority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    /* Configure and enable I2CMASTER interrupt --------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = I2C_MASTER_EV_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVICPreemptionPriority_I2CMASTER; //same as mido
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVICSubPriorityPriority_I2CMASTER_EV;
    NVIC_Init(&NVIC_InitStructure);

    /* Configure and enable SI2CMASTER interrupt --------------------------------*/
    NVIC_InitStructure.NVIC_IRQChannel = I2C_MASTER_ER_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVICPreemptionPriority_I2CMASTER; //same as mido
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVICSubPriorityPriority_I2CMASTER_ER;
    NVIC_Init(&NVIC_InitStructure);
}


你可以参考下库函数文件夹里面的例程,有个I2C的文件夹,也可以按照它的初始化步骤来。
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2012-11-9
在线时间
0 小时
 楼主| 发表于 2013-1-11 18:07:25 | 显示全部楼层
回复【12楼】parallax:
---------------------------------
好的,我试试
回复 支持 反对

使用道具 举报

11

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2015-7-6
在线时间
5 小时
发表于 2015-8-1 10:14:36 | 显示全部楼层
感谢分享!!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2019-7-30
在线时间
1 小时
发表于 2019-8-12 13:27:14 | 显示全部楼层
本帖最后由 baijie0711 于 2019-8-12 13:40 编辑

同样遇到这个问题,感谢#12楼分享。
最后增加以下代码后解决:

        GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);


配置内容如下:
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
                RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);

        GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStructure.I2C_OwnAddress1 = deviceAddr;
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
        I2C_InitStructure.I2C_ClockSpeed = kHZ * 1000;
   
        I2C_Cmd(I2Cx, ENABLE);
        I2C_Init(I2Cx, &I2C_InitStructure);
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-16 03:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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