beyondsupersoni 发表于 2013-8-6 15:17:33

STM8S103F3P6 I2C Slave问题

 最近调STM8,用I2C在从机模式下与主机通讯,采用中断模式。但是复位之后老是运行几次就死掉,貌似程序在中断里出不来,然后I2C就挂了。Debug查看寄存器,发现状态寄存器的值跟库里面定义的任何一个EVENT都不符合,搞了两天了,不知道什么问题,头疼。。。

四个方向键、 发表于 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++;
       
      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_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

:lol
新东西出现
/**********************************************************/
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;
                        MessageBegin = FALSE;
                }
    else if(u8_MyBuffp < &u8_My_Buffer)
      *(u8_MyBuffp++) = u8_RxData;
        }
        u8 I2C_byte_write(void)
        {
                if (u8_MyBuffp < &u8_My_Buffer)
                        return *(u8_MyBuffp++);
                else
                        return 0x00;
        }
页: [1]
查看完整版本: STM8S103F3P6 I2C Slave问题