The Weekly Herald

scie and axsee's electronics weblog.
<< 車載加速度アナログメータ1 | main | テトリス自作計画2 >>
スポンサーサイト このエントリーを含むはてなブックマーク

一定期間更新がないため広告を表示しています

| 書いた人:スポンサードリンク | - | | - | -
スロットマシーン2 このエントリーを含むはてなブックマーク
ハードウェア構成課題の、CPLDを使用したスロットマシーン。
その続き。
ハードウェアの構成は上図のようになっています。ボタンは押されるとLowになり、それ以外はHighになるようプルアップされています。レバーもボタンと同じ構造です。本物のスロットに近づけるために、今回はゲームスティックを使用しました。7セグメントLEDはスロットの数字表示用。レベルメータはスロットが回っている雰囲気を表現できるように、表示されている値に応じた番号のLEDが光ります。7セグもレベルメータもアノードコモン型で0で点灯、1で消灯となります。CPLDは外付けされた水晶発振器により7セグとレベルメータを更新していきます。ボタンが押されたらそのボタンに対応した7セグとレベルメータが停止し、3つとも止まった時、音楽がなるようにしたいと思っています。
開発段階はソフトウェア部分に入り、トランジスタ技術を読みながらVHDLを書いてみた。
ブロック図いきなりスロットマシーンのプログラムは難しいので、最初は“ボタンを押したらカウントアップして、7セグメントに値を表示する。10回ボタンが押されたら0に戻る”というのを作ってみた。
思ったより簡単で、ソフト嫌いのaxseeにも難なくできた。(というより、トラ技をまる写しした)
ロジックで書くとなかなか複雑な回路だが、VHDLでは簡単に出来たので
VHDLすげー
と思った。
ここまでは調子がよかったのだが、レバーを引くと7セグLEDの数字とレベルメータがカウントアップを開始する機能を作るのがなかなかできなかった。
さっき作ったプログラムのボタン入力のところに水晶発振器からのクロックを入力してみたのだが、うまくいかない。
VHDLを何度も見直しても、ミスが見当たらないのでハードウェアを確認すると、水晶発振が逆に刺さっていた・・・
すぐに直してみたが、残念ながら水晶発振器が再び発振することはなかった。

気を取り直してハードを修理し、無事動いたので次の段階へ。
ボタンを押したら止まるようにしようと思った。
問題は“ボタンを押している間、止まる”というのではなく、”一回押したらずっと止まっている”という機能の部分。
そんなのどうやるんだ?
状態遷移図アルゴリズムが想像できないまま、さらにトラ技を読み進めていくと、ちゃんと書いてありました。
トラ技によると状態遷移をステータスレジスタをつかって表現できるらしい。
ということで、状態遷移図を書いてみた。
そして、この構造でVHDLを書くと無事に自動で7セグとレベルメータが回り、ボタンを押したら止まるというスロットマシーンの基本が完成した。

さらに本物のスロットに近づけるために、スロットの回る速度を3つとも別の速度で回そうと思った。ブロック図◆水晶発振器のパルスをカウントし、一定カウントすると7セグLEDとレベルメータがカウントアップする。そのパルスカウンターの一定値をIF文で変えればいいだけなので、1分ぐらいで実装できると思ていた。
⇒(右のブロック図の構造でうまくいくと思った。)
が・・・

カウンタの値を変えてやってもなぜか同じ速度で回る。
そのときのソースの一部。
(水晶発振器の出力がCLKに繋がっている outA,B,Cの出力がLからHへ立ち上がったらスロットの値が進む)

process(CLK)
   begin
   if(CLK'event and CLK = '1') then
      if(count = 10000) then  --パルスカウンタが10000の時に
         outA <= not outA; --出力信号を変える
         count <= count + 1;
      elsif(count = 20000) then --中心のLEDは20000まで数える
         outB <= not outB;
         count <= count + 1;
      elsif(count = 30000) then
         outC <= not outC; --右は30000まで
         count <= 0;
      else
         count <= count + 1;
      end if;
   end if;
end process;


カウンターのずらし方気軽な気持ちで実装しようと決めたが、案外うまくいかない。
悩むこと30分・・・

scieの助言でこのソースでは一定間隔でパルスが出ることがやっと理解できた。
↑上の図はscieが説明してくれたカウント数とパルスの出るタイミングのグラフ
たしかに等間隔でパルスが出ています。
スロットのほうもよく見ると、少しずれて回っていた。

訂正したソース

process(CLK)
   begin
   if(CLK'event and CLK = '1') then
      if(count = 10000) then  --パルスカウンタが10000の時に
         outA <= not outA; --出力信号を変える
         outA <= not outB;
         outA <= not outC;

         count <= count + 1;
      elsif(count = 20000) then --中心のLEDは20000まで数える
         outA <= not outB;
         outB <= not outC;
         count <= count + 1;
      elsif(count = 30000) then
         outC <= not outC; --右は30000まで
         count <= 0;
      else
         count <= count + 1;
      end if;
   end if;
end process;


よーく考えたら当たり前だが、axseeはよくこういうミスで1日つぶしてしまうことがある。
注意不足を直すのも大切だが、たくさんプログラムを書いて多くの経験を積めば、こういうミスにもすぐ気がつくようになれそうと思った。
ブロック図あとはこのエンティティーを3つ並べて、数字がそろったら音楽が流れるようにした。
簡単に音楽をならすためにメロディーICを実装し、数字がそろったらメロディーICに電流が流れるようにした。

スロット3で完成したのがこちら。

blogに参加させてもらってから初の完成品です。
静止画では動きがお伝えできないので、動画もこちらにUPしてあります。よろしければご覧ください。

感想
マイコンを使えばスロットマシーンは簡単なプログラムで動かせそうですが、CPLD単体で作ると思ったより難しかった。
状態遷移などはマイコン、7セグデコーダなどはCPLDのほうが簡単に出来そうだと思った。
改めてマイコンのありがたみがわかった。
今度はマイコンとCPLDを組み合わせてお互いの長所をつかった何かを作ろうと思った。
| 書いた人:axsee | Embedded System | 01:42 | comments(0) | trackbacks(0)
スポンサーサイト このエントリーを含むはてなブックマーク
| 書いた人:スポンサードリンク | - | 01:42 | - | -
コメント
コメントする
※コメント欄にHTMLタグを使用することはできません。
※コメント欄内のURLは、自動的にリンクへと変換されます。
※英数字のみのコメントは投稿できません。









この記事のトラックバックURL
http://herald.jugem.jp/trackback/52
トラックバック
   1234
567891011
12131415161718
19202122232425
2627282930  
<< November 2017 >>


ブログ カウンター岩盤浴ゲルマニウム温浴