【问题标题】:Why do these arrangements of embedded c code perform so differently?为什么嵌入式 c 代码的这些安排执行如此不同?
【发布时间】:2012-05-12 08:16:45
【问题描述】:

背景

我正在使用基于 8052 的微控制器。我连接了 LCD 和编码器轮。用户可以通过旋转并按下编码轮来导航 LCD 上显示的菜单。

编码轮的旋转是基于中断的。

编码器轮的旋转方向 (encoder_turn) 在编码器中断内设置。

我在循环中调用update_lcd()

新的响应代码

void update_lcd()                           
{

        //ENCODER TURN      
        switch(encoder_turn)
        {
            case RIGHT:
                 lcd_clear();
                 next_screen();
                 break;
            case LEFT:
                lcd_clear();
                previous_screen();
                break;
            default:
                break;
        }
 }

void next_screen()
{
    if(current_test_screen < screen5)
    {
        current_test_screen++;
    }

    draw_current_test_screen(); 
}

void draw_current_test_screen()
{
    switch(current_test_screen)
    {
        case screen1:
            draw_screen1();
            break;
        case screen2:
            draw_screen2();
            break;
        case screen3:
            draw_screen3();
            break;
        case screen4:
            draw_screen4();
            break;
        case screen5:
            draw_screen5();
            break;      
        default:
        break;
    }
}

旧的无响应代码

void update_lcd()                           
{

        //ENCODER TURN      
        switch(encoder_turn)
        {
            case RIGHT:
                 lcd_clear();
                 next_screen();
                 break;
            case LEFT:
                lcd_clear();
                previous_screen();
                break;
            default:
                break;
        }

        switch(current_test_screen)
        {
            case screen1:
                draw_screen1();
                break;
            case screen2:
                draw_screen2();
                break;
            case screen3:
                draw_screen3();
                break;
            case screen4:
                draw_screen4();
                break;
            case screen5:
               draw_screen5();
               break;       
            default:
               break;
       }


 }

void next_screen()
{
    if(current_test_screen < screen5)
    {
        current_test_screen++;
    }
}

问题

为什么一个反应灵敏而另一个完全没用?

当我说响应式时,我指的是当我旋转编码器时屏幕变化是响应式的。这两种方法都“有效”,但从使用的角度来看,一种方法是不可接受的。

【问题讨论】:

  • 请显示encoder_turn 的定义。另外,这是从哪里调用的?
  • @EdS。只需将主循环视为 while(true){update_lcd();} 因为基本上就是这样
  • @DarkFalcon encoder_turn 是在单独文件中定义的 volatile int。它在此处使用的地方被声明为和 extern int
  • @appleskin:好的,但它可能相关也可能不相关。既然你不知道是什么导致了问题,你怎么可能假设它不在你的主循环中(更具体地说,函数是如何从主循环中调用的)?也许您认为不相关的细节之一实际上是相关的。

标签: c embedded interrupt


【解决方案1】:

这两段代码几乎是等价的,除了一个非常细微的差别。

如果您尝试重构旧代码以使其看起来更像您的新代码,您会发现旧代码进行了一次额外的函数调用。仔细看区别:

void update_lcd()                           
{
        //ENCODER TURN      
        switch(encoder_turn)
        {
            case RIGHT:
                 lcd_clear();
                 next_screen();
                 break;
            case LEFT:
                lcd_clear();
                previous_screen();
                break;
            default:
                draw_current_test_screen();   // <--- your new code omits this call
                break;
        }
 }

尝试使用您的新代码并添加该行,看看它是否会导致无响应问题。

【讨论】:

  • 哇...没错。我认为这将是比这更重要的事情。
  • 当编码器不转动时,它会输出该函数调用
【解决方案2】:

只是猜测,但我怀疑:由于您唯一更改的是函数嵌套,encoder_turn 可能正在被优化器缓存。您需要将encoder_turn 标记为易失性,因为中断可以随时发生并更改其值。

【讨论】:

    猜你喜欢
    • 2013-02-23
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多