AVRのMCUはおもしろい素子です。 アセンブリはしんどい言語ですが Cはまだ人間的です。 winAVRで、AVRを使うと楽しく遊べるのではないかと思います。 ソフトウエアが無料で使えて、開発機材も簡単に自作できるので、 中学生のお小遣いでも、マイクロコントローラを楽しめるでしょう。 「それでは始めよか!」と思った人が、なにから手を付けたらよいのか 分かるようにと考えながら、ここ数ヶ月歩んだ自分の道のりをまとめて みました。04.07.28 (そして、追加しました。) |
Tiny26LとC言語 90S2313?,tiny2313?
実験を始める環境づくり
実験1 LED1個の点滅 −−−Cコンパイラの使い方−−−
実験2 LED8個の順次点滅
実験3 タクトスイッチ2進カウンタ
実験4 7エレメントLED4桁表示(ダイナミック点灯)
実験5 ADCを使う−−電圧の測定−− 04.12.09
実験6 液晶表示器 04.12.23
実験7 LEDをセンサとして使う 05.10.16
あとは、ぼちぼち続きます ご要望があればご連絡下さい。
WinAVR20050214に対応するために修正しました。05.03.01
ATTiny26L
は比較的安価で、通信販売でも買うことができます。秋月電子通商で280円です。90S2313と似たような感じですが、
新しいデバイスです。RC発振機能を内蔵しているので水晶発振子(またはセラミックレゾネータ)が無くても使えるので実験回路が
簡単になります。必要ならば、水晶発振子を使うこともできます。また、アマチュアにとってありがたいことにプログラムの書き換え
保証が10,000回になっています(90S2313では1000回でした)。これだけあればプログラムを少しずつ変更しながら実験することができ
ます。 100回書き換えても2.8円なら気安く勉強できるでしょう。
値段、入手性、発振子不要、書き換え回数からATTiny26Lを選びました。
(05.07.20) tiny26はADCがあるのは良いのですが、UARTがありません。また、制作例も少ないようです。この項を書いた頃は私の経験も少なく、最初の勉強は
これで行こうと思ったのですが、その後の制作例などから2313の方が素直(何が?)な気がして、2313ではじめるのも良いかと思います。
2313は現在、90Sとtinyの2種類があります。90S2313は旧型であってセラミック(または水晶)発振子が必要で、書き換え保証が1000回ですが、秋月で安価に
入手できます。tiny2313は新しいデバイスでRC発振回路を内蔵していますのでセラミックレゾネータは無くても使えます。また書き換えが10000回となっているほか
多くの改良点があるようです。オプティマイズで4個1100円で購入できます。まとめ買い(25個)ならDegi-Keyでしょう。
ここの作例の内、ADC関係を除いて 2313 の回路とプログラムは作製が容易ですから、リクエストがあれば作ろうと思います。ご意見は掲示板にお書きいただければ
幸甚です。ADCが必要なら上位のmega48を使う手があります。2、3個なら絶対価格はびっくりするほどでもありません。
この「ATTiny26Lで始めるAVRの基礎 」は長期間更新していないのですが恒常的に多くのアクセスをいただいてますので 2313 についての考えを追記しました。
C言語を使う winAVRというフリーのすばらしいコンパイラがあります。デバイスの命令を覚えて、
アセンブリ言語を使うのが初歩の一般的な考え方ですが、フリーソフトがあるAVRではCで始めた方が良いと思います。レジスタやメモリの
使用状態を考えながら(メモしながら)流れを考えるのは苦しいことです。移植性が良いと言われるより、これらの管理を人間がしなくて
も良いのはうれしいことです。プログラム文も人間的です。
実験を始める環境づくり 次に挙げるものが必要です。
1 パソコン:シリアルコネクタ(D-sub 9ピン、RS2323Cと言われるもの)付きのもの。最近のノート型に多いUSBしかないものは
プログラマ(ライタ)を別に用意しなければなりません。OSはwindows2000かXPが普通でしょう。98でもokです。
2 エディタ:プログラムを書くために用意します。
3 Cコンパイラ:書いたプログラムをMCU(AVRのこと)用のHEXファイルに変えます。winAVRを使います。
4 プログラマ:書き込み機です。頑張って作りましょう。
5 書込用ソフト:フリーのものを使います。
6 電源装置: 5ボルトなら何でもいいのですが。
7 テスター: 無くても良いがあれば便利。ディジタルよりアナログが使いやすい。
8 実験用回路:これから作るもの。
・
Cコンパイラ
プログラマ
書き込み用ソフトウエア
win2000、winXPでは上にあるようにCOMポートが自由に使えなくなっています。このソフトは2004年5月に2000やXPに対応できるように
改良されたものです(これでXPで使えるようになりました 感謝)が、COMポートが使えるように「giveio.sys」をインストールする
必要があります。
電源装置
実験2 LED8個の順次点滅
と言うことになるでしょう。冒頭にメモを付けておくと良いでしょう
実験3 タクトスイッチ2進カウンタ
実験4 7エレメントLED4桁表示(ダイナミック点灯)
実験5 ADCを使う−−電圧の測定−−
測定のゆれはありますが、ほぼ直線関係にあります。カウント数のおよそ2.725倍が電圧値となるようですので、プログラムで計算させることにしました。
実験6 液晶表示器
エディタ
行番号が必要ですから「サクラエディタ」を用意します。 ここ
からダウンロードします。Package をDLしましょう。ダウンロードファイル(.exe)を実行してC:\Program Files\にインストールしました。行番号のあるエディタ
なら使い慣れたものがいいでしょう。かつて「えるの〜と」を薦めてきましたが公開終了になりましたので、サクラエディタに変更しました。少しカスタマイズ
して以前のエディタに近い配色にしています。05.07.20
実験を始める環境づくりへもどる
C言語のルールで書いたテキストファイル(.c)をAVRが分かる機械語に変換するのがコンパイラです。AVR用にすばらしい
ソフトウエアがフリーで提供されています。winAVRといいます。
最新版 WinAVR のダウンロードを参考にダウンロードしてください。
WinAVR-200xxxxx-install.exeがダウンロードできたでしょうか?
インストールしましょう。
WinAVR-200xxxxx-install.exeをダブルクリックで実行してください。インストールの場所は
一般にはC:\winAVRで良いでしょう。私はE:\winAVRにインストールしました。フォルダ winAVR のショートカットをデスクトップ
に置くと便利でしょう。このフォルダの中には多くのフォルダとファイルがあります。時間があれば覗いてください。
実験を始める環境づくりへもどる
書き込み機です。頑張って作りましょう。ChaNさんの
シリアルライタです。 「COMポート制御ISPアダプタの製作」を探して
ください。下に回路図を掲載します。
('04.12.12追加)この回路図のICは74HC126 or 74HC125となっていますが、これらで接続の一部と働きが異なります。この図は126の場合を示しています。
125はC入力が負論理ですから、@13番ピンはGNDに接続(最近のChanさんの図はそうなっています)、ASWはoff時に書き込みになります。onで書き込むには
C入力(1,4,10)をプルアップしておいてSWでGNDに落とします。 on書き込みでプッシュSWに変えると操作が快適です。
ピンソケット(メス)は写真下側です。AVR回路側はピンヘッダ(上側)を使います。両方とも2列×3本に切って(金属用糸鋸で)
使います。半田付けをする時にオス側、メス側とも誤接続防止のために、1番ピンに金色のマジックインクで印を付けています。
特別なデバイスが必要でなく、シリアル端子からケーブルが長くても安定した書き込みができる良い作品です。基板が小さいため、
スイッチ切り替え時の安定が悪いので木製の台を付けました。写真のものは電源が確認できるようにVcc-GND間にLED(抵抗を付けて)
を入れてあります。
制作時の注意を少し書いておきます。
・電源とGNDの配線は忘れやすいので良く注意しましょう。74HC126(125)のVccとGNDを確認しましょう。
・DSUB9ピンのシリアルコネクタはよく見ると番号が書いてあります。ルーペで見ましょう。番号を確認しながら配線すると間違いが防げます。
・回路図をプリントして置いて、配線した部分を赤鉛筆でなぞっておくと「忘れ」が防げます。昔の真空管アンプでは初心者の常識でした。
・うまく動かないときは、「神様でないから間違いがあって当たり前」の気持ちで、心静かに(?)点検しましょう。半田がちゃんとついていて、間違いがなければ
必ず動きます。ルーペは(私には)必需品です。
(05.07.20) リクエストがあって別項に「ChaNさんのISPライタの作り方」を書きました。
参照してください。
うまく働かないときのチェックポイント(上に書いたものと重複しています) 050702
@74HC126を使っていますか。HC126のときは13番ピンをVccにつなぎます。 125ならGNDにつなぎます。 126がお勧めです。
A74HC126のVcc(14番)とGND(7番)は電源と回路のGNDに接続していますか。 回路図には書かれていないので注意が必要です。
B同じ事ですが、126(125)はターゲットから5Vをもらっています。コネクタをとおして5Vが供給されていることをテスタで確認します。
CD-SUB9ピンの半田付けは間違いありませんか。回路図の配置でなく、コネクタの刻印を確認してください。(ルーペが必要?)
D「書き込み読み出し」と「テストラン」のモード切替にスイッチ操作が必要です(後発のUSBブリッジではOFFのままでよいのですが)。
126の時はONで書き込み、OFFでテストランです。125ではON,OFFが逆になります。
Eテスト用のターゲットはできるだけ簡単なもの(できれば動作確認済みのもの)を用意してください。
Fターゲットのクロックは確実に発振していますか。確認は困難ですが、古い90Sシリーズはクリスタル(セラロック)が無いと発振しません、mega、
tinyシリーズは内蔵のRCで発振可能です。新旧ともに使うときは忘れていることがあります。
GMISOとMOSIの配線をもう一度確認してください。
HターゲットのRESET端子をVccに直結していませんか。15〜47kΩくらいでプルアップしてください。(mega、tinyはなくてもよい。内部でプルアップ
されている。)
Iavrsp.exeのデフォルトポートはCOM1です。もし、COM2につながっているなら -pc2 でポートを指定しなければなりません。
(06.12.03) ライタが一つできたら、プログラムライタ と ライティングソフトの
★印のライタをお薦めします。書き込み時にスイッチ操作をしなくても良いので快適です。
実験を始める環境づくりへもどる
プログラマと同じ作者ChaNさんのライティングソフト avrsp.exe を使います。
シリアルライタのページの終わりの方に
「Win32版ISPライタ制御ツール(含ソース) 」というのがあるでしょう。これをダウンロードします。avrxtool32.zip が得られます。
解凍してください。avrsp.exeが書き込みソフトの本体です。
次の文はreadmeから抜粋したものです
●Windows NT/2k/XPでの使用
これらのOSではI/O操作のためにGIVEIOが必要です。GIVEIOが既にSCMに登録済みで
動作中の場合はすぐに使用できます。未登録の場合はGIVEIO.SYSを被検索パスのディ
レクトリ(%windir%\SYSTEM32など)に置いてAVRSPを使用すれば同時に登録されます。
この場合は、SCMにアクセスするためAdministrator権限でログインしている必要が
あります。
このページにインストールの詳しい方法が説明されていますのでこの
とおりインストールすることを勧めます。
実験を始める環境づくりへもどる
電圧が安定した5Vで、電流が200〜500mA流せるものならたいていの実験ができそうです。
もっとも簡単には、単三乾電池を4個直列にして、ダイオードを2個入れれば5V程度になります。新しい電池なら、3個直列でもいい
でしょう。
8V程度の電源があれば、3端子レギュレータ(7805など)で5Vを作るといいでしょう。発振防止のコンデンサが必要です。
スイッチングタイプの5V電源アダプタがあれば安心して実験を続けられます。
理想的には、過電流防止のヒューズをつけ、on/offスイッチがあり、電流計があれば安心です。私は、ヒューズを付けていませんが、
フルスケール600mAの電流計をつけています。電源回路のショートは、テスターで調べますが、微妙なトラブルは電流でわかることが
あります。ただ、電流計は3000円ほどしますので、用意しにくいかもしれません。私の電源は他の用途のために30年ほど前に
作ったものです。中古のVUメーターに直列と並列に適当な抵抗を入れておよその電流値をはかれるようにしたことがありますが、
こんなものでも安心感はあります。
他の用途の、ニッケル水素単三型電池4本の電源もよく使います。4.8〜4.9Vの安定した電圧を示します。私自身は乾電池をほとんど
使いません。
電源の出口は、リード線で引き出し、赤と黒のバナナクリップとしています。ターゲットにコネクタをつけなくてもピンを立てておく
だけで接続できます。
追記 100円ショップでアナログメーター付きの乾電池チェッカーを見ました。電源チェック用に使えないかと買ってみました。取り扱いの店が違うのですが次のページの報告「http://www.try-net.or.jp/~el_dream/report/btchk100/btchk100.html」とよく似た感じです。簡単に分解できました。テスターで調べたところ、フルスケール約500uA、内部抵抗500Ωのようでした。これだったら0.5Ωを並列に入れるとフルスケール500mAの電流計になりそうです。手持ちの大昔の4Ω巻線抵抗を分解しておよその長さに切ったものを半田付けしてみました。約20mAで少し振れがわかり、500mA程でフルスケールになりました。直線性は悪いようですが、実験回路のチェックには使えそうです。形が整ったら報告します。
実験を始める環境づくりへもどる
回路図は次の通りです。ポートPA0にLEDを1個だけ付けました。出力L(0)で点灯します。
ブレッドボードに実験回路を組み立てます。半田付けしなくて良いし、変更も簡単です。これは秋月電子で350円で買いました。
中央のエナメル線の束は書き込み用のケーブルです。別の写真のようにひもで縛って接着剤で固めました。バラバラの線より
すっきりします。また、実験用のLEDも抵抗を半田付けして一発で挿せるようにしました。このようなものを作っておくと便利です。
アマチュアの実験ですから、動かしながら作り上げるのはいかがでしょうか。上の写真のLEDを付ける前に、すなわち電源回路と書き込み
回路が完成したところで電源を入れて、書き込みソフトを走らせてみましょう。
電源を入れるときはテスターでショートしていないか調べます(抵抗レンジにして、マイナス=黒い方をプラス
に当てます)。次にちょこっと電源を入れて電流が極端に大きくないか見ましょう。数ミリアンペアまででしょう。なにも無いときはICに指を
ふれたままで電源を入れます。熱くなったら急いで切ります。
実験1 LED1個の点滅 −−プログラマのテスト
書き込みソフトavrsp.exeの本体を(ショートカットでなく)デスクトップに置いてください。2000やXPの方はgiveio.sysのインストール
は成功していますか? 大切なことですからチェックしておきましょう。DOSプロンプトのショートカットもデスクトップに置きましょう。
実験回路とプログラマをつなぎ、PCのシリアル端子に接続していることを確認して、電源を入れます。DOSプロンプトを起動して、avrsp.exeを
黒い窓の中にD&Dします。(くどいですが、ショーカットではダメ。) カレントがDOSにあることを確認して(カーソルチカチカでok)、
スペースを一つ入れて、 -rp とたたいてください。私の場合は次のようになりました。
-rp オプションはフラッシュROMを読み出す命令です。 tiny26 が検出されて、プログラムは書かれていない(FF)ことが分かります。
実験1 LED1個の点滅 −−プログラムを書く
いよいよプログラムです。先に保存場所を作って置きます。私の場合はwinAVRの下にprogフォルダを作り(winAVR\prog)、その中にプログラム
ごとのフォルダを作っています。これからの例で、作るプログラムが LED01(ゼロイチ) と言う名前にするとしましょう。winAVR\prog\LED01と
いうフォルダを作って置いて、その中に LED01.c というプログラムを置いています。なれるまで真似てください。winAVR\prog\LED01フォルダを
作りましたか?
えるの〜とを起動します。 次の通り入力してください。
念のためプログラムLED01.Cをここに置きます。若干の説明もコメント文で入れてあります。
最初の起動までは、まだ儀式があります。はじめだから頑張ってください。
makefile と mc.bat ファイルを作ります。
makefileを用意します。winAVR\sample\makefile をフォルダwinAVR\prog\LED01にコピーして編集します。
34行目 MCU= にATtiny26 と書き、40行目 TARGET= にLED01 と書きます。(コンパイルする.cファイルの".c"を除いて書く。)
それ以外はファイル名を含めて一切変更してはなりません。
これであとはカレントディレクトリをこのフォルダに移してmakeを実行すればよいのですが、面倒ですからカレントディレクトリ
を移動するバッチファイルを作っています。
エディタを起動して以下の3行の//より前の部分を書きます。行頭には空白は入れません。
E: //カレントドライブをE:に切り替えます。winAVR\prog\LED01フォルダのあるドライブ名に。C:の場合が多い。
cd E:\WinAVR\winAVR\prog\LED01 //カレントディレクトリを自分のプログラムのある場所に移動します。
make //makeを実行させます。
このテキストをmc.bat(mcは何でも良い)の名前でプログラムのあるフォルダに保存します。
この結果、1つのプログラムが入るフォルダには .cファイル、makefile、mc.batの3つのファイルができました。これから作るフォルダ
のすべてにこの3つのファイルが含まれることになります。新しいプログラムを書くときはこのmakefileとmc.batを新しいフォルダにコピー
して、makefileの MCU= とTARGER= 、mc.batのプログラムディレクトリ(フォルダ名)を変更して使っています。もっとスマートな
方法があるのかもしれませんがにわか勉強でまだ知りません。
コンパイルします。 コマンドプロンプトをショートカットから立ち上げて黒い窓を表示します。その窓の中に、
mc.batをD&Dします。
念のため窓の中で1クリックして間違いなくカレントを移し、enterキーを押します。いろいろな表示があって最後に Erroors: none
と表示があれば成功です。エラーがあれば、DOS窓を最小化してタスクバーに落とし、.cファイルを修正します。上書き保存して、タスクバーから
DOS窓を呼び出して、「F3キー」を押して(先ほどの入力をリピートしてくれる)enterキーで再度コンパイルします。
実験1 LED1個の点滅 −−AVRに書き込む−−
いよいよ,hexファイルをAVRに書き込みます。 先ほどのプログラムのあるフォルダにLED01.hexというhexファイルが
できているはずです。
コマンドプロンプトを新しく起動して、デスクトップにあるavrsp.exe(ショートカットではない。念のため)をD&Dします。
スペースを1つ書いてから目的の LED01.hex をD&Dします。
ターゲット回路とライタをつなぎ、電源を入れて、ライタの
書き込みスイッチをONにしてenterキーを押します。成功のメッセージを見たあと、プログラマのスイッチを切るとLEDが点滅する
でしょう。
成功しなかったら、回路を点検して、F3キーで再度書き込みます。
○avrsp.exeにhexファイルを指定しないとヘルプが表示されます。有用です。
実験1の回路に、ポートA1〜A7まで同じ向きに発光ダイオード(抵抗付き)を追加して、計8本の発光ダイオードを順番に点灯する
プログラムを考えて見よう。次のように考えてはどうか。
はじめに、ポートA0だけ点灯する。=ポートA0だけ0にする。しばらく時間を待つ。
つぎに、 ポートA1だけ点灯する。=ポートA1だけ0にする。しばらく時間を待つ。
ポートA2だけ点灯する。=ポートA2だけ0にする。しばらく時間を待つ。
順次番号を増やして
ポートA7だけ点灯する。=ポートA7だけ0にする。しばらく時間を待つ。
というプログラムを無限に繰り返せばよいと考えられます。
ここで、ポートA2だけ0にすると言うことは、2進数の「11111011」=16進数の0xfbを出力すればよい。win電卓を使ってください。
また、「しばらく時間を待つ」ルーチンは8回同じものができるので、サブルーチンにした方がよいだろう。
#include<avr/io.h>
void wait(void); /* プロトタイプ宣言 後でこの関数がでてくることをコンパイラに伝える */
int main(void){
DDRA=0xff; /* PORTA=output */
DDRB=0xff; /* PORTA=output 使わないポートはノイズ対策のため出力にする */
for(;;){ /* 無限ループの始まり */
PORTA=0xfe; /* fe=11111110 */
wait(); /* 時間稼ぎルーチン呼び出し */
PORTA=0xfd; /* fd=11111101 */
wait();
PORTA=0xfb; /* fb=11111011 */
wait();
PORTA=0xf7; /* f7=11110111 */
wait();
PORTA=0xef; /* ef=11101111 */
wait();
PORTA=0xdf; /* df=11011111 */
wait();
PORTA=0xbf; /* bf=10111111 */
wait();
PORTA=0x7f; /* 7f=01111111 */
wait();
} /* 無限ループの終わり */
} /* mainルーチン(main関数)の終わり */
void wait(void){ /* wait関数の始まり 時間稼ぎルーチン */
long k;
for(k=1;k<200000;k++){ /*19万9999回繰り返し */
k=k; /* 無意味な代入 時間稼ぎ */
}
} /* wait関数の終わり */
/* **********************************************************
LED02.c LEDの順次点灯 実験2のプログラム
LED:portA 0〜7
********************************************************** */
もっとスマートな方法もありますが、後で考えましょう。
winAVR\prog\LED02フォルダを作ります。このフォルダの中に、前のLED01フォルダの中のmakefileとmc.batをコピーします。
makefileのプログラム名をLED02に変え、mc.batのディレクトリをLED02に変えます。上のテキストをえるの〜とに書き、LED02.cの名で
LED02フォルダに保存します。あと、コンパイルして、書き込みましょう。
実験2の回路に、タクトスイッチを付け、押された回数を8個のLEDに2進表示します。リセットスイッチは付けないので、電源の再投入で
リセットに変えます。回路図は次のようになります。
さて、実装ですが、データシートでは通常bit7が左で、右端にbit0があります。Tiny26Lは1番ピンを左下におくとAポートは逆順になります。
LEDの位置を変更して右がbit0になるようにしました。さらに正論理で点灯(1で点灯)するように変更しました。
スイッチ入力には、2つの点で注意が必要です。。
1つは、「押されているか」を判断すると、コンピュータは速いものですから、一瞬間押したつもりでもコンピュータにとっては長時間押し続け
られたことになり、何回もカウントされます。ここでは前回の状態を記憶して置いて、前回がoff、今回がonの時だけカウントするように
しました。
2つ目は、チャタリングです。機械的スイッチは動作の時、何回か接点でバウンドして落ち着きます。言い換えると、スイッチを入れたとき
(切ったときも)何回か高速でon/offを繰り返してからonになります。対策を立てないと一押しでいくつものカウントをします。
リストの中のチャタリング防止の部分を除いて実験したところ、以外にもタクトスイッチはチャタリングが少なく、時々起こる程度でした
(もちろん時々でも困る)。比較のために、リン青銅板を使って小学校の工作のようなスイッチを作ってみました。右の方にある金属板です。
こちらは期待通りチャタリングがありました。一押しでいくつもカウントします。「暴れているうち」は読みに行かないように20mSほど
ディレイ(時間稼ぎだけ)をかけました。簡易スイッチでも大丈夫になりました。20mSといえば1秒間に50回ですから人間の手入力では
読み飛ばしは起こらないでしょう。ディレイでなくタイマー割り込みで処理するのが本格派かもしれません。割り込みによる方法は別項
「LEDピコピコ(2313)」を参考にしてください。
プログラムリストを見てください。
LEDの2進表示は3ビット(0〜7)だと深く考えなくても数値が分かります。この程度の表示には簡単だし価値があるかも知れません。
7エレメントLED表示器に4桁の数字を表示します。 いろいろ欲張りますと、プログラムのポイントがぼやけますので、ここでは
表示の内容にこだわらないことにします。単純にループを回して数値をインクリメントしているだけです。
写真の表示器の部分は別の目的で作ったものを流用しました。表示器のリード取り出し口からブレッドボードまでのリード線を
今回のために取り付けました。表示器を使う実験には便利だと思っています。細かいことを考えないでブレッドボードに
接続できます。
余談ですが、セグメントのa,b,c・・をポート0,1,2・・に割り当てたり、7,6,5・・に割り当てたり小数点をbit7にしたり、bit0にしたりと
いろいろになっています。そして毎回セグメントの絵を描きながらリストに載せた「10000000」のような表を作っています。一般には
規則があるのかもしれませんが私は知りません。そのときの思いつきで自分で苦労を作っています。
今回はPA0〜PA7にa〜g,dpを割り当てています。小数点を点灯するときは、その桁の値から128(10進)を引いたものをポートに送ると
よいと言うことになります。
ここにプログラムを置きます。
ダイナミック点灯は、表示した桁に順次アノード電圧を加え、シンクロしてカソードに点灯したいセグメントに"L"を送ります。
桁移動の時にいちど消灯しないと余分に点灯して表示が見にくくなります。プログラム的には、 @はじめの桁にアノード電圧を
かける(A1015をonにするためにベースに"L"を加える)。 Aその桁の表示すべきセグメントに"L"を送ってダイオードを導通させる。
Bしばらく時間を待つ(waitルーチン)。 C桁ポートに"H"を送って消灯する。 桁を移動して@からCを繰り返す。
このサイクルが長いと(1秒間の回数が少ないと)ちらつきを感じます。waitルーチンを長くすると点灯サイクルが長くなります。
実験してみてください。
4桁のカウントは、それぞれ10進の変数を4つ使っています。int d; で一つの変数にしてもよいのですが、桁表示の時に、4桁の
BCDに変換する必要が生じます。別々の方が簡単なようです。時計の時には、10進と6進を組み合わせれば良いのですから。
1秒に1だけインクリメント=増やす(又はデクリメント=減らす)ように調整すればラーメンタイマができるでしょう。
Tiny26LにはADC(アナログ-ディジタル コンバータ)が11ポートあります。このポートを使って電圧を測定する実験をしました。このチップには2.56V
の基準電圧が用意されてますので、それを基準に電圧をディジタルに変換してみます。
ハードウエアは実験4の「7エレメントLED4桁表示」のものをそのまま使います。被測定電圧はVccとGNDに接続した1kΩB型バリオームの中点から取ることに
しました。バリオームの中点をそのままTiny26Lの8番ピンに接続しています。データシートでは、GND電位の時カウント0、2.56Vの時1023になるのですが、実際は
思うようにはなりませんでした。バリオームを回転するとLEDの表示が0から上がっていきます。表示が安定しないので少々イライラしますが、適当に回転を止めながら
手持ちのディジタルテスタでバリオームの電圧を測定しました。その結果が次のグラフです。
表示が安定しなくて、かなりふらつきます。大体のところ30mV位の誤差で0〜2.7Vまで読めそうです。表示が安定すると気持ちがいいのですが、原因探しと対策には
考えつくことがありません。
10V程度の電圧を0.1V単位で読めそうですからおおざっぱな電圧測定には使い道があるかもしれません。別項のニッケル水素電池充電器では同じ方法で電圧を検出して
予定の電圧が検出されたら充電を止めていますが、気に入って使っています。
電圧をディジタル変換する方法は次の通りです。
ハードウエアでは、ほとんどのピンがAD変換に使えるのですが、実験4でLEDを接続していない8番ピンを使いました。(後で、9番ピンを低電圧側につないで差動測定の
実験ができるように9番ピンは使いませんでした。)
ソフトでは4つのレジスタが関係しています。
@A/Dチャンネル選択レジスタ ADMUX
bit7:6 基準電圧の設定 "10"で内部2.56Vを選択し、17番ピン(AREF)と切り離します。17番ピンはLED表示に使います。
bit5 データの右/左揃え "0"で右揃えに設定します。
bit4:0 変換ポートの選択 "01000"でADC8を使うとします。
AA/D変換制御/ステータスレジスタ ADCSR
bit7 ADEN 変換許可ビット "1"で許可。
bit6 ADSC 変換開始 "1"で変換を始める。
bit5 ADFR 連続変換/単変換 "1"で連続指定
bit4 ADIF 割込フラグ 自動のため設定不要
bit3 ADIE 割込許可 "1"で許可する。
bit2:0 ADPS クロック選択 50〜200kHzが必要なため、分周比を決める。今は1MHzだから "011"で1/8に設定する。
BA/Dデータレジスタ上位 ADCH
10ビット変換だから上位は 1:0ビットだけ
CA/Dデータレジスタ下位 ADCL
下位の8ビットが入る。上位を読みとるとデータの更新が許可されるので、下位を先に上位を後で読み込まねばなりません。
プログラム作成で注意したところは
・ADC入力ピンをソフトウエアプルアップしてはいけません。うっかりしておかしな変換値に苦労しました。
・割込で処理しています。グローバル割込許可 sei(); が必要です。
・数値変数に 8,16,32ビットのものを使っています。代入時にはキャストが必要です。そうでないと動かない場合があります。
キャスト:臨時に型を変換すること。型を括弧でくくって変数の前に書きます。 nn=(int16_t)abc; abcを16ビット型と考え
て(として)代入せよ。
・カウントを2.725倍すると電圧になりますが、浮動小数点を良く知りませんので、109を掛けて40で割っています。そのために
32ビット変数を使いました。
プログラム
Tiny26LのADC機能を実験することと、使い方の一例を整理することを目的にこの項を書きました。思ったほどには精度や安定性が出なかったのは
残念でした。克服のためのノウハウがあると思うのですが知っている方がおられましたら教えていただきたいと思います。
この実験では素性の分かった電圧しか測定していないので良いのですが、入力端子がIOポート直接であることに注意が必要だと思います。また、
電源のGNDがどのように関係しているかはっきりしない状態では電池駆動にすべきでしょう。
別項「徒然なるままに」で述べたように2行×16文字の液晶は個別のLEDや7セグメントLED数字表示器に比べて多くの情報を少ないIOポートで表示すること
ができます。必要なポートはコントロールに2(R/Wを使わないので)と、データに4の合計6ポートです。これで16×2=32文字の数字・アルファベット・カタカナを
表示することができます。数値を表示したいときはもちろんですが、スイッチのon・offの状態やレジスタの状態を表示できるほかデバッグのための情報も表すことが
可能です。
そこで、これからのTiny26Lを使った回路に組み込みやすいLCDのブロックを作ろうと考えました。次の写真がその実験回路です。
コネクターは今までの14ピンから8ピンに変更しました。コントラスト調整の可変抵抗は基板ではなくLCD側に付けることにし、R/W端子はディレイで処理して、
データは4ビットで2回に分けて送ることにしますから8ピンで足りることになります。ピンの接続は次のようにしました。
@GND AVcc BRS CEN DD4 ED5 FD6 GD7
Tiny26Lの関係ポートは、portBには他の機能が多いのでportAを使うことにします。portAの0〜3をデータ4〜6に、portA4をRSに、portA5をENに使います。同時に、
実験がしやすいようにブレッドボード用コネクタを作りました。エナメル線を束ねて瞬間接着剤で固めてピンプラグに半田付けしただけですが端子の場所を思案しなくて
接続できます。ISP用のコネクタと同じ考えです。Tiny26Lの場合は同じ側に並びますので始末が良くなります。誤接続を防ぐために1番ピンにマジックインクで印を
付けています。
回路図は下のようになります。
ソフトウエアについて
LCDドライバは楠さんの作品を利用させていただいています。今回はTiny26Lの上に書いたポート
での仕様に一部変更しています。(WinAVR20050214対応のためlcd.cを修正しました。05.03.01)
必要な3つのファイルをここに置きます。 lcdtest.c lcd.c
lcd.h
ただし、このページのサーバには .h ファイルが登録できませんのでlcd.cはlcd.txtに変えてあります。使うときはlcd.hに拡張子を変更してください。
LCD表示をプログラムに組み込むときは次の点に注意します。
1 lcd.h と lcd.c の二つのファイルをプログラムファイルと同じフォルダに置きます。
2 makefileの 「SRC = $(TARGET).c 」のところを「SRC = $(TARGET).c lcd.c」と変更します(半角空白が入っています)。
3 プログラムの中に #include "lcd.h" を書き加えます。システムにないインクルードファイルは "" で囲むそうです。
4 プログラムの中に 初期設定の関数 lcd_init(); を書きます。
以上の手続きをとっておけば次の関数を使って液晶に自由に表示できます。
lcd_cls(); 表示クリア
lcd_gotopos(12,1); カーソル移動。12,1は12カラム2行目を示します。カラムは0から始まります。
lcd_putch(c); 1文字表示。引数はアスキーコードか文字変数。
lcd_putstr("LCD test"); 文字列の表示。引数は文字列または文字列変数のポインタ。
ここに書いたプログラムは表示以外の何もしていません。他の機能を付けると肝心なポイントがぼやけると考えました。ただ、何も動かないと面白くないので
数値を0から999までインクリメントし、それを表示することにしました。
ところが数値(intまたはlong)を文字列に変換しないと lcd_putstr(); が使えません。さて困った、どうしたらいいものか?webを探しました。sprintf()を
使えばよい、とありますがこれが見つからない(後でWINAVRにはないことがわかりました)。さらに探し続けて \WinAVR\doc\avr-libc\avr-libc-user-manual\index.html
のGeneral utilitiesの中に itoa() を見つけました。これぞ integer to ascii 文字に変換する関数です。他に ltoa() などもあります。
文法は?と見れば char * itoa (int __val, char *__s, int __radix) 半世紀前から苦手な英語をたどり何となくはわかったつもりになりましたが、アスタリスクの
ことをとんと忘れていました。次はアスタリスクとの戦いです。適当に入れても思うように動きません。そうだ実体がないとポインタの意味がないと気づいて
文字列用の配列を用意し、かつ、ポインタを設定しました。(後にポインタを設定しなくても良いことがわかり設定をやめました。配列名がポインタの働きをするようです)
これで思い通りの表示になりました。20年ほど前にDOSマシンで数値処理のプログラムを1本だけCで書い
たことがありましたが、すべて忘却の彼方になっていました。
プログラムのサイズは約400ワードですから、Tiny26Lの40%程使っています。26LのROM容量から考えると十分使えるのではないでしょうか。
コンパイル時の儀式を守ればプログラムの中では簡単に書けますから便利なものと思います。
変数名など常識に従っていないところは初心者ゆえご辛抱ください。
実験7 LEDをセンサとして使う
pn接合に光を与えると光電流が流れる。一般のトランジスタ・ダイオードは光が通らない構造になっていますが、LEDは光を通すので光りセンサとして使えないだろうか。
ChaNさんのページ「LEDを光センサとして使ってみる」に興味を引かれて手持ちのTiny26Lで試してみました。
これはChaNさんのページの追試です。
赤色のLEDをデジタルテスタで測定すると蛍光灯直下に置いたとき、あるいは明るい空に向けたときにおよそ1.3Vの電位差が示されました。これをAD変換して、電圧が生じてい
ると判断したときは明るいのでLEDを点灯しない。電位差が小さければ、暗いと判断してポートを出力に切り替えてLEDに電流を流し点灯する。1個のLEDが時分割でセンサと
光源の働きをします。ChaNさんのページの動画は良くできていて、LEDがひとつしかないのに、光をさえぎると点灯するのは何とも不思議な感じです。
いつもの、電源に0.1μFを付けたブレッドボードにTiny26Lを載せ、220ΩとLEDを差し込んで、プログラム書き込みようの端子をセットして実験に入りました。
左が照明を当てたとき、右が照明を消したときです。照明を当てた状態で、手で光を遮ると点灯します。
回路図はこの通り簡単です。
プログラムは、内蔵RC発振によるクロック1MHzとして、ウエイトルーチンはインラインアセンブラによる1msを試してみました。クロックを基準にしていますから
クロックが変わればウエイトタイムが変わることに注意が要ります。
ADC6と共通ピンのポートA7だけを使用しています。まずLを出力して浮遊容量などのチャージを放電してから、ピンを入力に切り替えADCの入力としてLEDの電位差を読みます。
もちろんのことですがこのときは入力をプルアップしてはいけません。以前にこれを知らずに苦労したことがありました。
変換命令の後、1msのウエイトを置いています。変換の時間を待たないと正しく変換しません。
変換データが所定の数値より小さい場合には光が遮られたと判断してLEDを10ms点灯します。数値が大きいときは時間を待たずに測定ルーチンに戻ります。
関係のレジスタは次の3つです。
ADMUXレジスタ:10100110 bit7:6で基準電圧を内部2.56V、bit5で左揃え、bit4:0でADC6(シングルエンド)選択を設定します。AD変換は10ビットですが、
詳しい数値は必要ないので、左揃えとして上位8ビットだけADCHから読み取っています。
ADCSRレジスタ:11010011 bit7=1変換許可、bit6=1変換開始、bit5=0単独変換(非連続変換)、bit4=1割込フラグ(無関係)、bit3=0割込禁止、
bit2:1=011変換クロック1/8分周。AD変換に200〜50kHzのクロックが必要です。メインクロックが1MHzなので1/8分周=125kHzとしています。
ADCHレジスタ:変換データの上位バイトですが左揃えをしていますので上位8ビットが書かれます。これを取り出して判断します。
光のスイッチ基準は計算では変換8ビット値が100程度になるのですが、実際の負荷状態でかなり変わるようです。蛍光管のすぐ近くに置けば計算どおりに
なりますが、少し離すとデータが小さくなります。結局20mV程度を示す8ビット値で2を判断基準としました。
手をかざすとLEDが点灯するので愛嬌ですが、実用にはどうでしょうか。何となく楽しいものです。
プログラム