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

STM32F4 I2C 查询方式 自发自收问题

[复制链接]
lovelifett 提问时间:2014-1-11 16:30 /
 本人菜鸟,初学STM32F4 在调试I2C程序时,用I2C1作为主发送,I2C2作为从接收,进行自发自收,可是程序一直卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));上,一直找不出原因,求高手指导
以下是全部代码
#include"stm32F4xx.h"
 
void RCC_Configuration(void);
void GPIO_Configuration(void);
void I2C_Configuration(void);
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction);
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data);
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx);
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx);
void I2C_stop(I2C_TypeDef* I2Cx);
void Delay(int nCount);
 
int main(void)
{  
         RCC_Configuration();
   GPIO_Configuration();
   I2C_Configuration();       
   while(1)
         {                  int data=0;
                      I2C_start(I2C1,0x300;c2--);
        };
}
收藏 评论10 发布时间:2014-1-11 16:30

举报

10个回答
fengye5340 回答时间:2014-1-12 12:36:11

RE:STM32F4 I2C 查询方式 自发自收问题

ST的IIC为了规避专利,采用了独特的设计,楼主做硬件IIC时要严格遵守ST的设计思路才行,要不然容易出错。我花了一周的时间才把硬件IIC搞定,下面给你提供已经调试成功的两个函数作为参考:
如果你把这两个函数理解好了,后面页写函数和随机写函数都能搞定了。
void I2C_Write_OneByte(unsigned char Write_Addr,unsigned char Data)
{   
                      
        /*!< While the bus is busy */
              while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
        {
                      
        }   
        /* Start the config sequence */
        I2C_GenerateSTART(I2C1, ENABLE);
        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /* Test on EV5 and clear it */
        {  
        }      
        I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter); /* Transmit the slave address and enable writing operation */
       while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
       {
       }
       I2C_SendData(I2C1, Write_Addr);  /* Transmit the first address for write operation */
       while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING))  /* Test on EV8 and clear it */
       {  
       }
  
        I2C_SendData(I2C1, Data); /* Prepare the register value to be sent */
  
       /*!< Wait till all data have been physically transferred on the bus */
        while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF))
        {
        }
        /* End the configuration sequence */
        I2C_GenerateSTOP(I2C1, ENABLE);  
   
}
unsigned char  I2C_Read_OneByte(unsigned char Read_Addr)
{
        unsigned char  temp = 0;
        unsigned int   Timeout=0;  
        Timeout = I2C_Timeout ;       
              //I2C_AcknowledgeConfig(I2C1, ENABLE);               
       /*!< While the bus is busy */
              while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
        {
          if((Timeout--) == 0) return 1;
                     
        }
        /* Start the config sequence */
        I2C_GenerateSTART(I2C1, ENABLE);
        Timeout = I2C_Timeout ;
      
        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* Test on EV5 and clear it */
        {                                     
          if((Timeout--) == 0) return 1;                 
        }
        /* Transmit the slave address and enable writing operation */
        I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter);
        
        Timeout = I2C_Timeout ;
        while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
        {
          if((Timeout--) == 0) return 1;                 
               
        }
        /* Transmit the register address to be read */
        I2C_SendData(I2C1, Read_Addr);
      
        Timeout = I2C_Timeout ;
        while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET)   /* Test on EV8 and clear it */
        {
          if((Timeout--) == 0) return 1;                          
        }
  
        /*!< Send START condition a second time */  
        I2C_GenerateSTART(I2C1, ENABLE);

        
         Timeout = I2C_Timeout ;
         while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
        {
           if((Timeout--) == 0) return 1;                          
        }
  
         /*!< Send device address for read */
         I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Receiver);  
  
         /* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
            Timeout = I2C_Timeout ;
            while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET)  //EV6
            {
              if((Timeout--) == 0) return 1;                           
            }      
            /*!< Disable Acknowledgment */
           I2C_AcknowledgeConfig(I2C1, DISABLE);   
           /* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
           (void)I2C1->SR2;
                               
         /*!< Send STOP Condition */
         I2C_GenerateSTOP(I2C1, ENABLE);
         /* Wait for the byte to be received */
         Timeout = I2C_Timeout ;
         while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
         {
          if((Timeout--) == 0) return 1;                        
         }
          /*!< Read the byte received from the device */
          temp = I2C_ReceiveData(I2C1);
          /* Wait to make sure that STOP flag has been cleared */
          Timeout = I2C_Timeout ;
          while(I2C1->CR1 & I2C_CR1_STOP)
         {
             if((Timeout--) == 0) return 1;                           
         }  
  
         /*!< Re-Enable Acknowledgment to be ready for another reception */
         I2C_AcknowledgeConfig(I2C1, ENABLE);   
         /* Clear AF flag for next communication */
         I2C_ClearFlag(I2C1, I2C_FLAG_AF);  
         /* Return the byte read from device */                       
          return temp;
}
有缘于你 回答时间:2014-1-12 15:07:50

RE:STM32F4 I2C 查询方式 自发自收问题

用示波器或逻辑分析仪看看波形
dzc2001 回答时间:2014-1-12 19:12:26

回复:STM32F4 I2C 查询方式 自发自收问题

 是不是硬件不通?
