DACの話ではありません。

 

DACにもマイコンは使いますが、まず今回のようなケースには当てはまらないです。

 

昔も書いたんですが、今回は対策例(愚策のような気がします)。

マイコンを使う時、割り込み関数とメイン関数で同じ変数にアクセスしたいことがあります。
 

データの1かたまりが全部同時に読み書きできさえすれば、

読み書きのタイミングが問題になることがプログラムの仕様として要求されることは

メイン関数と割り込み関数で、ということであればそんなシビアな仕様にはしないと思います。

 

しかし、データが1つのかたまりとして整合性がとれなくなると、問題です。

 

割り込み関数側と、メイン関数側で、読み書きが同期的ではなく行われるようなケースでは

メインで読み書きしている最中に割り込みが入ることが考えられます。

 

昔の記事には、「割り込みを禁止しろ」と書きました。

対策の1つではあります。しかし、割り込みを禁止してしまうと、割り込みのタイミングが一定でなくなったり

割り込み要求が処理されるまでの時間が長くなったりします。

正確に◯msごとに割り込む、とか、割り込みを超高速で返さないとまずいときは困るんです。

 

私は、8bitのマイコンでは、1バイトのデータを操作することで対策しています。

1バイトなので、1命令で処理でき、データの整合が取れます。

 

uint16_t value1;

uint16_t value2;

 

uint8_t value1_main_using = 0;

 

main(){

 
  if(value1_main_using == 0){

    value1_main_using = 1;

    // main using value1

    // value1を操作

  }else{

    value1_main_using = 0;

    // main using value2

    // value2を操作

  }

}

 

割り込みではvalue1_main_usingを読んで、反対側の変数にアクセスします。

value1_main_usingは割り込みでは操作しません。

 

ネットの記事を読んでいて、同じ操作をしたページを見たことがないんです。

みなさんどうやってるんでしょう。

 

ちなみに、この方法だと、割り込み関数で変数が更新されたかどうかわかりません。

更新されない場合もあるときは、

 

uint8_t updated1;

uint8_t updated2;

変数を追加すればよいです。

  if(value1_main_using == 0){

    value1_main_using = 1;

    // main using value1

    if(updated1){

    // value1を操作

      updated1 = 0;

    }
  }else{

    value1_main_using = 0;

    // main using value2

    if(updated2){

    // value2を操作

      updated2 = 0;

    }

  }

 

こうすれば、割り込みで値が更新されたときだけ処理できます。

作業は面倒ですが、割り込みを切りたくないけど、データが壊れると困るときは

これに限ります。

 

普通の人はPICではIFとIEを割り込みでどちらも見て処理し、

IEを切るのでしょうか。

割り込み関数のリアルタイム性も、割り込み関数内に分岐があると意味ありませんし。

作業量を考えると、そちらのほうがいいかもしれませんね。

あまりにデータが大きく、処理に困る時に使うくらいでしょう。