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

[复制链接]
10018|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通讯吗?
主机通讯代码:
  1. 因为注释在这里显示乱了,所以以下代码都没有备注
  2. //主机发送字节
  3. void I2C_WriteBytes(unsigned char SlaveAddress)
  4. {        
  5.    I2C_GenerateSTART(I2C2,ENABLE);
  6.    while(!((uint16_t)(I2C2->SR1)&(uint16_t)(0x0001)));//SB=1
  7.    while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);//BUSY=1+MSL=1
  8.    I2C_Send7bitAddres(I2C2,SlaveAddress,I2C_Direction_Transmitter);         
  9.   while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//ADDR=1
  10.   while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0007))!=0x0007);
  11.   while(g_I2Tx_Counter!=BUFFER_SIZE)
  12.        {
  13.           I2C_SendData(I2C2, g_I2TxBuffer[g_I2Tx_Counter++]);
  14.           while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0080))!=0x0080);//TXE
  15.           while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0007))!=0x0007);//MSL+BUSY+TRA
  16.        }
  17.   g_I2Tx_Counter=0;
  18. I2C_GenerateSTOP(I2C2, ENABLE);
  19. }
  20. //主机接收字节
  21. void I2C_ReadBytes(unsigned char  SlaveAddress)
  22. {  
  23.   I2C_GenerateSTART(I2C2, ENABLE);
  24.   while(!((uint16_t)(I2C2->SR1)&(uint16_t)(0x0001)));//SB=1
  25.   while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);//BUSY=1               
  26.   I2C_Send7bitAddress(I2C2, SlaveAddress, I2C_Direction_Receiver);        
  27. //操作从机2时卡在这里,发送从机2地址之后程序就停在了这里        
  28.   while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//确认地址是否发送完成
  29.   while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);
  30.   while(g_I2Rx_Counter!=BUFFER_SIZE)
  31.   {
  32.    if(g_I2Rx_Counter==(BUFFER_SIZE-1))
  33.    {
  34.       if(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE)==1)
  35.      {
  36.          I2C_AcknowledgeConfig(I2C2, DISABLE);
  37.          I2C_GenerateSTOP(I2C2, ENABLE);
  38.      }
  39.   }
  40. while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0040))!=0x0040);
  41. while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0003))!=0x0003);
  42. g_I2RxBuffer[g_I2Rx_Counter++] = I2C_ReceiveData(I2C2);        
  43. }
  44. I2C_GenerateSTOP(I2C2, ENABLE);
  45. I2C_AcknowledgeConfig(I2C2, ENABLE);
  46. g_I2Rx_Counter=0;
  47. }
  48. //主函数
  49. int main(void)
  50. {  
  51.     unsigned char i;
  52.     RCC_Configuration();
  53. //    LED_Configuration();
  54.     NVIC_Configuration();
  55.     I2C_Configuration();
  56.    USART_Configuration();
  57. //    LEDG_ALL_ON;
  58. //    while(g_USART1Received!=0xD1);
  59. //从机1地址0x54,操作从机1
  60.   I2C_WriteBytes(0x54);
  61.   Sleep(100);
  62.   I2C_ReadBytes(0x54);
  63. for(i=0;i<BUFFER_SIZE;i++)
  64. {
  65.    g_I2RxBuffer[i]=0;
  66. }
  67.     Sleep(100);
  68. //操作从机2,从机2地址0x53
  69. I2C_WriteBytes(0x53);               
  70. Sleep(100);
  71. I2C_ReadBytes(0x53);               
  72. for(i=0;i<BUFFER_SIZE;i++)//清除接收缓存器
  73. {
  74.   g_I2RxBuffer[i]=0;
  75. }
  76.     while(1)
  77.    {
  78.     }
  79. }               
  80. 从机代码:[code]从机1和从机2代码一样只是初始化是定义的从机地址不一样
  81. void I2C_Configuration(void)
  82. {
  83.         I2C_InitTypeDef I2C_InitStructure;
  84.         GPIO_InitTypeDef GPIO_InitStructure;

  85.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
  86.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

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

  92.         I2C_DeInit(I2C2);
  93.         I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ;
  94.         I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  95.         I2C_InitStructure.I2C_OwnAddress1 = 0x53;  
  96.         I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  97.         I2C_InitStructure.I2C_AcknowledgedAddress =I2C_AcknowledgedAddress_7bit;
  98.         I2C_InitStructure.I2C_ClockSpeed = 40000;
  99.         I2C_Init(I2C2, &I2C_InitStructure);

  100.         I2C_ITConfig(I2C2,I2C_IT_ERR,ENABLE);
  101.         I2C_Cmd(I2C2,ENABLE);
  102.         I2C_AcknowledgeConfig(I2C2,ENABLE);
  103. }
  104. //主机发送从机接收
  105. void SlaveRxBytes()
  106. {
  107.     while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);
  108.     while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0002))!=0x0002);
  109.      while(g_I2Rx_Counter!=BUFFER_SIZE)
  110.       {     
  111.         while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0040))!=0x0040);//RxNE=1
  112.         g_I2RxBuffer[g_I2Rx_Counter++]=I2C_ReceiveData(I2C2);
  113.       }
  114.   while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0010))!=0x0010);
  115.   g_I2Rx_Counter=0;
  116. }
  117. //主机接收从机发送
  118. void SlaveTxBytes()
  119. {
  120.     while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0002))!=0x0002);//ADDR=1 receive address matched
  121.     while(((uint16_t)(I2C2->SR2)&(uint16_t)(0x0006))!=0x0006);//BUSY=1+MSL=0+TRA=1
  122.     I2C_SendData(I2C2,g_I2TxBuffer[g_I2Tx_Counter++]);
  123.     while(g_I2Tx_Counter!=BUFFER_SIZE)
  124.      {
  125.         while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0080))!=0x0080);
  126.         I2C_SendData(I2C2,g_I2TxBuffer[g_I2Tx_Counter++]);
  127.       }
  128.         while(((uint16_t)(I2C2->SR1)&(uint16_t)(0x0010))!=0x0010);
  129.         g_I2Tx_Counter=0;
  130. }
