打印

求助STM32 I2C主机与一个从机通讯成功 与多个从机通讯失败

[复制链接]
9084|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
stevendaoyun|  楼主 | 2013-9-12 21:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 stevendaoyun 于 2013-9-12 21:15 编辑

系统中,一片STM32做主机,两片STM32作为从机,主机和一个从机通讯成功,能够发送数据给从机也能读取从机数据,与两个从机通讯时,与从机1通讯结束后,接着与从机2通讯,但程序卡在从机2地址发送处,屏蔽从机1通讯程序后从机2又能够正常通讯。我试了在和从机2通讯之前重置I2C和清除主机接收缓存器,但是依然没能成功,是不是在主机在和从机通讯时,与从机1通讯结束后,需要对I2C进行处理才能发送从机2地址与从机2通讯吗?
主机通讯代码:
因为注释在这里显示乱了,所以以下代码都没有备注
//主机发送字节
void I2C_WriteBytes(unsigned char SlaveAddress)
{        
   I2C_GenerateSTART(I2C2,ENABLE);
   while(!((uint16_t)(I2C2->SR1)&(uint16_t)(0x0001)));//SB=1
   while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);//BUSY=1+MSL=1
   I2C_Send7bitAddres(I2C2,SlaveAddress,I2C_Direction_Transmitter);         
  while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//ADDR=1
  while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0007))!=0x0007);
  while(g_I2Tx_Counter!=BUFFER_SIZE)
       {
          I2C_SendData(I2C2, g_I2TxBuffer[g_I2Tx_Counter++]);
          while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0080))!=0x0080);//TXE
          while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0007))!=0x0007);//MSL+BUSY+TRA
       }
  g_I2Tx_Counter=0;
I2C_GenerateSTOP(I2C2, ENABLE);
}
//主机接收字节
void I2C_ReadBytes(unsigned char  SlaveAddress)
{  
  I2C_GenerateSTART(I2C2, ENABLE);
  while(!((uint16_t)(I2C2->SR1)&(uint16_t)(0x0001)));//SB=1
  while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);//BUSY=1               
  I2C_Send7bitAddress(I2C2, SlaveAddress, I2C_Direction_Receiver);        
//操作从机2时卡在这里,发送从机2地址之后程序就停在了这里        
  while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//确认地址是否发送完成
  while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);
  while(g_I2Rx_Counter!=BUFFER_SIZE)
  {
   if(g_I2Rx_Counter==(BUFFER_SIZE-1))
   {
      if(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE)==1)
     {
         I2C_AcknowledgeConfig(I2C2, DISABLE);
         I2C_GenerateSTOP(I2C2, ENABLE);
     }
  }
