STM32_I2C硬件中断方式读写疑问

2019-07-20 23:55发布

本帖最后由 小笨蛋 于 2016-1-26 21:24 编辑

注意:请不要说推荐模拟I2C相关的话题,各有优略,我只是想啃啃骨头


volatile int i = 0;   while(!pSR1->RxNE)
   {
    i++;
   }


疑问:红 {MOD}部分代码,为什么进入中断,事件表明接收完成,DR却不能立即读取?是我手册看得不到位还是这就是这么回事儿?

事件I2C_EVENT_MASTER_BYTE_RECEIVED下:pSR1->RxNE(RxNE标志位)竟然为0?经过测试i大概+到35的时候,数据才进入DR,否则读出来的数据是不正确的;(找这个BUG花了不少时间-  -)

欢迎指出这种方式的问题,弊端,不胜感激!!

1.初始化不说了,中断优先级暂时写的最高,如果不是最高优先级应该也不会有问题,可以断在中断函数里调试
2.中间定义了两个数组,为了测试中断事件的顺序是不是我预期的那样,结果的确是的;
3.触发写或者读取只需要将WCR或者RCR的标志置位,执行I2C_GenerateSTART(I2C1, ENABLE);


[mw_shl_code=c,true]
// WCR,RCR的定义
typedef enum
{
WCR_NULL,
WCR_TRANS_MODE_REQ,
WCR_SUB_ADR_REQ,
WCR_DATA_REQ,
WCR_STOP_REQ
}WRITE_CTRL_TYPE;
typedef enum
{
RCR_NULL,
RCR_TRANS_MODE_REQ,
RCR_SUB_ADR_REQ,
RCR_START_REQ,
RCR_RECV_MODE_REQ,
RCR_STOP_REQ,
RCR_READ_DATA_REQ
}READ_CTRL_TYPE;

// 中断函数
void I2C1_EV_IRQHandler(void)
{
volatile pI2C_SR1_Type pSR1 = (pI2C_SR1_Type)&(I2C1->SR1);/* 自己定义的结构体,为了方便看标志位 */

    switch (I2C_GetLastEvent(I2C1))    // 获取事件
    {
case I2C_EVENT_MASTER_MODE_SELECT: // 发送了起始位,接下来应该发送slaver地址,并约定读写
  if ( WCR == WCR_TRANS_MODE_REQ ) // W1---写进入的第一个中断,Wx下同
  {
   test0[i0++] = 1;// 通过数组test0 中的数据可以看出来中断事件的顺序
   I2C_Send7bitAddress(I2C1, SLAVER_ADR, I2C_Direction_Transmitter);// 发送地址
   WCR++;// 标志+1,进入下一个环节
  }
  if ( RCR ==  RCR_TRANS_MODE_REQ ) // R1
  {
   test1[i1++] = 1;
   I2C_Send7bitAddress(I2C1, SLAVER_ADR, I2C_Direction_Transmitter);
   RCR++;
  }
  else if ( RCR == RCR_RECV_MODE_REQ ) // R4
  {
   test1[i1++] = 4;
   I2C_Send7bitAddress(I2C1, SLAVER_ADR, I2C_Direction_Receiver);
   RCR++;
  }
  break;
/* Master Transmitter --------------------------------------------------- */
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
  if ( WCR == WCR_SUB_ADR_REQ ) // W2
  {
   test0[i0++] = 2;
   I2C_SendData(I2C1, WriteAdr);
   WCR++;
  }
  if ( RCR == RCR_SUB_ADR_REQ ) // R2
  {
   test1[i1++] = 2;
   I2C_SendData(I2C1, ReadAdr);
   RCR++;
  }
  break;
/* Master Transmitter sent done ----------------------------------------- */
case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
  if ( WCR == WCR_DATA_REQ ) // W3
  {
   test0[i0++] = 3;
   I2C_SendData(I2C1, WriteData);
   WCR++;
  }
  else if ( WCR == WCR_STOP_REQ ) // W4
  {
   test0[i0++] = 4;
   I2C_GenerateSTOP(I2C1, ENABLE);
   WCR = WCR_NULL;
  }
  
  if ( RCR == RCR_START_REQ ) // R3
  {
   test1[i1++] = 3;
   I2C_GenerateSTART(I2C1, ENABLE);
   RCR++;
  }
  break;
/* Master Receiver ------------------------------------------------------ */
case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
  if ( RCR == RCR_STOP_REQ ) // R5
  {
   test1[i1++] = 5;
   I2C_AcknowledgeConfig(I2C1, DISABLE);
      // I2C_GenerateSTOP(I2C1, ENABLE);
   // pSR1->RxNE = 0;
   RCR++;
  }
case I2C_EVENT_MASTER_BYTE_RECEIVED:
  if ( RCR == RCR_READ_DATA_REQ ) // R6
  {
   test1[i1++] = 6;
   volatile int i = 0;
   while(!pSR1->RxNE)
   {
    i++;
   }
   ReadData =  I2C_ReceiveData(I2C1);   
     // I2C_AcknowledgeConfig(I2C1, ENABLE);
   I2C_GenerateSTOP(I2C1, ENABLE);
   RCR = RCR_NULL;
  }
    default:
        break;
    }
}[/mw_shl_code]

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。