簡體   English   中英

STM32中的中斷排序

[英]Ordering the interrupts in STM32

我想用我的 4x4 鍵盤和 SSD(7 段顯示器)在 STM32 上做一個計算器。 我將使用 A 作為鍵盤上的加法,假設我將計算:9 + 8 = 17。我使用中斷從鍵盤獲取數字,所以我用於這些數字的中斷是:

//INTERRUPT FOR NUMBER 9

void EXTI0_1_IRQHandler(void){ // Interrupt from PB0
    GPIOB->ODR ^= (1U << 9); //PB9
    if ((GPIOB->IDR >> 0) & 1){
        //9
        setSSD(9);
    }
GPIOB->ODR ^= (1U << 9); //PB9
}

//INTERRUPT FOR NUMBER 8
void EXTI2_3_IRQHandler(void){// Interrupt from PB2

    GPIOB->ODR ^= (1U << 9); //PB9
    if ((GPIOB->IDR >> 2) & 1){
        //8
        setSSD(8);
    }
}

//INTERRUPT FOR A 
void EXTI4_15_IRQHandler(void){
        if ((GPIOA->IDR >> 9) & 1){
            //A
            addition (x,y);
        }
        GPIOB->ODR ^= (1U << 4); //PB4
}

這是我的問題:在普通的 C 語言中,我會要求用戶用 scanf 給出數字並將數字放入變量 x,然后取另一個數字,將其放入 y。 並將A定義為x + y,這樣計算就完成了。

但是在這里,沒有像 function 這樣的 scanf,那么我該如何訂購中斷呢? 就像第一個中斷(按下的第一個數字)應該是 x,第二個中斷(按下的第二個數字)應該是 y。

對不起,我的腦子很亂,如果你能想出任何解決方案,我會很高興的。

您需要修改您的設計,而不是將 I/O 與應用程序混為一談。 首先讓您的 I/O 使用開關去抖動等(可能使用中斷,也可能不使用中斷); 然后編寫計算器應用程序。 您已經考慮過如何使用 stdio 執行此操作,就像scanf()不會更新顯示或執行計算一樣,您的鍵盤驅動程序也不應該。

合適的鍵盤驅動程序將檢測按鍵,執行去抖動,然后將按鍵放置在環形緩沖區或隊列中。 然后,您的計算器應用程序可以在正常處理線程中實現,而不是在中斷處理程序中。

然后,您需要將計算器應用程序分解為每個可能的按鍵操作的子程序。 例如下面我假設了一個簡單的四位 function 計算器。

您的問題的答案具體是使用一個簡單的“狀態機”,其中 state 在按下操作員鍵時遞增,並使用該“狀態”來確定正在更新哪個操作員。 您只需要兩個“寄存器”,因為真正的計算器執行 x = x + y 而不是 A = x + y,因此答案可以用作進一步操作數中的操作數。

// Variables to store the operands and operator
int operand[2] = 0 ;
int operand_idx = 0 ;
typedef enum
{
    ADD,SUB,MUL,DIV
} eOperator ;

eOperator operator ;

// Call for each digit key pressed
void addDigit( int d )
{
    operand[operand_idx] *= 10 ;
    operand[operand_idx] += d ;
    display( operand[operand_idx] ) ;
}

// Call when an operator key is pressed
void setOperator( eOperator op )
{
    if( operator == 0 )
    {
        operator = op ;
        operand_idx = 1 ;
    }
    else
    {
        calculate() ;
    }
}

// Call when "=" / answer key pressed
void calculate()
{
    switch( operator )
    {
        case ADD :  operand[0] = operand[0] + operand[1] ; break ;
        case SUB :  operand[0] = operand[0] - operand[1] ; break ;
        case MUL :  operand[0] = operand[0] * operand[1] ; break ;
        case DIV :  operand[0] = operand[0] / operand[1] ; break ;
    }

    display( operand[0] ) ;
    operand[1] = 0 ;
}

// Call to clear calculation
void clear()
{
    operand[0] = 0 ;
    operand[1] = 0 ;
    operand_idx = 0 ;
}

然后假設您使用getKey() function 實現了合適的鍵盤驅動程序,那么計算器本身將如下所示:

for(;;)
{
    char key = getKey() ;

    if( isdigit( key ) )
    {
        addDigit( key - '0' ) ;
    }
    else
    {
        switch( key )
        {
             case 'A' : setOperator( ADD ) ; break ;
             case 'B' : setOperator( SUB ) ; break ;
             case 'C' : setOperator( MUL ) ; break ;
             case 'D' : setOperator( DIV ) ; break ;
             case 'E' : calculate() ; break ;
             case 'F' : clear() ; break ;
        }
    }
}

您描述的用戶界面是有狀態的,即它可以在您輸入“X”的 state 中,也可以在您輸入“Y”的 state 中。 可以在中斷處理程序中添加 state “分支”,即if (state == StateX)... else if (state == StateY)... 但中斷處理程序通常最好簡短而簡單。

一種方法如下:讓數字和小數點中斷在某個Q寄存器上工作,然后當按下非數字鍵時,您使用當前 state 來決定應該將Q復制到哪個寄存器(並且您然后還更新 state)。

您需要為自己繪制一個 state 圖表,以識別您關心的狀態、觸發它們之間轉換的原因以及進入和退出每個 state 時會發生什么(這些操作當然可能是空的)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM