为什么这些嵌入式c代码的安排如此不同?

时间:2012-05-02 20:03:30

标签: c embedded interrupt

背景

我正在使用基于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++;
    }
}

问题

为什么一个响应而另一个完全没用?

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

2 个答案:

答案 0 :(得分:9)

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

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

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;
        }
 }

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

答案 1 :(得分:0)

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