勒布朗 回答时间:2014-1-13 10:48:42

RE:STM32F4 I2C 查询方式 自发自收问题

示波器观察数据是否发出,数据石头接收到
lovelifett 回答时间:2014-1-13 17:02:08

回复:STM32F4 I2C 查询方式 自发自收问题

回复第 2 楼 于2014-01-12 12:36:11发表:
ST的IIC为了规避专利,采用了独特的设计,楼主做硬件IIC时要严格遵守ST的设计思路才行,要不然容易出错。我花了一周的时间才把硬件IIC搞定,下面给你提供已经调试成功的两个函数作为参考:
如果你把这两个函数理解好了,后面页写函数和随机写函数都能搞定了。
void I2C_Write_OneByte(unsigned char Write_Addr,unsigned char Data)
{   

/*!< While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{

}   
/* Start the config sequence */
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /* Test on EV5 and clear it */
{  
}      
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter); /* Transmit the slave address and enable writing operation */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
{
}
I2C_SendData(I2C1, Write_Addr);  /* Transmit the first address for write operation */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING))  /* Test on EV8 and clear it */
{  
}

I2C_SendData(I2C1, Data); /* Prepare the register value to be sent */

/*!< Wait till all data have been physically transferred on the bus */
while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF))
{
}
/* End the configuration sequence */
I2C_GenerateSTOP(I2C1, ENABLE);  

}
unsigned char  I2C_Read_OneByte(unsigned char Read_Addr)
{
unsigned char  temp = 0;
unsigned int   Timeout=0;  
Timeout = I2C_Timeout ;       
//I2C_AcknowledgeConfig(I2C1, ENABLE);               
/*!< While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
if((Timeout--) == 0) return 1;

}
/* Start the config sequence */
I2C_GenerateSTART(I2C1, ENABLE);
Timeout = I2C_Timeout ;

while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))  /* Test on EV5 and clear it */
{                                     
if((Timeout--) == 0) return 1;                 
}
/* Transmit the slave address and enable writing operation */
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter);

Timeout = I2C_Timeout ;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
{
if((Timeout--) == 0) return 1;                 

}
/* Transmit the register address to be read */
I2C_SendData(I2C1, Read_Addr);

Timeout = I2C_Timeout ;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET)   /* Test on EV8 and clear it */
{
if((Timeout--) == 0) return 1;                          
}

/*!< Send START condition a second time */  
I2C_GenerateSTART(I2C1, ENABLE);


Timeout = I2C_Timeout ;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
{
if((Timeout--) == 0) return 1;                          
}

/*!< Send device address for read */
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Receiver);  

/* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
Timeout = I2C_Timeout ;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET)  //EV6
{
if((Timeout--) == 0) return 1;                           
}      
/*!< Disable Acknowledgment */
I2C_AcknowledgeConfig(I2C1, DISABLE);   
/* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
(void)I2C1->SR2;

/*!< Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Wait for the byte to be received */
Timeout = I2C_Timeout ;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
{
if((Timeout--) == 0) return 1;                        
}
/*!< Read the byte received from the device */
temp = I2C_ReceiveData(I2C1);
/* Wait to make sure that STOP flag has been cleared */
Timeout = I2C_Timeout ;
while(I2C1->CR1 & I2C_CR1_STOP)
{
if((Timeout--) == 0) return 1;                           
}  

/*!< Re-Enable Acknowledgment to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);   
/* Clear AF flag for next communication */
I2C_ClearFlag(I2C1, I2C_FLAG_AF);  
/* Return the byte read from device */                       
return temp;
}
请问下,就是在发送从地址时,到底address左不左移一位,我左移后从设备就没有应答了?如果不左移,从设备应答,但又卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));这句,数据寄存器的数据一直发不出。。。
 
lovelifett 回答时间:2014-1-13 17:04:08

回复:STM32F4 I2C 查询方式 自发自收问题

回复第 3 楼 于2014-01-12 15:07:50发表:
用示波器或逻辑分析仪看看波形
看了,就是在时钟第九位时没有应答,我把address不左移,后用库函数就有应答,但是卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));这句上,数据发不出去
 
lovelifett 回答时间:2014-1-13 17:06:07

回复:STM32F4 I2C 查询方式 自发自收问题

回复第 4 楼 于2014-01-12 19:12:26发表:
 是不是硬件不通?
感觉有点儿像,不过我用的是开发板,是微雪电子的M4,portZ系列
 
一灯一登 回答时间:2014-5-11 21:52:23

RE:STM32F4 I2C 查询方式 自发自收问题

我们不使用STM32的硬件IIC来读写24C02,而是通过软件模拟。STM32的硬件IIC非常复杂,更重要的是不稳定,故不推荐使用
_ilikerome_ 回答时间:2015-2-20 16:09:48
学习了。。。哈
taoshengyijiu-3 回答时间:2015-10-8 16:26:26
fengye5340 发表于 2014-1-12 12:36
ST的IIC为了规避专利,采用了独特的设计,楼主做硬件IIC时要严格遵守ST的设计思路才行,要不然容易出错。我 ...

在配置I2C的接口地址时,向I2C_OAR1寄存器写的地址是自己随便确定的吗?只要保证与I2C设备不重复即可?
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版