//从机主函数
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 | 显示全部楼层
个人调试经验,在调试一个新的外设时必须仔细阅读外设的操作手册,并且一定要懂,严格按照操作手册的说明来,最重要的是按时序来
Atom2004 发表于 2013-9-28 09:00 | 显示全部楼层
非常强大。支持一个。
mmbs 发表于 2013-9-29 21:00 | 显示全部楼层
楼主很牛x,自己解决了。
mmbs 发表于 2013-9-29 21:00 | 显示全部楼层
上个代码来学习学习的。
gaochy1126 发表于 2013-9-29 21:47 | 显示全部楼层
应该是地址操作没有对吧?
yjbemail 发表于 2014-3-12 14:39 | 显示全部楼层
我也用这个功能,需要1个CPU访问8个24LC02,我将24LC02的A0,A1,A2设置成不同的8个地址。求帮助,急。我的信箱是yjbemail@163.com 谢谢
jack123465 发表于 2014-5-26 21:56 | 显示全部楼层
楼主,你是怎么解决的??求解决方法1111,
793162484 发表于 2014-9-28 14:36 | 显示全部楼层
楼主厉害啊
w165661916 发表于 2015-4-20 14:13 | 显示全部楼层
还在吗?求告之此段代码~从机部分的~
coulson 发表于 2017-12-18 22:31 | 显示全部楼层
你好,我在论坛上看到你关于iic多级通讯的问题,现在我也遇到了一些问题,能不能请教你一下 我的QQ 1151144104
1274668851 发表于 2018-6-27 21:54 | 显示全部楼层
主机通过iic与16个ad5933器件通信,楼主,求助,

我已经加你好友
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

25

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部