xiaoqi976633690 发表于 2024-5-8 15:45:49

让AI来优化下I2C从机的过多的if else,改用switch

//帮忙用switch优化下面代码在优化中断服务程序(ISR)代码时,我们通常希望尽量减少在ISR中的执行时间,因为中断可能会阻塞其他中断的执行。使用`switch`语句可以提高代码的可读性,并且可能有助于减少一些不必要的条件判断。下面是使用`switch`语句优化后的代码示例:

```c
void I2C_Isr() interrupt 24
{
    _push_(P_SW2);
    P_SW2 |= 0x80;

    switch (I2CSLST & 0xF0) // 只检查高四位,因为事件标志位都在高四位
    {
      case 0x40: // START事件
            I2CSLST &= ~0x40;
            break;
      case 0x20: // RECV事件
            I2CSLST &= ~0x20;
            if (isda)
            {
                isda = 0;
            }
            else if (isma)
            {
                isma = 0;
                addr = I2CRXD;
                I2CTXD = buffer;
            }
            else
            {
                buffer = I2CRXD;
            }
            break;
      case 0x10: // SEND事件
            I2CSLST &= ~0x10;
            if (I2CSLST & 0x02)
            {
                I2CTXD = 0xff;
            }
            else
            {
                I2CTXD = buffer[++addr];
            }
            break;
      case 0x08: // STOP事件
            I2CSLST &= ~0x08;
            isda = 1;
            isma = 1;
            break;
      default:
            // 可以在这里添加错误处理或者什么都不做
            break;
    }

    _pop_(P_SW2);
}
```

在这个优化版本中,我使用了`switch`语句来替代多个`if-else`语句。通过将`I2CSLST`的高四位与不同的值进行比较,可以快速地跳转到相应的代码块。这样,每个`case`块都只处理一种特定的事件,减少了代码的复杂性。

请注意,这个优化假设`I2CSLST`的事件标志位都位于高四位(即0xF0掩码)。如果这个假设不成立,你可能需要调整掩码值以匹配实际的硬件规范。

此外,我保留了原始代码中的`_push_`和`_pop_`宏,这些通常用于保存和恢复中断状态。如果你的编译器或硬件平台不使用这些宏,你可能需要替换为适当的方法来管理中断。switch (I2CSLST & 0xF0) 这个应该是switch (I2CSLST & 0xF8)吧您是对的,我之前的代码示例中使用的掩码`0xF0`只考虑了`0x40`和`0x20`这两种情况,遗漏了`0x10`和`0x08`这两种情况。正确的掩码应该是`0xF8`,这样能够覆盖所有四种事件标志位。以下是修正后的代码:

```c
void I2C_Isr() interrupt 24
{
    _push_(P_SW2);
    P_SW2 |= 0x80;

    switch (I2CSLST & 0xF8) // 使用0xF8掩码以检查START, RECV, SEND, STOP事件
    {
      case 0x40: // START事件
            I2CSLST &= ~0x40;
            break;
      case 0x20: // RECV事件
            I2CSLST &= ~0x20;
            if (isda)
            {
                isda = 0;
            }
            else if (isma)
            {
                isma = 0;
                addr = I2CRXD;
            }
            else
            {
                buffer = I2CRXD;
            }
            break;
      case 0x10: // SEND事件
            I2CSLST &= ~0x10;
            if (I2CSLST & 0x02)
            {
                I2CTXD = 0xff; // 如果接收到NAK,发送0xff
            }
            else
            {
                if (addr < sizeof(buffer)) // 确保没有超出buffer大小
                {
                  I2CTXD = buffer;
                }
            }
            break;
      case 0x08: // STOP事件
            I2CSLST &= ~0x08;
            isda = 1;
            isma = 1;
            break;
      default:
            // 可以在这里添加错误处理或者什么都不做
            break;
    }

    _pop_(P_SW2);
}
```

在这个修正后的版本中,我使用了`0xF8`作为掩码,这样可以确保所有相关的事件标志位都被检查到。同时,我添加了一个检查以确保在发送数据时不会超出`buffer`的大小。这样可以避免潜在的数组越界错误。

感谢您的指正,这有助于提供更准确的代码示例。

xiaoqi976633690 发表于 2024-5-8 16:01:23





嵌入式之路 发表于 2024-5-8 16:28:47

保证可读性的话就是正向优化
页: [1]
查看完整版本: 让AI来优化下I2C从机的过多的if else,改用switch