fc2ブログ
AVRで1秒を出力
Atmel社の AVR シリーズはコストパフォーマンスに優れた ワンチップマイコン。中でも ATtiny2313 は1個100円(秋月電子通商)という安価にもかかわらず小規模制御に利用できる十分な機能を有しており、対応するフリーの開発ソフトが沢山あることやプログラムライターが簡単に自作できるなどのメリットがある。

小規模制御といえども欠かすことのできないのは「時間処理」。ワンチップマイコンに書込むプログラムではもちろん「遅延命令」が利用できるけれども、単純にこれを使ってしまうと他の処理を滞らせることにもなりかねない。多少PLC(シーケンサ)ライクに使うためには時間計測をメイン処理ループと分離させた方がベターで、AVRでは内部機能である「ハードウェアタイマー」を利用することでこれを実現できる。

ただこの「ハードウェアタイマー」の概念がなかなか取っつきにくいため、以下に簡単にまとめてみた。マイコン学習を始める人の一助になれば。

-----------------------------------------------------------

・ハードウェアタイマーを動かす基準は内蔵オシレータや外付けした発振子が発生させる周波で、分周波を1に設定すると周波の波1つがタイマーの1カウントになる。分周波8の場合は波8つで1カウント、分周波64の場合は波64個で1カウント。

・ATtiny2313 は「Timer0」と「Timer1」の2種類のハードウェアタイマーを持っていて、前者は256カウントでオーバーフロー(いわゆるタイムアップ)、後者は65536カウントでオーバーフローする。オーバーフローが発生するとそれをタイミングにして割込処理を実施できる。ただオーバーフローはPLCのタイムアップと異なりタイマーのカウントは基本的には止まらない(タイマー停止命令で止めるまでまた0からカウント)。なのでどちらかというとタイマーと言うより鳩時計に近い(笑)。またカウント値はそれぞれの名前の変数で随時取得ができ、カウント値を変更することもできる。

・例えば内蔵オシレータを利用(既定)で1MHz(1000000波/秒)をクロック周波数に設定し、Timer0で分周波を64にして使用する場合、1000000÷64÷256=61と余り9、即ち61回オーバーフローしてさらに9カウントしたら1秒ということになる。実際はオシレータ発振誤差や命令処理に消費するロスタイムがあると思うがここではそんなことは無視(笑)。

・以下に、1秒毎に赤LEDをフラッシュ、10秒経過毎に緑LEDが点灯/消灯を繰り返すプログラムの例を記載した( BASCOM-AVR でコンパイルする場合の記述)。当方の ブレッドボード では時間誤差も見られず気持ち良くLEDが点滅している。

-----------------------------------------------------------

$regfile = "ATtiny2313.DAT" ' 使用するチップのデータファイルを指定
$crystal = 1000000 ' クロック周波数を1MHzに指定
Config Timer0 = Timer , Prescale = 64 ' Timer0を分周波64で設定
Config Portb = &B00011000 ' ポートbのビット3から4を出力に設定
Config Portd = &B00000000 ' ポートdの全ビットを入力に設定
Portd = Bits(2) ' ポートdのビット2(割込用ビット)の内部抵抗をプルアップ
On Timer0 Tout ' Timer0がオーバーフローしたときの割込実行先を指定
On Int0 Prb ' 割込用ビットのPBをONした場合の割込実行先を指定
Enable Timer0 ' Timer0による割込を許可
Enable Int0 ' Int0による割込を許可
Enable Interrupts ' 割込を許可
Dim B As Byte ' オーバーフロー変数をバイト型に指定
Dim C As Byte ' 秒変数をバイト型に指定
Stop ' Stopの記述はそこでの永久ループを意味する

Tout: ' Timer0がオーバーフローした時に割込実行されるサブルーチン
B = B + 1 ' オーバーフロー回数を変数Bに追加
If B = 8 Then ' オーバーフロー回数が8回なら、
Reset Portb.3 ' ポートbのビット3(赤LED)をOFF
End If
If B = 61 Then ' オーバーフロー回数が61回なら、
Do ' (ループ起点)
If Timer0 >= 9 Then ' Timer0のカウントが9以上で、
B = 0 ' オーバーフロー回数変数Bを初期化し、
Gosub Ldisp ' サブルーチン「Ldisp」の処理をして、
Exit Do ' ループを抜ける
End If
Loop ' (ループ終点)
End If
Return

Ldisp: ' 1秒経過ごとに実行されるサブルーチン
C = C + 1 ' 秒を秒変数Cに追加
If C = 10 Then ' 10秒たったら、
Toggle Portb.4 ' ポートbのビット4(緑LED)を反転し、
C = 0 ' 秒変数Cを初期化
End If
Set Portb.3 ' ポートbのビット3(赤LED)をON
Return

Prb: ' 割込用ビットのPBをONした場合に割込実行されるサブルーチン
Set Portb.3 ' ポートbのビット3(赤LED)をON
Set Portb.4 ' ポートbのビット4(緑LED)をON
Bitwait Pind.2 , Set ' PBがOFFになるまで待機
Reset Portb.3 ' ポートbのビット3(赤LED)をOFF
Reset Portb.4 ' ポートbのビット4(緑LED)をOFF
Timer0 = 0 ' Timer0のカウント値をリセット
B = 0 ' オーバーフロー回数変数Bを初期化
C = 0 ' 秒変数Cを初期化
Return

-----------------------------------------------------------

タグ : AVRATtiny2313マイコンPLCシーケンサハードウェアタイマーブレッドボードBASCOM

2008-11-04 01:29 マイコン応用
コメントの投稿 (ここをクリックするとフォームが開きます。)
    管理者にだけ表示を許可する


コメント

解説が判りやすいです!!
今まで悩んでたモヤモヤが綺麗に晴れます。
気持ちがいいですね。
今度はヒューズビットの説明をお願いいたします。
どしどし解説お願いいたします。


2011-01-12 | URL | さとう #- [ 編集]
トラックバック
この記事のトラックバックURL
(記事引用不問です。関連記事からのトラックバック歓迎します。)

管理人の承認後に表示されます

2013-10-17 /
管理人の承認後に表示されます

2013-10-25 /
管理人の承認後に表示されます

2013-11-07 /