高级会员 
  
	- 积分
 - 743
 
        - 金钱
 - 743 
 
       - 注册时间
 - 2016-1-20
 
      - 在线时间
 - 189 小时
 
 
 
 | 
 
50金钱 
 本帖最后由 CCXX 于 2022-5-25 16:05 编辑  
 
使用STM32F401的I2C3做smbus slave,I2C3不接host的时候一切正常。当I2C host以100KHz每500ms发一包数据,slave接收中断后导致操作系统不能调度,debug发现是systick不能进中断了,我试过把I2C3的优先级调到最低也是这样。i2c3使用PA8和PB4,初始化和中断函数如下,麻烦大家帮忙分一下,谢谢。 
 
- void pcie_smbus_init(void)
 
 - {
 
 -     RCC->AHB1ENR |= 0xff;
 
 -     GPIOA->MODER &= ~(0x3 << (8 * 2));
 
 -     GPIOA->MODER |=  (0x2 << (8 * 2));
 
 -     GPIOA->OTYPER |=  1 << 8;
 
 -     GPIOA->PUPDR &= ~(0x3 << (8 * 2));
 
 -     GPIOA->PUPDR |=  (0x1 << (8 * 2));
 
 -     GPIOA->AFR[1] = 4;
 
  
-     GPIOB->MODER &= ~(0x3 << (4 * 2));
 
 -     GPIOB->MODER |=  (0x2 << (4 * 2));
 
 -     GPIOB->OTYPER |=  1 << 4;
 
 -     GPIOB->PUPDR &= ~(0x3 << (4 * 2));
 
 -     GPIOB->PUPDR |=  (0x1 << (4 * 2));
 
 -     GPIOB->AFR[0] = 9 << (4 * 4);
 
  
-     RCC->APB1ENR |= 1 << 23;
 
 -     I2C3->CR1 = 0;
 
 -     I2C3->CR2 |= 1 << 10;
 
 -     I2C3->CR2 |= 1 << 9;
 
 -     I2C3->CR2 |= 1 << 8;
 
 -     I2C3->CR2 |= 42;
 
  
-     I2C3->OAR1 = 0xa0;
 
 -     I2C3->OAR2 = 0x50 | 0x01;
 
 -     I2C3->SR1 = 0;
 
 -     I2C3->SR2 = 0;
 
 -     I2C3->CCR = 210;
 
 -     I2C3->TRISE = 0x2b;
 
  
-     I2C3->CR1 |= 1 << 1;
 
 -     I2C3->CR1 |= 1 << 0;
 
 -     I2C3->CR1 |= 1 << 10;
 
  
-     NVIC->IP[I2C3_EV_IRQn] = 0 << 4;
 
 -     NVIC->ISER[I2C3_EV_IRQn / 32] |= (1 << (I2C3_EV_IRQn % 32));
 
 -     NVIC->IP[I2C3_ER_IRQn] = 0 << 4;
 
 -     NVIC->ISER[I2C3_ER_IRQn / 32] |= (1 << (I2C3_ER_IRQn % 32));
 
 - }
 
  复制代码 
- unsigned char g_smbus_buffer[256] = {0};
 
 - unsigned int g_count = 0;
 
 - void I2C3_EV_IRQHandler(void)
 
 - {
 
 -     volatile unsigned short sr1 = 0;
 
 -     volatile unsigned short sr2 = 0;
 
  
-     sr1 = I2C3->SR1;
 
 -     sr2 = I2C3->SR2;
 
  
-     if((sr2 & 0x0005) == 0x0000)
 
 -     {
 
 -         if((sr1 & (1 << 0)) == (1 << 0))//start
 
 -         {
 
 -         }
 
 -         if((sr1 & (1 << 1)) == (1 << 1))//addr matched
 
 -         {
 
 -             g_count = 0;
 
 -             memset(g_smbus_buffer, 0, sizeof(g_smbus_buffer));
 
 -         }
 
 -         if((sr1 & (1 << 2)) == (1 << 2))//byte finished
 
 -         {
 
 -         }
 
 -         if((sr1 & (1 << 4)) == (1 << 4))//stop
 
 -         {
 
 -         }
 
 -         if((sr1 & (1 << 6)) == (1 << 6))//recv data
 
 -         {
 
 -             g_smbus_buffer[g_count++] = I2C3->DR;
 
 -         }
 
 -     }
 
 - }
 
  
- void I2C3_ER_IRQHandler(void)
 
 - {
 
 -     volatile unsigned short sr1 = 0;
 
 -     sr1 = I2C3->SR1;
 
  
-     if((sr1 & (1 << 11)) == (1 << 11))//OVR
 
 -     {
 
 -         I2C3->CR1 &= ~(1 << 11);
 
 -     }
 
 -     if((sr1 & (1 << 10)) == (1 << 10))//AF
 
 -     {
 
 -         I2C3->CR1 &= ~(1 << 10);
 
 -     }
 
 -     if((sr1 & (1 << 9)) == (1 << 9))//ARLO
 
 -     {
 
 -         I2C3->CR1 &= ~(1 << 9);
 
 -     }
 
 -     if((sr1 & (1 << 8)) == (1 << 8))//BERR
 
 -     {
 
 -         I2C3->CR1 &= ~(1 << 8);
 
 -     }
 
 - }
 
  复制代码 
 
 
 |   
 
 
 
 
 
 |