ATtiny13の8bitタイマ操作でanalogWrite()再現

ATtiny13

はじめに

こんにちは!

最近はATtiny13ばっかりの記事ですが私自身の備忘録として細かいこともまとめていこうと思います。

今回はArduino関数であるanalogWrite()をATtiny13のレジスタ操作で再現しますよ。

詳細は次項から説明しますが、ATtiny13には8bitタイマ/カウンタの機能があり、これを使用してPWMを作っていこうと思います。

では、どうぞ!

8bitタイマ/カウンタ説明

ATtiny13には8bitタイマ/カウンタが2ピン(OC0A, OC0B)備え付けられております。

ざっくりとですがタイマ/カウンタレジスタは【TCNT0】であり、タイマ/カウンタ比較レジスタ【OCR0A, OCR0B】と比較することでPWMを作り出すことが出来ます。

  • タイマカウンタ:TCNT0(カウント中の書き込みは厳禁です。)
7bit 6bit 5bit 4bit 3bit 2bit 1bit 0bit
(MSB) (LSB)
  • タイマカウンタ比較レジスタ:OCR0A, OCR0B
7bit 6bit 5bit 4bit 3bit 2bit 1bit 0bit
(MSB) (LSB)

これらの設定に関してはタイマ/カウンタ制御レジスタ【TCCR0A】と【TCCR0B】で行う必要があります。

  • タイマカウンタ制御レジスタ:TCCR0A
7bit 6bit 5bit 4bit 3bit 2bit 1bit 0bit
COM0A1 COM0A0 COM0B1 COM0B0 WGM01 WGM00
  • タイマカウンタ制御レジスタ:TCCR0B
7bit 6bit 5bit 4bit 3bit 2bit 1bit 0bit
FOC0A FOC0B WGM02 CS02 CS01 CS00

動作設定に関してはWGM02, WGM01, WGM00を設定することで出力波形の種別の選択ができます。6動作ありますが、基本4動作に分類され残りの2動作に関してはタイマ波形のTOP値、タイマ/カウンタ漏れ割り込みフラグ【TOV0】の設定の違いになります。

WGM02 WGM01 WGM00 動作種別 TOP OCR0x更新時 TOV0設定時
0 0 0 標準 FF 即時 MAX
0 0 1 8bit位相基準PWM FF TOP BOTTOM
0 1 0 CTC OCR0A 即時 MAX
0 1 1 8bit高速PWM(本記事) FF BOTTOM MAX
1 0 0 予約
1 0 1 位相基準PWM OCR0A TOP BOTTOM
1 1 0 予約
1 1 1 高速PWM OCR0A BOTTOM TOP
  • 標準動作:単純な加算カウント8bit(255)を超えて値がオーバーフローすると0からカウントリスタートする(非PWM)。

  • CTC動作:OCR0Aがカウンタに対するTOP値となり、カウントがOCR0Aに達すると0に戻る。カウントがTOPに達するときに割り込み(TOV0)が生成できるのでこの時にOCR0Aを更新することでカウンタに対するTOP値を更新することができる(非PWM)。

  • 高速PWM動作:片傾斜の三角波に対してOCR0Aを比較することでPWMを生成することができる。次項の両傾斜三角波によるPWM動作に比べて動作周波数を1/2にすることができる。(今回はこちらでテストしていきます。)

  • 位相基準PWM動作:両傾斜の三角波に対してOCR0Aを比較することでPWMを生成することができる。高速PWM動作に比べて動作周波数は低くなるが、メリットとして両傾斜の三角波を使用しているので、その対称性からPWM波形の位相がずれにくくなります。モーター制御に有利らしい。

また、COM0x1, COM0x0の設定により比較出力(PWM)の選択を行うことが出来ます。本記事では非反転出力を扱っていきます。その他の設定に関してはデータシートの参照をお願い致します。

ATtiny13データシート

実装_高速PWM

コード

実装という事で今回は高速PWMのみをピックアップしていきます。コードに関してはArduino関数であるanalogWrite(pin, int8_t)の雰囲気でhsPWM(bool, int8_t)とする関数を作っていきますね。

<引数>

  • bool:  0または1(PB0,PB1出力のため)
  • int8_t:  0~255

返り値は8bitPWM出力です。システムクロック9.6Mzに対するタイマクロックの分周比は行っていませんが【TCCR0B】レジスタで8分周~1024分周まで設定することが出来ます。次項で少し説明します。

テスト回路はPB0に適当な抵抗を繋いだLEDを接続してみてください。hsPWMの第二引数を調整することでLEDの調光ができるかと思います。

タイマ/カウンタ入力クロック(分周)について

ATtiny13の8bitタイマ/カウンタの入力クロックはシステムクロック(デフォルト9.6MHz)に対して0~1024の分周比を取ることが出来ます。本記事ではLED調光に使用したので分周なしで使用しました。

例えば分周比8(9.6/8=1.2MHz)で使用した場合は83us毎にカウントアップしていきます。たとえば前述のコードで分周比8にして、比較レジスタ【OCR0A】を127に設定した場合は0.01ms(83us×127)毎にON/OFFするような出力になります。分周比1024(9.4kHz)に設定して【OCR0A】を127に設定した場合は13.5ms(0.1ms×127)毎にON/OFFされるはず、、、です(間違っていたらご指摘ください)。

その様子を以下の動画にまとめました。

※視覚的にわかりやすいようにする為にシステムクロックを9.6/8分周比で1.2MHzとしています。

おわりに

先日の記事から引き続きでArduinoの関数をレジスタ操作で再現していきました。今回のAnalogWrite()が出来ればほぼほぼ基本的な関数はマスターすることが出来たのでしょうか(細かいところは全然だと思いますが、、、)

せっかくなので、近いうちにATtiny13を使った何かを作ってみたいと思います!

ではでは~

コメント

タイトルとURLをコピーしました