[英]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.