void
sysdown ( int dly ) // dly .. in msec
{
int i ;
byte s ;
SPCR = 0x00 ; // disable SPI
TCCR0B = 0x00 ; // stop timer0
TCCR0A = 0x02 ; // ctc mode
TIMSK0 = 0x00 ; // Disable all timer0 irqs
TIFR0 = 0x07 ; // clear flags
TCNT0 = 0x00 ;
OCR0A = 250 - 1 ;
TCCR0B = 0x03 ; // start timer0 pre = 1/64 i.e 250kHz
s = 0 ;
while ( true ) {
if ( ++ s & 1 )
PORTB |= 0x20 ; // D13 == HIGH (LED on)
else
PORTB &= 0xdf ; // D13 == LOW (LED off)
for ( i = 0 ; i < dly ; i ++ ) {
while ( ( TIFR0 & 2 ) == 0 )
;
TIFR0 = 0x07 ; // clear flags
}
}
}
/*
関数名からすると、システムダウンした場合の後始末をする関数らしい。
例として、txinit(void)内にて送信バッファが最大サイズTXBSZ以上になるとsysdown(200)が実行される。
ここでのカウンタ0の目的は何だろう?
SPCR = 0x00; // disable SPI リセット直後と同じ値
TCCR0B = 0x00; // stop timer0 リセット直後と同じ値
TCCR0A = 0x02; // ctc mode ctc (clear timer on compare match) リセット直後は0x00
ctc動作とは、カウンタ値=比較器に設定した値 で、割込みフラグ立てカウンタ値を0にセット
PWM動作させるためには 0x42 or 0x82 or 0xc2 だと思うが、0x02だとOC0A出力ではなくて標準ポート。
TIMSK0 = 0x00; // Disable all timer0 irqs 割り込み許可のリセット リセット直後と同じ値
TIFR0 = 0x07; // clear flags 各ビットに対応する割り込み要求フラグの解除 リセット直後は0x00
TCNT0 = 0x00; カウンタの初期値 リセット直後と同じ値
OCR0A = 250 - 1; 比較器0Aに値をセット
TCCR0B = 0x03; // start timer0 pre = 1/64 64分周を設定 i.e 250kHz 16MHz÷64=250kHz
ということはカウンタ0は250kHzのクロックを249個まで数える?
とすると1msec間隔でctc動作している。
最初のwhileですが、while(true) で無限ループになっています。どうやって抜けるのでしょう?
でも、システムダウンしているなら抜ける必要もないのかもしれません。
sが奇数の時はLED on、偶数の時LED off、それから2番目のwhile文ですが、dlyで設定した時間だけLED
の状態を維持させています。つまり、LEDの点滅間隔でどの関数が呼んだsysdown(dly)かを区別させてる?
ここでのカウンタ0の使い方がよくわからないですね。もしわかったら追記修正します。
*/
【このカテゴリーの最新記事】
- no image
- no image
- no image
- no image
- no image