工作の2S(Seiri/Seiton)

工作やプログラムでやったことをまとめていきます

PIC1823のTimer0モジュールまとめ

●Timer0モジュールを使う目的

  • ミリ秒のウェイト
  • メインループのFPS管理

ワタクシはTimer0の割り込みでカウンタをインクリメントしています

現在オーバーフロー対策がありません(そんなんでいいんかい!)

 

●Timer0モジュール

f:id:kt-marshal:20160502215516j:plain

f:id:kt-marshal:20160502220447j:plainFosc/4(左上)を青線のとおりに導いてクロック源とするために OPTION_REG を設定し、割り込みを有効化すればTMR0レジスタのカウントが始まります。オーバフローするたびに割り込みルーチンが呼び出されます。

TMR0レジスタ

TMR0レジスタは8bitなので255からインクリメントした時点でオーバフローし、割り込み処理が呼び出されます。つまり256クロック必要なことになり必然的に256分周されちゃうわけです。

そこで割り込み処理終了時にTMR0に意図的に数字をセットすることで細かいタイミング調整ができると思います。(なぜ断言しないかというと合ってるかどうかはわからないがそれっぽくなったから)

●プログラム

tim0Initなど関数はtim0_lib.cにまとめてあります

// ------------------------------------------------------------------------------------------------
// 割り込み
// ------------------------------------------------------------------------------------------------
void interrupt isr(void){
  // Timer0割り込み処理
  if (TMR0IF == 1){
    tim0_count++;
    TMR0IF = 0;
    TMR0 = tmr0_val;
  }
}

void main(void) {
  // 初期化処理
  // Oscillator Control Register
  // SPLLEN (1) : 4x PLL is enable.
  // IRCF (1101): Internal oscillator frequency [4MHz HF]
  // uninplemented (0) : Read as '0'
  // SCS (11) : System clock select [Internal oscillator block]
  OSCCON = 0b11101011;

  // Timer0初期化
  tim0Init(OPTION_PA_8, 131);

  // 割り込みの有効
  PEIE = 1;
  GIE = 1;

  while(1){
    tim0_Wait(1000);
  }

  return;
}

 

下記は参考プログラムファイル

tim0_lib.zip - Google ドライブ

 

●チョイ待ちWait談義

職場ではArduinoの普及とともに、続々とマイコンデビューするようになっています。しかも、Arduinoでは標準でdelay()が用意されておりWaitもお気軽です。

そして、よく見かけるのが「ここのWait10秒実行してる間、スイッチとか見れないからどうしようかなー」というマイコンWait All 無視状態への対策。特にフロー制御系で出てきます。

こういう処理の場合、ワタクシは個人的に500msec以上のWaitは使わないようにしています。

下記のように「入力処理」と「状態」に分離し一箇所で処理がクローズしないようにします

 

入力処理 --------------------------

現在の状態を設定する

スイッチ、完了信号を変数などに代入(制御、出力は行わない)

 

状態処理 --------------------------

状態により遷移と処理

mode変数を列挙対として用意する。case内で状態遷移と処理を行う

switch(mode){

  case state1:  // センサーONならstate2へ

  case state2:  // 処理1実行しstate3へ

  case state3:  // 処理1実行完了ならstate1へ

}

てきな?

switchを増やせば並列作業も一応できると思います。ポイントはwhileなどで一箇所で処理が停滞することのないプログラムにするところです。

これはPLCのラダーの概念を参考にしています