2016-04-07 6 views
2

以下のコードでは、LEDが常に点滅しているため、タイマーが正常に動作しています。しかし、count変数の値は、2番目のwhileの内部で決して変更されません。STM32F4の割り込みによって変数の値が更新されないディスカバリー

何が間違っている可能性があるのか​​分かりませんか?

// count variable used only in main and TIM2_IRQHandler. 
uint8_t count=0; 

int main(void) 
{ 
    count=0; 
    SystemInit(); 
    GPIOInit(); 
    NVIC_Configuration(); 
    TIM_Configuration(); 
    init_USART3(115200); 
    // All initialization is ok. 
    USART_puts(USART3, "\r\nConnection ok.\r\n");// Working normally 
    while (1) 
    { 
     if(asterixok==1)// No problem. This code if ok ->>process continue next step. 
     { 
      GPIO_SetBits(GPIOD , GPIO_Pin_12); // Led on (ok) 
      count=0;// count going to zero, timer working, must be change in there 
      while(1) 
      { 
       //Led blinking continue 
       //Timer query working normal led (13) blink. 
       //There is a problem 
       if(count>5) // Timer working, count never change in timer interrupt query (WHY) 
       { 
        GPIO_SetBits(GPIOD , GPIO_Pin_14); // LED OFFFFFFFFFFFFFFFF 
        USART_puts(USART3, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r\n"); 
        goto nextstate; 
       } 
      } 
      nextstate: 
      GPIO_SetBits(GPIOD , GPIO_Pin_15); // Led never going on because code step in while loop. 
     } 
    } 
} 

void USART3_IRQHandler(void) 
{ 
    if(USART_GetITStatus(USART3, USART_IT_RXNE)) 
    { 
     unsigned char t = USART3->DR; 
     if(t=='*') 
     { 
      asterixok=1; 
     } 
    } 
} 

void TIM2_IRQHandler(void) 
{ 
    if (TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET) 
    { 
     TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); 
     count++; 
     if(count>100) 
      count=0; 
     if(display) 
     { 
      GPIO_ResetBits(GPIOD , GPIO_Pin_13); 
     } 
     else 
     { 
      GPIO_SetBits(GPIOD , GPIO_Pin_13); 
     } 
     display = ~display; 
    } 
} 

私は別のディスカバリーボードを試しましたが、問題は引き続き発生します。 助けてください。私はおかしくなりそうだ!コンパイラはcountはループ本体で変更されていなかったことを証明することができたmainをコンパイルしながら

volatile uint8_t count; 

を、ので、それはおそらく、レジスタにその値をキャッシュされた:

答えて

1

次のような、volatileとしてcountを宣言する必要がありますおそらくifステートメントを最適化することさえできます。あなたは分解を見て確認することができます。コンパイラは、標準に従って割り込みについて知らないので、そのような最適化を実行することが許可されています。 countvolatileとすると、コンパイラはこれらの最適化を行わず、使用するたびにメモリから変数をリロードすることを強制します。

この単純なケースでは、volatileで十分ですが、操作のアトミック性を保証するものではなく、コンパイラとCPUが変数へのアクセスに関する命令を並べ替えることを妨げません。これは、変数が使用されるたびにコンパイラにメモリアクセス命令を生成させるだけです。原子性のためにはロックが必要であり、並べ替えを防ぐためにはメモリの障壁が必要です。

+0

Tahnkあなたの解決策をお手伝いします。私はvolatile変数のキーワードを試しました。ときどき問題が繰り返されることもありました。私が理解しているように、割り込みクエリハンドラと依存コードの両方が同じ "名前付きカウント" GLOBAL変数にアクセスしている場合、おそらくこれが発生します。おそらく、これを修正する割り込みアクションを無効/有効にします。私は適切な時にそれを試してみる。 – Fico

関連する問題