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

STM8S103F3P6 I2C Slave问题

[复制链接]
beyondsupersoni 提问时间:2013-8-6 15:17 /
 最近调STM8,用I2C在从机模式下与主机通讯,采用中断模式。但是复位之后老是运行几次就死掉,貌似程序在中断里出不来,然后I2C就挂了。Debug查看寄存器,发现状态寄存器的值跟库里面定义的任何一个EVENT都不符合,搞了两天了,不知道什么问题,头疼。。。
收藏 评论6 发布时间:2013-8-6 15:17

举报

6个回答
四个方向键、 回答时间:2013-8-30 11:00:19

RE:STM8S103F3P6 I2C Slave问题

晕倒 我也是这样官方例子有问题 我是IO模拟解决的
kevin8857 回答时间:2016-5-8 01:14:00
我也是适用官方的代码;发现是没有应答发出的。。。。。导致主机结束通信;还真不知道怎么解决哦
kevin8857 回答时间:2016-5-8 01:21:26
******************************************************************************/
void I2C_SlaveInit(void)
{
    I2C_DeInit();
       
        /*
         * 将I2C配置为:
         * 波特率 = 100K
         * 从地址0x40
       
         * 使能接收和发送
         * 使能接收中断
         */
   
    I2C_Init(100000, I2C_SLAVE_ADDRES, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, 16);
    I2C_ITConfig((I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
    I2C_Cmd(ENABLE);
}


INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
  */
   /* Read SR2 register to get I2C error */
  if ((I2C->SR2) != 0)
  {
    /* Clears SR2 register */
   // i2c.Event=I2C->SR2;

    I2C->SR2 = 0;

    /* Set LED2 */
   // STM_EVAL_LEDOn(LED2);
   

  }
  
  i2c.Event = I2C_GetLastEvent();

  switch (i2c.Event)
  {
      /******* Slave transmitter ******/
      /* check on EV1 */
    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
   
      I2C_SendData(i2c.Slave_Buffer_Tx[i2c.Tx_Idx]);
      i2c.Tx_Idx++;
         
      break;

      /* check on EV3 */
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
               
      break;
      /******* Slave receiver **********/
      /* check on EV1*/
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
       
         i2c.Rx_Add_MATCHED=1;
     
      break;

      /* Check on EV2*/
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:
          if(i2c.Rx_Add_MATCHED==1)
                  {
                      i2c.Rx_Add_MATCHED=0;
                      i2c.Tx_Idx=I2C_ReceiveData();  //确定修改或者读寄存器地址
                  }
          else
                  {
                        i2c.Slave_Buffer_Tx[i2c.Tx_Idx] = I2C_ReceiveData();
                  i2c.Tx_Idx++;
                  }
     
         
      break;

      /* Check on EV4 */
    case (I2C_EVENT_SLAVE_STOP_DETECTED):
               
            /* write to CR2 to clear STOPF flag */
            I2C->CR2 |= I2C_CR2_ACK;
          
      break;
       

    default:
   
         
          
      break;
  }
}


/**********************************************************/
发现进入中断卡死;从示波器看到    主机给103从机发送数据后没有ACK应答返回导致通信停止。。。。。。。。。
zcl201207 回答时间:2016-5-8 13:07:22
kevin8857 回答时间:2016-5-8 16:13:24

新东西出现
/**********************************************************/
INTERRUPT_HANDLER(I2C_IRQHandler, 19)
{
        static u8 sr1;                                       
        static u8 sr2;
        static u8 sr3;
       
// save the I2C registers configuration
sr1 = I2C->SR1;
sr2 = I2C->SR2;
sr3 = I2C->SR3;

/* Communication error? */
  if (sr2 & (I2C_SR2_WUFH | I2C_SR2_OVR |I2C_SR2_ARLO |I2C_SR2_BERR))
  {               
    I2C->CR2|= I2C_CR2_STOP;  // stop communication - release the lines
    I2C->SR2= 0;                                            // clear all error flags
        }
/* More bytes received ? */
  if ((sr1 & (I2C_SR1_RXNE | I2C_SR1_BTF)) == (I2C_SR1_RXNE | I2C_SR1_BTF))
  {
    I2C_byte_received(I2C->DR);
  }
/* Byte received ? */
  if (sr1 & I2C_SR1_RXNE)
  {
    I2C_byte_received(I2C->DR);
  }
/* NAK? (=end of slave transmit comm) */
  if (sr2 & I2C_SR2_AF)
  {       
    I2C->SR2 &= ~I2C_SR2_AF;          // clear AF
                I2C_transaction_end();
        }
/* Stop bit from Master  (= end of slave receive comm) */
  if (sr1 & I2C_SR1_STOPF)
  {
    I2C->CR2 |= I2C_CR2_ACK;          // CR2 write to clear STOPF
                I2C_transaction_end();
        }
/* Slave address matched (= Start Comm) */
  if (sr1 & I2C_SR1_ADDR)
  {         
                I2C_transaction_begin();
        }
/* More bytes to transmit ? */
  if ((sr1 & (I2C_SR1_TXE | I2C_SR1_BTF)) == (I2C_SR1_TXE | I2C_SR1_BTF))
  {
                I2C->DR = I2C_byte_write();
  }
/* Byte to transmit ? */
  if (sr1 & I2C_SR1_TXE)
  {
                I2C->DR = I2C_byte_write();
  }       
        //GPIOD->ODR^=1;
}
/*********************************/
在初始化不变情况从官网再找到这代码测试可以返回应答;
kevin8857 回答时间:2016-5-8 16:14:43
void I2C_transaction_begin(void)
        {
                MessageBegin = TRUE;
        }
        void I2C_transaction_end(void)
        {
                //Not used in this example
        }
        void I2C_byte_received(u8 u8_RxData)
        {
                if (MessageBegin == TRUE  &&  u8_RxData < MAX_BUFFER) {
                        u8_MyBuffp= &u8_My_Buffer[u8_RxData];
                        MessageBegin = FALSE;
                }
    else if(u8_MyBuffp < &u8_My_Buffer[MAX_BUFFER])
      *(u8_MyBuffp++) = u8_RxData;
        }
        u8 I2C_byte_write(void)
        {
                if (u8_MyBuffp < &u8_My_Buffer[MAX_BUFFER])
                        return *(u8_MyBuffp++);
                else
                        return 0x00;
        }
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版