while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0040))!=0x0040);
while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);
g_I2RxBuffer[g_I2Rx_Counter++] = I2C_ReceiveData(I2C2);        
}
I2C_GenerateSTOP(I2C2, ENABLE);
I2C_AcknowledgeConfig(I2C2, ENABLE);
g_I2Rx_Counter=0;
}
//主函数
int main(void)
{  
    unsigned char i;
    RCC_Configuration();
//    LED_Configuration();
    NVIC_Configuration();
    I2C_Configuration();
   USART_Configuration();
//    LEDG_ALL_ON;
//    while(g_USART1Received!=0xD1);
//从机1地址0x54,操作从机1
  I2C_WriteBytes(0x54);
  Sleep(100);
  I2C_ReadBytes(0x54);
for(i=0;i<BUFFER_SIZE;i++)
{
   g_I2RxBuffer[i]=0;
}
    Sleep(100);
//操作从机2,从机2地址0x53
I2C_WriteBytes(0x53);               
Sleep(100);
I2C_ReadBytes(0x53);               
for(i=0;i<BUFFER_SIZE;i++)//清除接收缓存器
{
  g_I2RxBuffer[i]=0;
}
    while(1)
   {
    }
}               
从机代码:[code]从机1和从机2代码一样只是初始化是定义的从机地址不一样
void I2C_Configuration(void)
{
        I2C_InitTypeDef I2C_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

        /*PB10=SCL,PB11=SDA*/
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;                  
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD;     
        GPIO_Init(GPIOB,&GPIO_InitStructure);

        I2C_DeInit(I2C2);
        I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ;
        I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStructure.I2C_OwnAddress1 = 0x53;  
        I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStructure.I2C_AcknowledgedAddress =I2C_AcknowledgedAddress_7bit;
        I2C_InitStructure.I2C_ClockSpeed = 40000;
        I2C_Init(I2C2, &I2C_InitStructure);

        I2C_ITConfig(I2C2,I2C_IT_ERR,ENABLE);
        I2C_Cmd(I2C2,ENABLE);
        I2C_AcknowledgeConfig(I2C2,ENABLE);
}
//主机发送从机接收
void SlaveRxBytes()
{
    while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);
    while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0002))!=0x0002);
     while(g_I2Rx_Counter!=BUFFER_SIZE)
      {     
        while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0040))!=0x0040);//RxNE=1
        g_I2RxBuffer[g_I2Rx_Counter++]=I2C_ReceiveData(I2C2);
      }
  while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0010))!=0x0010);
  g_I2Rx_Counter=0;
}
//主机接收从机发送
void SlaveTxBytes()
{
    while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//ADDR=1 receive address matched
    while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0006))!=0x0006);//BUSY=1+MSL=0+TRA=1
    I2C_SendData(I2C2,g_I2TxBuffer[g_I2Tx_Counter++]);
    while(g_I2Tx_Counter!=BUFFER_SIZE)
     {
        while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0080))!=0x0080);
        I2C_SendData(I2C2,g_I2TxBuffer[g_I2Tx_Counter++]);
      }
        while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0010))!=0x0010);
        g_I2Tx_Counter=0;
}
//从机主函数
int main(void)
{
RCC_Configuration();
I2C_Configuration();
NVIC_Configuration();
SlaveRxBytes();
SlaveTxBytes();
}
沙发
stevendaoyun|  楼主 | 2013-9-12 21:24 | 只看该作者
自己先顶一个,仍在研究中

使用特权

评论回复
板凳
stevendaoyun|  楼主 | 2013-9-14 12:52 | 只看该作者
通过再次阅读I2C手册,问题已经解决了,问题出在主接收关闭通信这里,现在实现注浆机与多从机的通信,能正常收发了

使用特权

评论回复
地板
stevendaoyun|  楼主 | 2013-9-14 12:55 | 只看该作者
个人调试经验,在调试一个新的外设时必须仔细阅读外设的操作手册,并且一定要懂,严格按照操作手册的说明来,最重要的是按时序来

使用特权

评论回复
5
Atom2004| | 2013-9-28 09:00 | 只看该作者
非常强大。支持一个。

使用特权

评论回复
6
mmbs| | 2013-9-29 21:00 | 只看该作者
楼主很牛x,自己解决了。

使用特权

评论回复
7
mmbs| | 2013-9-29 21:00 | 只看该作者
上个代码来学习学习的。

使用特权

评论回复
8
gaochy1126| | 2013-9-29 21:47 | 只看该作者
应该是地址操作没有对吧?

使用特权

评论回复
9
yjbemail| | 2014-3-12 14:39 | 只看该作者
我也用这个功能,需要1个CPU访问8个24LC02,我将24LC02的A0,A1,A2设置成不同的8个地址。求帮助,急。我的信箱是yjbemail@163.com 谢谢

使用特权

评论回复
10
jack123465| | 2014-5-26 21:56 | 只看该作者
楼主,你是怎么解决的??求解决方法1111,

使用特权

评论回复
11
793162484| | 2014-9-28 14:36 | 只看该作者
楼主厉害啊

使用特权

评论回复
12
w165661916| | 2015-4-20 14:13 | 只看该作者
还在吗?求告之此段代码~从机部分的~

使用特权

评论回复
13
coulson| | 2017-12-18 22:31 | 只看该作者
你好,我在论坛上看到你关于iic多级通讯的问题,现在我也遇到了一些问题,能不能请教你一下 我的QQ 1151144104

使用特权

评论回复
14
1274668851| | 2018-6-27 21:54 | 只看该作者
主机通过iic与16个ad5933器件通信,楼主,求助,

我已经加你好友

使用特权

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

本版积分规则

3

主题

25

帖子

1

粉丝