<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
   <channel>
      <title>dinop.com</title>
      <link>http://www.dinop.com/</link>
      <description></description>
      <language>ja</language>
      <copyright>Copyright 2007</copyright>
      <lastBuildDate>Mon, 01 Oct 2007 12:26:58 +0900</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

            <item>
         <title>MetaTrader 4で移動平均線を表示する</title>
         <description><![CDATA[
<a href="http://www.dinop.com/2007/09/29/ma01.gif" rel="lightbox"><img alt="ma01.gif" src="http://www.dinop.com/2007/09/29/ma01-thumb.gif" width="400" height="334" align="left" /></a>
移動平均線などのテクニカル指標は「Indicators」ボタンから追加できる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/ma02.gif" rel="lightbox"><img alt="ma02.gif" src="http://www.dinop.com/2007/09/29/ma02-thumb.gif" width="400" height="334" align="left" /></a>
MetaTrader 4には移動平均線やMACD、RSI、ボリンジャーバンド、ストキャスティック、一目均衡表．．．と様々なテクニカル指標が用意されている。また既存のテクニカル指標の改造やまったく独自のものを開発して登録することもできる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/ma03.gif" rel="lightbox"><img alt="ma03.gif" src="http://www.dinop.com/2007/09/29/ma03-thumb.gif" width="400" height="334" align="left" /></a>
移動平均線の追加は「Trend」にある「Moving Average」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/ma04.gif" rel="lightbox"><img alt="ma04.gif" src="http://www.dinop.com/2007/09/29/ma04-thumb.gif" width="400" height="334" align="left" /></a>
するとパラメーターを入力する画面が開く。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/ma05.gif" rel="lightbox"><img alt="ma05.gif" src="http://www.dinop.com/2007/09/29/ma05-thumb.gif" width="400" height="334" align="left" /></a>
とりあえず移動平均線を表示してみよう。「期間」を「21」に設定して「OK」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/ma06.gif" rel="lightbox"><img alt="ma06.gif" src="http://www.dinop.com/2007/09/29/ma06-thumb.gif" width="400" height="334" align="left" /></a>
これで移動平均線が表示された。図は1時間足のチャートのため21時間移動平均線となる。21日移動平均線に切り替えるにはツールバーの「D1」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma07.gif" rel="lightbox"><img alt="ma07.gif" src="http://www.dinop.com/2007/09/30/ma07-thumb.gif" width="400" height="334" align="left" /></a>
するとチャートが日足に切り替わり、移動平均線は21日平均となる。このように表示されているチャートの時間足単位と「期間」で設定した数値を利用して移動平均線が描画される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma08.gif" rel="lightbox"><img alt="ma08.gif" src="http://www.dinop.com/2007/09/30/ma08-thumb.gif" width="400" height="334" align="left" /></a>
さらにもう1本移動平均線を追加してみる。先ほどと同じようにツールバーの「Indicators」ボタンを押して現れるメニューにある「Trend」から「Moving Average」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma09.gif" rel="lightbox"><img alt="ma09.gif" src="http://www.dinop.com/2007/09/30/ma09-thumb.gif" width="400" height="334" align="left" /></a>
今回は「期間」を「90」に設定した。さらに線の色を指定するため「スタイル」欄の右にある下三角をクリックする。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma10.gif" rel="lightbox"><img alt="ma10.gif" src="http://www.dinop.com/2007/09/30/ma10-thumb.gif" width="400" height="334" align="left" /></a>
するとパレットが表示されるので利用したい色を指定する。今回は青色を選択した。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma11.gif" rel="lightbox"><img alt="ma11.gif" src="http://www.dinop.com/2007/09/30/ma11-thumb.gif" width="400" height="334" align="left" /></a>
これで「OK」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma12.gif" rel="lightbox"><img alt="ma12.gif" src="http://www.dinop.com/2007/09/30/ma12-thumb.gif" width="400" height="334" align="left" /></a>
すると青色の線で90日移動平均線が描かれた。
<br clear=left>




<a href="http://www.dinop.com/2007/09/30/ma13.gif" rel="lightbox"><img alt="ma13.gif" src="http://www.dinop.com/2007/09/30/ma13-thumb.gif" width="400" height="334" align="left" /></a>
次に表示中の移動平均線などのテクニカル指標のパラメーターを変更する。
「チャート」メニューにある「表示中の罫線分析ツール」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma14.gif" rel="lightbox"><img alt="ma14.gif" src="http://www.dinop.com/2007/09/30/ma14-thumb.gif" width="400" height="334" align="left" /></a>
すると表示中のテクニカル指標が一覧される。ここから「Moving Average」を選択して「編集」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma15.gif" rel="lightbox"><img alt="ma15.gif" src="http://www.dinop.com/2007/09/30/ma15-thumb.gif" width="400" height="334" align="left" /></a>
するとパラメーター設定画面が開く。ここで適用価格を「Simple」から「Exponential」に変更する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma16.gif" rel="lightbox"><img alt="ma16.gif" src="http://www.dinop.com/2007/09/30/ma16-thumb.gif" width="400" height="334" align="left" /></a>
今まで描画されていた移動平均線は単純移動平均のものだが、Exponentialにすることで指数移動平均となる。
設定したら「OK」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma17.gif" rel="lightbox"><img alt="ma17.gif" src="http://www.dinop.com/2007/09/30/ma17-thumb.gif" width="400" height="334" align="left" /></a>
もう1つの「Moving Average」を選択して「編集」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma18.gif" rel="lightbox"><img alt="ma18.gif" src="http://www.dinop.com/2007/09/30/ma18-thumb.gif" width="400" height="334" align="left" /></a>
こちらも適用価格を「Simple」から「Exponential」に変更する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma19.gif" rel="lightbox"><img alt="ma19.gif" src="http://www.dinop.com/2007/09/30/ma19-thumb.gif" width="400" height="334" align="left" /></a>
これで設定の変更が終わったので「閉じる」ボタンを押す。
<br>
ちなみに「削除」ボタンを使うと表示している移動平均線などのテクニカル指標を消すことができる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma20.gif" rel="lightbox"><img alt="ma20.gif" src="http://www.dinop.com/2007/09/30/ma20-thumb.gif" width="400" height="334" align="left" /></a>
すると表示されていた2本の移動平均線が最近の価格に重みを置いた指数平均移動線に切り替わる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma21.gif" rel="lightbox"><img alt="ma21.gif" src="http://www.dinop.com/2007/09/30/ma21-thumb.gif" width="400" height="334" align="left" /></a>
移動平均線などのテクニカル指標のパラメーター変更や削除はチャート画面からもできる。
変更や削除したいテクニカル指標の上で右クリックをする。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma22.gif" rel="lightbox"><img alt="ma22.gif" src="http://www.dinop.com/2007/09/30/ma22-thumb.gif" width="400" height="334" align="left" /></a>
そしてパラメーターの変更をしたいときは現れたメニューから「プロパティー」を、削除したいときは「分析ツールを削除」を選択する。
ここでは「分析ツールを削除」を選択した。
<br clear=left>

<a href="http://www.dinop.com/2007/09/30/ma23.gif" rel="lightbox"><img alt="ma23.gif" src="http://www.dinop.com/2007/09/30/ma23-thumb.gif" width="400" height="334" align="left" /></a>
これで移動平均線が1本消えた。
右クリックによるパラメーターの変更や削除は、クリック位置がシビアなためうまく操作できないことがある。そのようなときは素直に「チャート」メニューにある「表示中の罫線分析ツール」を利用した方がいいだろう。
<br clear=left>

]]></description>
         <link>http://www.dinop.com/fx_trade/metatrader_4_movingaverage_basic.html</link>
         <guid>http://www.dinop.com/fx_trade/metatrader_4_movingaverage_basic.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">自動売買でFX</category>
        
        
         <pubDate>Mon, 01 Oct 2007 12:26:58 +0900</pubDate>
      </item>
            <item>
         <title>MetaTrader 4の基礎的なチャート操作</title>
         <description><![CDATA[<a href="http://www.dinop.com/2007/09/29/WS22.gif" rel="lightbox"><img alt="WS22.gif" src="http://www.dinop.com/2007/09/29/WS22-thumb.gif" width="400" height="334" align="left" /></a>
MetaTrader 4の左側「気配値表示」の中からチャートを表示したい通貨ペアを探し、右クリックする。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS23.gif" rel="lightbox"><img alt="WS23.gif" src="http://www.dinop.com/2007/09/29/WS23-thumb.gif" width="400" height="334" align="left" /></a>
そして現れたメニューから「チャート表示」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS24.gif" rel="lightbox"><img alt="WS24.gif" src="http://www.dinop.com/2007/09/29/WS24-thumb.gif" width="400" height="334" align="left" /></a>
これでウインドウが開く。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS25.gif" rel="lightbox"><img alt="WS25.gif" src="http://www.dinop.com/2007/09/29/WS25-thumb.gif" width="400" height="334" align="left" /></a>
そしてしばらく待つとチャートが表示される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS26.gif" rel="lightbox"><img alt="WS26.gif" src="http://www.dinop.com/2007/09/29/WS26-thumb.gif" width="400" height="334" align="left" /></a>
タイトルバーの部分をダブルクリックする。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS27.gif" rel="lightbox"><img alt="WS27.gif" src="http://www.dinop.com/2007/09/29/WS27-thumb.gif" width="400" height="334" align="left" /></a>
少しは大きく表示される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS28.gif" rel="lightbox"><img alt="WS28.gif" src="http://www.dinop.com/2007/09/29/WS28-thumb.gif" width="400" height="334" align="left" /></a>
チャートを1分足に切り替えたいときは「M1」ボタンを押せばいい。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS29.gif" rel="lightbox"><img alt="WS29.gif" src="http://www.dinop.com/2007/09/29/WS29-thumb.gif" width="400" height="334" align="left" /></a>
「M1」は1分足、「M5」は5分足、「M15」は15分足、「M30」は30分足、「H1」は1時間足、「H4」は4時間足、「D1」は日足、「W1」は週足、「MN」は月足をそれぞれ示す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS31.gif" rel="lightbox"><img alt="WS31.gif" src="http://www.dinop.com/2007/09/29/WS31-thumb.gif" width="400" height="334" align="left" /></a>
チャート表示をロウソク足に切り替えたいときは「Candlesticks」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS34.gif" rel="lightbox"><img alt="WS34.gif" src="http://www.dinop.com/2007/09/29/WS34-thumb.gif" width="400" height="334" align="left" /></a>
チャートが小さすぎて分かりずらいので「＋」ボタンで拡大表示する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS36.gif" rel="lightbox"><img alt="WS36.gif" src="http://www.dinop.com/2007/09/29/WS36-thumb.gif" width="400" height="334" align="left" /></a>
「Bar Chart」ボタンでは図のようなカギ足で表示される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS38.gif" rel="lightbox"><img alt="WS38.gif" src="http://www.dinop.com/2007/09/29/WS38-thumb.gif" width="400" height="334" align="left" /></a>
「Line Chart」ボタンでは文字通り1本の線で結んだチャートとなる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS40.gif" rel="lightbox"><img alt="WS40.gif" src="http://www.dinop.com/2007/09/29/WS40-thumb.gif" width="400" height="334" align="left" /></a>
縮小表示したいときは「－」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS41.gif" rel="lightbox"><img alt="WS41.gif" src="http://www.dinop.com/2007/09/29/WS41-thumb.gif" width="400" height="334" align="left" /></a>
拡大や縮小などの操作をするとチャートの描画位置が若干ずれるときがある。このような場合はチャート上をドラッグする。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS42.gif" rel="lightbox"><img alt="WS42.gif" src="http://www.dinop.com/2007/09/29/WS42-thumb.gif" width="400" height="334" align="left" /></a>
これで右側の隙間がなくなりチャートがきちんと表示された。
<br clear=left>

]]></description>
         <link>http://www.dinop.com/fx_trade/metatrader_4_basic_chart.html</link>
         <guid>http://www.dinop.com/fx_trade/metatrader_4_basic_chart.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">自動売買でFX</category>
        
        
         <pubDate>Sat, 29 Sep 2007 18:07:21 +0900</pubDate>
      </item>
            <item>
         <title>MetaTrader 4のインストール方法</title>
         <description><![CDATA[<a href="http://www.dinop.com/2007/09/29/WS00.gif" rel="lightbox"><img alt="WS00.gif" src="http://www.dinop.com/2007/09/29/WS00-thumb.gif" width="400" height="334" align="left" /></a>
MetaTrader 4は無料で利用できるチャートソフトだ。複数の通貨ペアのチャートを同時に開くこともできる。拡張性もあり動作も軽快で使いやすい。インストールしていて損のないソフトだ。
<br>
まずはMetaTrader 4をダウンロードする。
<a href="http://www.metaquotes.net/downloads" target="_blank">http://www.metaquotes.net/downloads</a>にアクセスし、「MetaTrader t Client Terminal (Windows 98,Me,XP,2000)」と書かれている本文の中にあるリンクをクリックする。<br>
残念ながら現バージョンはWindows Vistaに対応していない。そのため私はVirtual PC上のWindows 2000でMetaTrader 4を利用している。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS01.gif" rel="lightbox"><img alt="WS01.gif" src="http://www.dinop.com/2007/09/29/WS01-thumb.gif" width="400" height="334" align="left" /></a>
リンクをクリックすると「ファイルのダウンロード」ウインドウが開く。
ここで「このプログラムをディスクに保存する」を選択して「OK」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS02.gif" rel="lightbox"><img alt="WS02.gif" src="http://www.dinop.com/2007/09/29/WS02-thumb.gif" width="400" height="334" align="left" /></a>
今回は保存先として「デスクトップ」を選択した。保存先を決めたら「OK」ボタンを押す。
<br clear=left>


<a href="http://www.dinop.com/2007/09/29/WS03.gif" rel="lightbox"><img alt="WS03.gif" src="http://www.dinop.com/2007/09/29/WS03-thumb.gif" width="400" height="334" align="left" /></a>
するとダウンロードが開始される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS04.gif" rel="lightbox"><img alt="WS04.gif" src="http://www.dinop.com/2007/09/29/WS04-thumb.gif" width="400" height="334" align="left" /></a>
しばらくするとデスクトップ上に「mt4setup」というアイコンができる。これをダブルクリックする。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS05.gif" rel="lightbox"><img alt="WS05.gif" src="http://www.dinop.com/2007/09/29/WS05-thumb.gif" width="400" height="334" align="left" /></a>
するとMetaTrader 4のセットアップ画面が開く。
<br>
．．．しかしきちんと作られていないからなのか文字が読めない状態になってしまっている。問題ないのでとりあえず気にせずに「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS06.gif" rel="lightbox"><img alt="WS06.gif" src="http://www.dinop.com/2007/09/29/WS06-thumb.gif" width="400" height="334" align="left" /></a>
さらに「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS07.gif" rel="lightbox"><img alt="WS07.gif" src="http://www.dinop.com/2007/09/29/WS07-thumb.gif" width="400" height="334" align="left" /></a>
そしてライセンス条項を読み「はい。全てのライセンス条項に同意します。」のチェックを入れて「次へ」ボタンで進む。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS08.gif" rel="lightbox"><img alt="WS08.gif" src="http://www.dinop.com/2007/09/29/WS08-thumb.gif" width="400" height="334" align="left" /></a>
そのまま「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS09.gif" rel="lightbox"><img alt="WS09.gif" src="http://www.dinop.com/2007/09/29/WS09-thumb.gif" width="400" height="334" align="left" /></a>
そのまま「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS10.gif" rel="lightbox"><img alt="WS10.gif" src="http://www.dinop.com/2007/09/29/WS10-thumb.gif" width="400" height="334" align="left" /></a>
そのまま「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS11.gif" rel="lightbox"><img alt="WS11.gif" src="http://www.dinop.com/2007/09/29/WS11-thumb.gif" width="400" height="334" align="left" /></a>
これでMetaTrader 4のインストールが開始される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS12.gif" rel="lightbox"><img alt="WS12.gif" src="http://www.dinop.com/2007/09/29/WS12-thumb.gif" width="400" height="334" align="left" /></a>
しばらくしてインストールが終わったら「終了」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS13.gif" rel="lightbox"><img alt="WS13.gif" src="http://www.dinop.com/2007/09/29/WS13-thumb.gif" width="400" height="334" align="left" /></a>
これでMetaTrader 4が自動的に起動する。初回起動時は登録画面が開く（2回目以降の起動時には登録画面は開かない）。
ここでは住所や名前、電話番号などを問われる。これらは無料で利用できるデモ口座用の登録情報になる。クレジットカードの情報や実際の'現金'は必要ないのでそのまま入力する。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS14.gif" rel="lightbox"><img alt="WS14.gif" src="http://www.dinop.com/2007/09/29/WS14-thumb.gif" width="400" height="334" align="left" /></a>
ここでは簡易のため「aaa」のように書き込んでいるが、実際にはローマ字表記できちんと書き込む。
<br>
「証拠金」欄はデモ口座に入金する仮想マネーの金額設定になる。標準は5000ドルだが、ここではきりのいいところで1000ドルを指定した。「貴社からのニュースレター受け取りに同意します。」にチェックを入れて「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS15.gif" rel="lightbox"><img alt="WS15.gif" src="http://www.dinop.com/2007/09/29/WS15-thumb.gif" width="400" height="334" align="left" /></a>
さらに「次へ」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS16.gif" rel="lightbox"><img alt="WS16.gif" src="http://www.dinop.com/2007/09/29/WS16-thumb.gif" width="400" height="334" align="left" /></a>
すると住所などの登録情報が送信される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS17.gif" rel="lightbox"><img alt="WS17.gif" src="http://www.dinop.com/2007/09/29/WS17-thumb.gif" width="400" height="334" align="left" /></a>
そしてしばらくするとデモ口座用のパスワードなどが取得される。これらは自動的にMetaTrader 4に保存されるので、メモしておく必要はない。最後に「完了」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS18.gif" rel="lightbox"><img alt="WS18.gif" src="http://www.dinop.com/2007/09/29/WS18-thumb.gif" width="400" height="334" align="left" /></a>
これでMetaTrader 4の準備が整うと同時に画面上にEURUSD、GBPUSD、USDCHF、USDJPYの4通貨ペアのチャートが表示される。このチャートは市場が開いている時間帯（月曜早朝～土曜早朝まで）であればリアルタイムに更新される。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS19.gif" rel="lightbox"><img alt="WS19.gif" src="http://www.dinop.com/2007/09/29/WS19-thumb.gif" width="400" height="334" align="left" /></a>
とりあえずチャートは必要ないので「×」ボタンで閉じる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS20.gif" rel="lightbox"><img alt="WS20.gif" src="http://www.dinop.com/2007/09/29/WS20-thumb.gif" width="400" height="334" align="left" /></a>
さらに「×」ボタンで閉じる。
<br clear=left>

<a href="http://www.dinop.com/2007/09/29/WS21.gif" rel="lightbox"><img alt="WS21.gif" src="http://www.dinop.com/2007/09/29/WS21-thumb.gif" width="400" height="334" align="left" /></a>
これでチャートを全部閉じた。
<br clear=left>
]]></description>
         <link>http://www.dinop.com/fx_trade/metatrader_4_install.html</link>
         <guid>http://www.dinop.com/fx_trade/metatrader_4_install.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">自動売買でFX</category>
        
        
         <pubDate>Sat, 29 Sep 2007 16:33:54 +0900</pubDate>
      </item>
            <item>
         <title>現在利用している完全自動売買ソフトのメリットとデメリット</title>
         <description><![CDATA[2007年8月27日から完全自動売買によりFX取引を始めました。

巷にはチャートトレーダーやMetaTrader4などの自動売買対応ソフトがありますが、それらは利用せずに自分で作成しました。理由はインターネット接続環境です。光ファイバーやADSLなどの常時接続環境であればチャートトレーダーのように自分のPC上から取引するソフトを利用する（かもしれない）のですが、私はPHSによるダイヤルアップ接続です（DoCoMoの@FreeD）。

PHSですから接続はブチブチ切れますし、自動的に再接続するように設定していても数十分に渡ってきちんと再接続できないことが多々あります。そのためPC上で動作するソフトではログイン状態が切れて手動で再接続＆自動売買スタートという手順を踏まなければならないことになります。

せっかくの自動売買にも関わらず手動で再接続をしないといけないのは非常に面倒、というよりも論外です。
<br>

そのため自動売買ソフトはPerlで作成して、レンタルサーバー上に設置（このホームページ上です）、Cron設定により6分に一度FX取引会社にアクセスしてレートの取得および新規注文や決済注文、注文取消しなどを行っています。
<br>
<br>
私が利用しているPerlによる自動売買ソフトのメリットとデメリットは以下のようです。

【メリット】
・電気代がかからない（PCの電気代はレンタルサーバー会社持ちですから）
・家が停電になっても問題なし（レンタルサーバー会社が落ちたらNGですが）
・携帯電話で制御できる（ホームページから自動注文の停止／再開や状況確認できるようにしています）

【デメリット】
・リアルタイムなレートを取得できない（一定間隔ごとにレートを取得しないといけないためです）
・過去のレートを取得できない（取引会社は残念ながら過去のレートを提供していません）（※）
・平均線などのテクニカル指標はすべて自分で計算しないといけない
・FX取引会社がシステムを更新したら自動売買ソフトが動かなくなる恐れがある
・ソフトをすべて自分で作らないといけない
<br>
<br>
特にデメリットが大きいです。

過去のレートは<a href="http://www.forexite.com/free_forex_quotes/forex_history_arhiv.html" target="_blank">http://www.forexite.com/</a>などのサイトから取得できます。しかしこれらのサービスで取得できるレートはFX取扱会社が提供するレートとは数pips異なる値になっていることが多いです。そのため正確な過去のレートを参照したい場合は、そのFX取扱会社からなんらかの方法（チャート図の解析など）を利用して取得する必要があります。

また、ホームページが一新されて、注文手順が変更になったりしたら．．．きちんと自動売買ソフトが動かなくなるというトラブルも考えられますし、かなりリスキーです。

そのため、自動売買ソフトに想定外のトラブルが生じた場合は携帯電話に状況をメールを送信。携帯電話から自動売買の状況や注文取消し、自動売買機能の停止／再開などの指示ができるようにしています。これにより（携帯電話が圏外でなければ）多少トラブルが生じても大丈夫なようにしています。
]]></description>
         <link>http://www.dinop.com/fx_trade/autofx_merit_demerit.html</link>
         <guid>http://www.dinop.com/fx_trade/autofx_merit_demerit.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">自動売買でFX</category>
        
        
         <pubDate>Tue, 28 Aug 2007 17:27:25 +0900</pubDate>
      </item>
            <item>
         <title>完全自動売買向けFX取引会社の選び方</title>
         <description><![CDATA[最近は自動売買機能を用意しているFX取引会社が増えてきました。特にFXA証券の「チャートトレーダー」などはまったくの初心者でもソフトを起動して数クリックするだけで自動売買が開始されるほどの簡単さです。

完全自動売買をするためのFX取引会社を選ぶときは、自動売買サービスが整っているところを選ぶのがいいかもしれません。サザインベストメントやFXA証券などです。しかし、私の場合はFX取引会社が提供している自動売買機能は利用せずに、自分で自動売買ソフトを作ることが前提でした。そのため．．．

・取引がHTMLベースで行えること（取引に専用ソフトやJava、Frashなどを利用していない）

という条件が必須でした。多くのFX取引会社が発注やレート表示に専用ソフトもしくはJavaを利用しています。しかし携帯電話の取引サービスを行っている会社は（iアプリなどJavaの場合もありますが）、多くは完全にHTMLベースでサービスを提供しています。そのため私は携帯電話に対応しているFX取引会社を第一条件にしました。
<br>
<br>


さらに一般的なFX取引のときと同じような条件があります。

・手数料とスプレッドの合計額が少ないこと
・システムが安定していること。

スプレッドが小さくても手数料が多い場合はNGです。手数料無料＆スプレッド1を謳う会社や手数料無料＆スプレッド2固定というFX取引会社もあります。しかし実際の提供スプレッドを見てみるとスプレッド1や2のように小さいことは少なく、スプレッド8のように広がることも多いため気をつけないとダメなようです。

また、普段は注文がスムーズに通っていても、急激な円高や円安のときに突然ログインできなくなったり注文が通らなくなるトラブルがあるそうです。儲ける側に値動きした場合だったらまだいいのですが、損する側に動いたときに注文ができず、損失が拡大するとなると笑えません。

パンタレイ証券はUSD/JPYでスプレッド1ということです。実際に1になることも多いのですが、平均的には2から3ぐらいでしょうか？システムが不安定という話を耳にします。

FXA証券はUSD/JPYでスプレッド2固定のようですが、証券会社内のスプレッドは変動しているようで（平均スプレッドは5程度？）、約定しないなどのケースが多く、システムも不安定なようです。（デモ口座はライブ口座とは注文の受け付け方が大きく違うようです）

私が採用したGMOインターネット証券はUSD/JPYでスプレッド2～ということですが、実際にはスプレッド2になることはほとんどなく、スプレッド3以上と考えた方がいいようです。

これから選ぶならUSD/JPYはスプレッド3固定で自動売買サービスも提供中、さらにシステムも安定している（という噂の）サザインベストメントがいいかもしれません。
<br>
<br>



ちなみに私はFXA証券（のデモ口座）とJNB-FX、GMO-FXを利用しました（利用しています）。

JNB-FXはコストが非常に高いです。しかしジャパンネットバンクの口座を持っているのなら書類申請など必要なく、数分あれば口座開設から実際の取引までできる手軽さがあります。初めて取引をしたのはここでした。

FXA証券は当初完全自動売買ソフトを作成した会社で、今でもデモ口座＋チャートトレーダーを利用しています。デモ口座だからなのかもしれませんが、すでに決済したポジションやすでに取り消した注文が表示されたままになったり、保持ポジションの損益額がずっと同じ値できちんと計算されないなど、バグが目立ちます。デモ口座＋仮想マネーなので気になりませんが、（少なくとも私は）実際の現金を利用して取引する気にはなれません。

GMO-FXはブラウザーベースの取引ができますが、立ち上げてから実際の取引までが煩雑です。ログインページを開いてパスワードなどを入力、ログインしたらFX画面に切り替えて、チャートを開く．．．という操作になります。チャートもJavaベースなので使い勝手が悪いため利用していません（そのためチャートはFXA証券のチャートトレーダーで表示しています）。
]]></description>
         <link>http://www.dinop.com/fx_trade/fx_select_dealer.html</link>
         <guid>http://www.dinop.com/fx_trade/fx_select_dealer.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">自動売買でFX</category>
        
        
         <pubDate>Tue, 28 Aug 2007 16:27:37 +0900</pubDate>
      </item>
            <item>
         <title>PSoCでSDカードにGPSログを取りつつNikon D200へ位置情報を送る</title>
         <description><![CDATA[<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_01.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_01.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_01-thumb.gif" width="400" height="326" align="left" /></a>
今回は「<a href="http://www.dinop.com/elec/psoc_sdcard_gps_log.html" target="_blank">PSoCでSDカードにGPSログを保存する</a>」で作成したプロジェクトをさらに拡張して、デジカメ「Nikon D200」から電源を取り、Nikon D200での撮影画像内に位置情報が記録されるようにする。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_02.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_02.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_02-thumb.gif" width="400" height="326" align="left" /></a>
前回はGPSから受信したデータをSDカードに保存するのみだった。今回は受信データをさらにNikon D200へ送信するので、送信用のモジュールをプロジェクトに追加する。
前回作成したプロジェクトを開いたら、「Design Editor」の「Selection」画面を開き、「Digital Comm」にある「TX8」を右クリックして現れるメニューから「Select」を選択して追加する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_03.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_03.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_03-thumb.gif" width="400" height="326" align="left" /></a>
「TX8_1」のアイコンが追加されたら、そのアイコンを右クリックした現れるメニューから「Rename」を選択して名前を「TX8」に変更しておく。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_04.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_04.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_04-thumb.gif" width="400" height="326" align="left" /></a>
Nikon D200ではGPSが接続されている間は半押しタイマーが無効になる。半押しタイマーが無効になると露出系が常時作動した状態になるため、電池消耗が激しくなる。普段は24時間電源を入れっぱなしでも問題ないデジカメだが、半押しタイマーが無効になった状態では一晩置いただけで電池が空になり、メモリーカードの残撮影枚数すら表示されなくなる。
そのため自動的にGPS信号をデジカメへ送らないようにするためのタイマーを作るため、先ほどと同様に「Counters」にある「Counter16」を追加する。名前も「Counter16_1」から「Counter16」に変えておく。
ちなみに半押しタイマーの無効化はスピードライト用のシューに機器を接続したときにも起きる。Nikon D200を水中で使うためのハウジングに電源をONにしたまま入れて放置しておいたら完全に電源が切れてしまい、撮影ができなくなったことがある。半押しタイマー無効の挙動は困ったものだ。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_05.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_05.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_05-thumb.gif" width="400" height="326" align="left" /></a>
モジュールの追加が済んだら「Interconnect」画面に切り替える。そして「Counter16」を右クリックして現れるメニューから「Place」を選択して配置する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_06.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_06.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_06-thumb.gif" width="400" height="326" align="left" /></a>
そして「Clock」を「CPU_32_KHz」に、
「Enable」を「High」に、
「CompareOut」を「None」に、
「TerminalCountOut」を「None」に、
「Period」を「30000」に、
「CompareType」を「Less Than Or Equal」に、
「InterruptType」を「Compare True」に、
「ClockSync」を「Sync to SysClk」にする。これでおおよそ1秒（0.92秒ぐらい）ごとに割り込みが起きるようになる。この割り込みを利用してタイマーを作る。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_07.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_07.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_07-thumb.gif" width="400" height="326" align="left" /></a>
次に「TX8」を右クリックして現れるメニューから「Place」を選択して配置する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_08.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_08.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_08-thumb.gif" width="400" height="326" align="left" /></a>
そして「Clock」を「VC3」に、
「Output」を「Row_1_Output_1」に、
「TX Interrupt Mode」を「TXRegEmpty」に、
「ClockSync」を「Sync to SysClk」に、
「Data Clock Out」を「None」にする。さらに内部配線図でTX8の出力がポート01に接続されるようにする。

<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_09.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_09.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_09-thumb.gif" width="400" height="326" align="left" /></a>
次にポート14の「Drive」を「Open Drain Low」に、「Interrupt」を「RisingEdge」に設定しておく。
このポート14にNikon D200からのVcc端子を接続しておく。Vcc端子はデジカメの半押しタイマーが作動している間のみHighになる。Highになったことを検出してGPS信号をNikon D200へ送り込むようにする。GPS信号を送り始めると半押しタイマーが無効になり、Vcc端子がHighのままになり続ける。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_10.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_10.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_10-thumb.gif" width="400" height="326" align="left" /></a>
モジュール設定が済んだら、「Application Editor」画面に切り替えて、まず「main.c」の内容を修正する。
<br clear=left>
<pre class=SourceCode>//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include &lt;m8c.h&gt;        // part specific constants and macros
#include &quot;PSoCAPI.h&quot;    // PSoC API definitions for all User Modules

#include &quot;stdlib.h&quot;

//#define	_DEBUG

int		g_nCount;
BOOL	g_bTx;

#pragma interrupt_handler COUNT16_INT
void COUNT16_INT(void)
{
	g_nCount++;
	if(g_nCount &gt;= 60)
	{
		Counter16_Stop();
		g_bTx = FALSE;
		TX8_Stop();
	}

	#ifdef	_DEBUG
		LCD_Position(0,0);
		LCD_PrHexInt(g_nCount);
	#endif
}

#pragma interrupt_handler GPIO_INT
void GPIO_INT(void)
{
	if(PRT1DR &amp; 0x10)
	{
		//D200 semi-release, so timer start/restart
		#ifdef	_DEBUG
			LCD_Position(0,0);
			LCD_PrHexInt(g_nCount);
		#endif
		g_nCount = 0;
		g_bTx = TRUE;
		Counter16_Start();
		TX8_Start(TX8_PARITY_NONE);
		#ifdef	_DEBUG
			LCD_PrCString(&quot;ok&quot;);
		#endif
	}
}





// Can not retreave last data of CSV
BOOL	GetCSVData(char* pszCSV,int nIndex,char** ppszStart,char** ppszEnd)
{
	int		i;
	int		nFind;

	if(nIndex &lt; 0)
		return	FALSE;

	*ppszStart = pszCSV;
	*ppszEnd = pszCSV;
	nFind = 0;
	i = -1;
	while(1)
	{
		i++;
		if(pszCSV[i] != ',')
			continue;

		nFind++;

		if(nFind == nIndex)
			*ppszStart = &amp;(pszCSV[i+1]);
		if(nFind == nIndex + 1)
		{
			*ppszEnd = &amp;(pszCSV[i-1]);
			return	TRUE;
		}
	}

	return	FALSE;
}




BOOL	IsFileExist(char* pszFileName)
{
	char	fp;

	fp = SDCard_fopen(pszFileName,&quot;r&quot;);
	if(fp &gt; SDCard_MAXFILES)			// != SDCard_MAXFILES
		return	TRUE;
//	if(fp == SDCard_MAXFILES || SDCard_ferror(fp) &amp; 0x02)	//check error flag of &quot;File not found.&quot;
	if(fp == SDCard_MAXFILES)
	{
		SDCard_fclose(fp);
		return	FALSE;
	}
	if(SDCard_GetFileSize(fp) == 0)		//File is empty.
	{
		SDCard_fclose(fp);
		return	FALSE;
	}
	SDCard_fclose(fp);

	return	TRUE;
}



BOOL	OpenSDCardFile(char* pfp,char* pszFileName)
{
	int	i;

	for(i = 0; i &lt; 2; i++)
	{
		BYTE	ret;

		*pfp = SDCard_fopen(pszFileName,&quot;a&quot;);
		#ifdef	_DEBUG
			LCD_Position(2,0);
			LCD_PrCString(&quot;fp:&quot;);
			LCD_PrHexByte(*pfp);
		#endif
		if(*pfp &lt; SDCard_MAXFILES)			// != SDCard_MAXFILES
			return	TRUE;

		ret = SDCard_ferror(*pfp);
		SDCard_fclose(*pfp);

		#ifdef	_DEBUG
			LCD_Position(1,4);
			LCD_PrCString(&quot;error         &quot;);
			LCD_Position(1,10);
			LCD_PrHexByte(ret);
		#endif
	}

	return	FALSE;
}


BOOL	CreateFileName(char* pszRMCData,char* pszFileName)
{
	//LOG file is not open, so make file name and open...
	//file name is &quot;ayymmdda.txt&quot; to &quot;zyymmdda.txt&quot;

	int		j;
	int		k;
	char*	pszStart;
	char*	pszEnd;
	BOOL	ret;

	//file name is made from date, and date data is only in RMC data.
	if(!(pszRMCData[3] == 'R' &amp;&amp; pszRMCData[4] == 'M' &amp;&amp; pszRMCData[5] == 'C'))
		return	FALSE;

	//Get date from RMC data.
	ret = GetCSVData(pszRMCData,9,&amp;pszStart,&amp;pszEnd);
	if(ret == FALSE || pszStart == pszEnd || pszEnd - pszStart &lt; 5)
		return	FALSE;

	pszFileName[1] = pszStart[4];	//year
	pszFileName[2] = pszStart[5];
	pszFileName[3] = pszStart[2];	//month
	pszFileName[4] = pszStart[3];
	pszFileName[5] = pszStart[0];	//day
	pszFileName[6] = pszStart[1];

	pszFileName[8]  = '.';
	pszFileName[9]  = 't';
	pszFileName[10] = 'x';
	pszFileName[11] = 't';
	pszFileName[12] = 0;


	for(j = 0; j &lt; 26; j++)
	{
		pszFileName[0]  = 'a' + j;
		for(k = 0; k &lt; 26; k++)
		{
			pszFileName[7]  = 'a' + k;

			ret = IsFileExist(pszFileName);
			if(ret == FALSE)
				return	TRUE;
		}
	}

	return	FALSE;
}




void main()
{  
	char	fp;

	g_bTx = FALSE;

	// make Port16 to &quot;strong&quot; for LED
	PRT1DM0 |= 0x40;
	PRT1DM1 &amp;= ~0x40;
	PRT1DM2 &amp;= ~0x40;

	// make Port15 to &quot;pull-down&quot; for input sw
	PRT1DM0 &amp;= ~0x20;
	PRT1DM1 &amp;= ~0x20;
	PRT1DM2 &amp;= ~0x20;

	#ifdef	_DEBUG
		LCD_Start();
	#endif

	SDCard_Start();
	{
		char   cardInfo;                      // Card information  

		SDCard_Select(SDCard_ENABLE); // Select card  
		cardInfo = 0;  
		while ( ! cardInfo )          // Wait for card to communicate  
		{
			cardInfo = SDCard_InitCard();
		}
	}

	RX8_Start(RX8_PARITY_NONE);
	RX8_DisableInt();
	TX8_Start(TX8_PARITY_NONE);
	TX8_DisableInt();
	Counter16_EnableInt();

	M8C_EnableGInt;
	M8C_EnableIntMask(INT_MSK0,INT_MSK0_GPIO);

	PRT0DR &amp;= ~0x02;		//Port01 is LOW (for TX8)
	fp = SDCard_MAXFILES;
	while(1)
	{
		int		i;
		int		nLen;
		char	pszBuff[160];

		i = 0;
		while(1)
		{
			while ( !(RX8_bReadRxStatus() &amp; (RX8_RX_COMPLETE | RX8_RX_NO_ERROR)))
			{
			}
			pszBuff[i] = RX8_bReadRxData();
			if(g_bTx)
				TX8_SendData(pszBuff[i]);			//ignore tx buffer empty flag
			if(pszBuff[i] == '\n' &amp;&amp; i &gt; 0 &amp;&amp; pszBuff[i-1] == '\r')
				break;
			i++;
			if(i &gt;= 158)
				i = 0;
		}
		//pszBuff[i+1] = NULL;
		nLen = i + 1;

		if(!(pszBuff[0] == '$' &amp;&amp; pszBuff[1] == 'G' &amp;&amp; pszBuff[2] == 'P'))
			continue;

		for(i = 0; i &lt;= nLen-3; i++)		//pszBuff[nLen-2]=='\r' pszBuff[nLen-1]=='\n'
		{
			if(pszBuff[i] &lt; 0x20 || pszBuff[i] &gt;= 0x7f)
				break;
		}
		if(i != nLen-2)
			continue;

		if(!((pszBuff[3] == 'G' &amp;&amp; pszBuff[4] == 'G' &amp;&amp; pszBuff[5] == 'A')
			|| (pszBuff[3] == 'R' &amp;&amp; pszBuff[4] == 'M' &amp;&amp; pszBuff[5] == 'C')))
			continue;

		if(fp == SDCard_MAXFILES)
		{
			BOOL	ret;
			char	pszFileName[13]; 	 //File name is 8.3 format

			ret = CreateFileName(pszBuff,pszFileName);
			if(ret == FALSE)
			{
				fp = SDCard_MAXFILES;
				continue;
			}

			#ifdef	_DEBUG
				LCD_Position(0,0);
				LCD_PrString(pszFileName);
			#endif

			ret = OpenSDCardFile(&amp;fp,pszFileName);
			if(ret == FALSE)
			{
				fp = SDCard_MAXFILES;
				continue;
			}
			#ifdef	_DEBUG
				LCD_Position(1,0);
				LCD_PrCString(&quot;  ok                  &quot;);
			#endif
		}

		#ifdef	_DEBUG
			LCD_Position(1,0);
			LCD_PrHexByte(fp);
		#endif


		{
			BYTE bRet;
			PRT1DR |= 0x40;			//Busy LED On

			bRet = SDCard_fputBuff(pszBuff, nLen, fp);
			SDCard_fflush(fp);
			if(SDCard_ferror(fp))//bRet == SDCard_EOF)//
			{
				//error!!
				#ifdef	_DEBUG
					LCD_Position(3,0);
					LCD_PrCString(&quot;                   &quot;);
					LCD_Position(3,0);
					LCD_PrCString(&quot;error &quot;);
					//LCD_PrHexByte(SDCard_ferror(fp));
					LCD_PrHexByte(fp);
				#endif

				SDCard_fclose(fp);
				fp = SDCard_MAXFILES;
			}
			PRT1DR &amp;= ~0x40;		//Busy LED Off
		}

		if((PRT1DR &amp; 0x20))		//break sw is on
			break;
	}
	SDCard_fclose(fp);
	SDCard_Select(SDCard_DISABLE);         // Deselect card
} </pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_11.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_11.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_11-thumb.gif" width="400" height="326" align="left" /></a>
そして1回、「Build」メニューの「Build」を選択してビルドする。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_12.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_12.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_12-thumb.gif" width="400" height="326" align="left" /></a>
すると新しく追加したモジュールの割り込み設定用ソースコードがプロジェクトに追加される。その中から「counter16int.asm」を開き、「ljmp _COUNT16_INT」の1行を追加する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_13.gif" rel="lightbox"><img alt="psoc_gps_sd_d200_13.gif" src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_13-thumb.gif" width="400" height="326" align="left" /></a>
同様に「psocgpioint.asm」の中には「ljmp _GPIO_INT」の1行を追加する。これでソースコードの修正まで終わった。
<br clear=left>

<img src="http://www.dinop.com/2007/07/13/psoc_gps_sd_d200_14.gif" width="794" height="559"><br>

<a href="http://www.dinop.com/2007/07/13/_DSC9380.JPG" rel="lightbox"><img alt="_DSC9380.JPG" src="http://www.dinop.com/2007/07/13/_DSC9380-thumb.JPG" width="400" height="267" align="left" /></a>
PSoCへプログラムを書き込み、上の回路図のようにNikon D200と接続するとGPSログをSDカードに保存しつつ、Nikon D200へ流し込めるようになった。Nikon D200でシャッターを半押しするとGPSマークが表示され、撮影画像に位置情報が記録される。1分ほど経つとGPSマークが消え、さらに数秒たつと半押しタイマーが作動する。シャッターの押下情報を利用していないのでまだ使い勝手は悪いもののなんとか形になったかな？
<br clear=left>

]]></description>
         <link>http://www.dinop.com/elec/psoc_sdcard_gps_nikon_d200.html</link>
         <guid>http://www.dinop.com/elec/psoc_sdcard_gps_nikon_d200.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">電子工作</category>
        
        
         <pubDate>Fri, 13 Jul 2007 01:50:33 +0900</pubDate>
      </item>
            <item>
         <title>PSoCでSDカードにGPSログを保存する</title>
         <description><![CDATA[
<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_01.gif" rel="lightbox"><img alt="psoc_gps_sd_01.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_01-thumb.gif" width="400" height="326" align="left" /></a>
今回はGPSからRS-232C経由で取得できる緯度経度のログデータをSDカードに保存してみる。
GPSユニットは「<a href="http://www.dinop.com/elec/psoc_gps.html" target="_blank">PSoCとGPSモジュールで経緯度を表示する</a>」で用いたのと同じものを使った。
前回の「<a href="http://www.dinop.com/elec/psoc_sdcard_write.html" target="_blank">PSoCでSDカードに書き込む</a>」でSDカードをPSoCから（実用的に）使うのは無理と感じたが、"なんとかなるかもしれない"という淡い希望を抱き作業した。結論は．．．やはりダメだった。GPSログをSDカードに保存はできるが、信頼性がなさすぎてとても実用にはできない。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_02.gif" rel="lightbox"><img alt="psoc_gps_sd_02.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_02-thumb.gif" width="400" height="326" align="left" /></a>
前回作成した「<a href="http://www.dinop.com/elec/psoc_sdcard_write.html" target="_blank">PSoCでSDカードに書き込む</a>」のプロジェクトをPSoC Designerで開く。そして「View」メニューの「Device Editor」を選択して画面を切り替える。
<br clear=left>


<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_03.gif" rel="lightbox"><img alt="psoc_gps_sd_03.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_03-thumb.gif" width="400" height="326" align="left" /></a>
さらに「Config」メニューの「Selection」を選択してモジュール選択画面に切り替える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_04.gif" rel="lightbox"><img alt="psoc_gps_sd_04.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_04-thumb.gif" width="400" height="326" align="left" /></a>
ここでGPSからのデータを受信するためのモジュールを追加する。「Digital Comm」にある「RX8」を右クリックして現れるメニューから「Select」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_05.gif" rel="lightbox"><img alt="psoc_gps_sd_05.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_05-thumb.gif" width="400" height="326" align="left" /></a>
追加された「RX8_1」というアイコンを右クリックして現れるメニューから「Rename」を選択して名前を「RX8」に変更する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_06.gif" rel="lightbox"><img alt="psoc_gps_sd_06.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_06-thumb.gif" width="400" height="326" align="left" /></a>
名前の変更までできたら、「Config」メニューの「Interconnect」を選択して配線設定画面に切り替える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_07.gif" rel="lightbox"><img alt="psoc_gps_sd_07.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_07-thumb.gif" width="400" height="326" align="left" /></a>
そして「RX8」のアイコンを右クリックして現れるメニューから「Place」を選択して配置する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_08.gif" rel="lightbox"><img alt="psoc_gps_sd_08.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_08-thumb.gif" width="400" height="326" align="left" /></a>
前回行ったプロジェクトの設定で「VC1」が「6」、「VC2」が「8」になっているが、さらに．．．
「VC3 Source」を「VC2」に、
「VC3 Divider」を「13」にする。そして「RX8」の設定欄で
「Clock」を「VC3」に、
「Input」を「Row_0_Input_0」に、
「ClockSync」を「Sync to SysClk」に、
「RxCmdBuffer」を「Disable」に、
「RxBufferSize」を「128 Bytes」にする。これでGPSからの信号を4800bpsで受信できるようになる。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_09.gif" rel="lightbox"><img alt="psoc_gps_sd_09.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_09-thumb.gif" width="400" height="326" align="left" /></a>
とは言うもののどのポートから受信するかの設定がまだなので、「RX8」の入力が「Port_0_0」からになるように配線する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_10.gif" rel="lightbox"><img alt="psoc_gps_sd_10.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_10-thumb.gif" width="400" height="326" align="left" /></a>
配線が終わったら「View」メニューの「Application Editor」を選択してソースコード編集画面に切り替える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_11.gif" rel="lightbox"><img alt="psoc_gps_sd_11.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_11-thumb.gif" width="400" height="326" align="left" /></a>
ここで「main.c」の中に処理を書く。
今回はGPSから受信するデータのうち「$GPRMC」と「$GPGGA」データをSDカードに保存し、ほかのデータは無視している。GPSから届くデータを全て書き込めるほど高速にSDカードへ書き込めないためだ。受信割り込み処理でバッファーを複数確保して切り替えながらSDカードへ保存するなどの方法も試したが速度的に間に合わなかった。
<br clear=left>
<pre class=SourceCode>//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include &lt;m8c.h&gt;        // part specific constants and macros
#include &quot;PSoCAPI.h&quot;    // PSoC API definitions for all User Modules

#include &quot;stdlib.h&quot;

//#define	_DEBUG

// Can not retreave last data of CSV
BOOL	GetCSVData(char* pszCSV,int nIndex,char** ppszStart,char** ppszEnd)
{
	int		i;
	int		nFind;

	if(nIndex &lt; 0)
		return	FALSE;

	*ppszStart = pszCSV;
	*ppszEnd = pszCSV;
	nFind = 0;
	i = -1;
	while(1)
	{
		i++;
		if(pszCSV[i] != ',')
			continue;

		nFind++;

		if(nFind == nIndex)
			*ppszStart = &amp;(pszCSV[i+1]);
		if(nFind == nIndex + 1)
		{
			*ppszEnd = &amp;(pszCSV[i-1]);
			return	TRUE;
		}
	}

	return	FALSE;
}




BOOL	IsFileExist(char* pszFileName)
{
	char	fp;

	fp = SDCard_fopen(pszFileName,&quot;r&quot;);
	if(fp &gt; SDCard_MAXFILES)			// != SDCard_MAXFILES
		return	TRUE;
//	if(fp == SDCard_MAXFILES || SDCard_ferror(fp) &amp; 0x02)	//check error flag of &quot;File not found.&quot;
	if(fp == SDCard_MAXFILES)
	{
		SDCard_fclose(fp);
		return	FALSE;
	}
	if(SDCard_GetFileSize(fp) == 0)		//File is empty.
	{
		SDCard_fclose(fp);
		return	FALSE;
	}
	SDCard_fclose(fp);

	return	TRUE;
}



BOOL	OpenSDCardFile(char* pfp,char* pszFileName)
{
	int	i;

	for(i = 0; i &lt; 2; i++)
	{
		BYTE	ret;

		*pfp = SDCard_fopen(pszFileName,&quot;a&quot;);
		#ifdef	_DEBUG
			LCD_Position(2,0);
			LCD_PrCString(&quot;fp:&quot;);
			LCD_PrHexByte(*pfp);
		#endif
		if(*pfp &lt; SDCard_MAXFILES)			// != SDCard_MAXFILES
			return	TRUE;

		ret = SDCard_ferror(*pfp);
		SDCard_fclose(*pfp);

		#ifdef	_DEBUG
			LCD_Position(1,4);
			LCD_PrCString(&quot;error         &quot;);
			LCD_Position(1,10);
			LCD_PrHexByte(ret);
		#endif
	}

	return	FALSE;
}


BOOL	CreateFileName(char* pszRMCData,char* pszFileName)
{
	//LOG file is not open, so make file name and open...
	//file name is &quot;ayymmdda.txt&quot; to &quot;zyymmdda.txt&quot;

	int		j;
	int		k;
	char*	pszStart;
	char*	pszEnd;
	BOOL	ret;

	//file name is made from date, and date data is only in RMC data.
	if(!(pszRMCData[3] == 'R' &amp;&amp; pszRMCData[4] == 'M' &amp;&amp; pszRMCData[5] == 'C'))
		return	FALSE;

	//Get date from RMC data.
	ret = GetCSVData(pszRMCData,9,&amp;pszStart,&amp;pszEnd);
	if(ret == FALSE || pszStart == pszEnd || pszEnd - pszStart &lt; 5)
		return	FALSE;

	pszFileName[1] = pszStart[4];	//year
	pszFileName[2] = pszStart[5];
	pszFileName[3] = pszStart[2];	//month
	pszFileName[4] = pszStart[3];
	pszFileName[5] = pszStart[0];	//day
	pszFileName[6] = pszStart[1];

	pszFileName[8]  = '.';
	pszFileName[9]  = 't';
	pszFileName[10] = 'x';
	pszFileName[11] = 't';
	pszFileName[12] = 0;


	for(j = 0; j &lt; 26; j++)
	{
		pszFileName[0]  = 'a' + j;
		for(k = 0; k &lt; 26; k++)
		{
			pszFileName[7]  = 'a' + k;

			ret = IsFileExist(pszFileName);
			if(ret == FALSE)
				return	TRUE;
		}
	}

	return	FALSE;
}




void main()
{  
	char   fp;                            // File Pointer  

	// make Port16 to &quot;strong&quot; for LED
	PRT1DM0 |= 0x40;
	PRT1DM1 &amp;= ~0x40;
	PRT1DM2 &amp;= ~0x40;

	// make Port15 to &quot;pull-down&quot; for input sw
	PRT1DM0 &amp;= ~0x20;
	PRT1DM1 &amp;= ~0x20;
	PRT1DM2 &amp;= ~0x20;


	#ifdef	_DEBUG
		LCD_Start();
	#endif

	SDCard_Start();
	{
		char   cardInfo;                      // Card information  

		SDCard_Select(SDCard_ENABLE); // Select card  
		cardInfo = 0;  
		while ( ! cardInfo )          // Wait for card to communicate  
		{
			cardInfo = SDCard_InitCard();
		}
	}

	RX8_Start(RX8_PARITY_NONE);
	RX8_DisableInt();
	M8C_DisableGInt;

	fp = SDCard_MAXFILES;
	while(1)
	{
		int		i;
		int		nLen;
		char	pszBuff[160];

		i = 0;
		while(1)
		{
			while ( !(RX8_bReadRxStatus() &amp; (RX8_RX_COMPLETE | RX8_RX_NO_ERROR)))
			{
			}
			pszBuff[i] = RX8_bReadRxData();
			if(pszBuff[i] == '\n' &amp;&amp; i &gt; 0 &amp;&amp; pszBuff[i-1] == '\r')
				break;
			i++;
			if(i &gt;= 158)
				i = 0;
		}
		//pszBuff[i+1] = NULL;
		nLen = i + 1;

		if(!(pszBuff[0] == '$' &amp;&amp; pszBuff[1] == 'G' &amp;&amp; pszBuff[2] == 'P'))
			continue;

		for(i = 0; i &lt;= nLen-3; i++)		//pszBuff[nLen-2]=='\r' pszBuff[nLen-1]=='\n'
		{
			if(pszBuff[i] &lt; 0x20 || pszBuff[i] &gt;= 0x7f)
				break;
		}
		if(i != nLen-2)
			continue;

		if(!((pszBuff[3] == 'G' &amp;&amp; pszBuff[4] == 'G' &amp;&amp; pszBuff[5] == 'A')
			|| (pszBuff[3] == 'R' &amp;&amp; pszBuff[4] == 'M' &amp;&amp; pszBuff[5] == 'C')))
			continue;

		if(fp == SDCard_MAXFILES)
		{
			BOOL	ret;
			char	pszFileName[13]; 	 //File name is 8.3 format

			ret = CreateFileName(pszBuff,pszFileName);
			if(ret == FALSE)
			{
				fp = SDCard_MAXFILES;
				continue;
			}

			#ifdef	_DEBUG
				LCD_Position(0,0);
				LCD_PrString(pszFileName);
			#endif

			ret = OpenSDCardFile(&amp;fp,pszFileName);
			if(ret == FALSE)
			{
				fp = SDCard_MAXFILES;
				continue;
			}
			#ifdef	_DEBUG
				LCD_Position(1,0);
				LCD_PrCString(&quot;  ok                  &quot;);
			#endif
		}

		#ifdef	_DEBUG
			LCD_Position(1,0);
			LCD_PrHexByte(fp);
		#endif


		{
			BYTE bRet;
			PRT1DR |= 0x40;			//Busy LED On

			bRet = SDCard_fputBuff(pszBuff, nLen, fp);
			SDCard_fflush(fp);
			if(SDCard_ferror(fp))//bRet == SDCard_EOF)//
			{
				//error!!
				#ifdef	_DEBUG
					LCD_Position(3,0);
					LCD_PrCString(&quot;                   &quot;);
					LCD_Position(3,0);
					LCD_PrCString(&quot;error &quot;);
					//LCD_PrHexByte(SDCard_ferror(fp));
					LCD_PrHexByte(fp);
				#endif

				SDCard_fclose(fp);
				fp = SDCard_MAXFILES;
			}
			PRT1DR &amp;= ~0x40;		//Busy LED Off
		}

		if((PRT1DR &amp; 0x20))		//break sw is on
			break;
	}
	SDCard_fclose(fp);
	SDCard_Select(SDCard_DISABLE);         // Deselect card
} </pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/12/_DSC9257.JPG" rel="lightbox"><img alt="_DSC9257.JPG" src="http://www.dinop.com/2007/07/12/_DSC9257-thumb.JPG" width="400" height="268" align="left" /></a>
これでPSocへ書き込んで動かしてみた。ポート00にGPSからの信号線(TX)を接続、ポート15にスイッチ、ポート16にLEDを接続した。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/_DSC9258.JPG" rel="lightbox"><img alt="_DSC9258.JPG" src="http://www.dinop.com/2007/07/12/_DSC9258-thumb.JPG" width="400" height="268" align="left" /></a>
今回利用したGPSモジュール。ストロベリーリナックスで6200円程度のもの。今日、新たに追加購入しようかと思い通販ページをチェックしたのだが．．．残念ながら売り切れていた。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_14.gif" rel="lightbox"><img alt="psoc_gps_sd_14.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_14-thumb.gif" width="400" height="315" align="left" /></a>
実際にSDカードへ書き込まれたログを見てみると．．．図のようにまれに文字化けが起きている。文字化けがあるとSDカードの内容が壊れたりするのでプログラム中で変な文字は書き込まないようにチェックを入れているのだが．．．ダメなようだ。
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_13.gif" rel="lightbox"><img alt="psoc_gps_sd_13.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_13-thumb.gif" width="400" height="360" align="left" /></a>
そしてファイル内容が完全に変な状態になったり．．．
<br clear=left>

<a href="http://www.dinop.com/2007/07/12/psoc_gps_sd_12.gif" rel="lightbox"><img alt="psoc_gps_sd_12.gif" src="http://www.dinop.com/2007/07/12/psoc_gps_sd_12-thumb.gif" width="400" height="188" align="left" /></a>
このようにFATがほとんど壊れてしまったりもする。Windowsで認識できずにフォーマットするしかなくなることもある。
また、利用するSDカードがフォーマット直後でなくファイルがたくさん入っている状態（例えばデジカメで撮った画像が入ったままのSDカード）だと1回の書き込みに数十秒かかるため速度が間に合わず失敗する。<br>
要するに全然使い物にならない。
<br clear=left>
]]></description>
         <link>http://www.dinop.com/elec/psoc_sdcard_gps_log.html</link>
         <guid>http://www.dinop.com/elec/psoc_sdcard_gps_log.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">電子工作</category>
        
        
         <pubDate>Thu, 12 Jul 2007 03:10:32 +0900</pubDate>
      </item>
            <item>
         <title>PSoCでSDカードに書き込む</title>
         <description><![CDATA[<a href="http://www.dinop.com/2007/07/10/psoc_sd_01.gif" rel="lightbox"><img alt="psoc_sd_01.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_01-thumb.gif" width="400" height="326" align="left" /></a>
今回はPSoCにSDカードを接続して書き込んでみる。PSoC DesignerにはSDカードを利用するための「SDCard」モジュールが用意されている。今回はこれを利用した。このモジュールはFAT16とFAT32をサポートし、最大で2GBのメディアを扱える。
ただしこのユーザーモジュールは結論から書くと非常に遅く（今回は100バイト程度書き込んだが30秒かかった）、SDカードの内容が完全に消えてしまうこともある。ファイルの作成日時設定用のAPIも用意されていないなど、かなり中途半端なものだった。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/_DSC9252.JPG" rel="lightbox"><img alt="_DSC9252.JPG" src="http://www.dinop.com/2007/07/10/_DSC9252-thumb.JPG" width="400" height="268" align="left" /></a>
まずはSDカードのソケットを準備する。「SDカード」とは書いたがSDカードは持っていないのでminiSDカードを使うことにした。ソケットはこれ。以前携帯電話を買ったときに付属していたminiSDカード→SDカードの変換アダプター。<br>
PSoCでSDカードを使うのに必要なものは．．．SDカード（最大2GB）、SDカードソケット、10KΩの抵抗×3、300Ωの抵抗×3、3.3V出力の3端子レギュレーター、10～100μF程度の電解コンデンサー×2、0.01μF程度の積層セラミックコンデンサー×2かな？。PSoCはCY8C29466など、CY8C29xxxのものが必要（データシートはCY7C29xxxとなっているがそれは誤植）。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/_DSC9253.JPG" rel="lightbox"><img alt="_DSC9253.JPG" src="http://www.dinop.com/2007/07/10/_DSC9253-thumb.JPG" width="400" height="268" align="left" /></a>
端子めんを見ると金メッキされた端子が見える。ここにリード線を直接ハンダ付けしてしまう。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/_DSC9254.JPG" rel="lightbox"><img alt="_DSC9254.JPG" src="http://www.dinop.com/2007/07/10/_DSC9254-thumb.JPG" width="400" height="268" align="left" /></a>
こんな感じ。せっかくだったのでプルアップ抵抗もつけた。SDカードモジュールのデータシートによると10KΩと300Ωの2通りのプルアップ抵抗だったのだが．．．間違えて全部10KΩでプルアップしてしまった。PSoCを3.3Vで動かす場合は10KΩの抵抗3つ、PSoCを5Vで動かす場合は10KΩを3つと300Ωを3つ利用するのが正しい。
写真上から緑黒の線をポート05、緑赤をポート04、ピンクを3.3V、灰をGND、橙黒をポート03、橙赤をポート02に接続した。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/_DSC9256.JPG" rel="lightbox"><img alt="_DSC9256.JPG" src="http://www.dinop.com/2007/07/10/_DSC9256-thumb.JPG" width="400" height="268" align="left" /></a>
SDカードに供給するための3.3Vは秋月電子で売られていた4端子レギュレーターを利用した。1ピンに5V、3ピンをGNDに接続すると2ピンから3.3Vが出力される。
5Vと3.3Vラインには10μFの電解コンデンサーを入れた。積層コンデンサーは面倒だったので入れていない。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_02.gif" rel="lightbox"><img alt="psoc_sd_02.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_02-thumb.gif" width="400" height="326" align="left" /></a>
PSoC Designerを起動したら「Digital Comm」にある「SDCard」を右クリックして現れるメニューから「Select」を選択してプロジェクトに追加する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_03.gif" rel="lightbox"><img alt="psoc_sd_03.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_03-thumb.gif" width="400" height="326" align="left" /></a>
すると利用モードの選択画面が開く。今回はライトプロテクト端子などの制御は行わない（ソケットの形状から行なえない）ので「SDCard without Card Detect or Write Protect Inputs」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_04.gif" rel="lightbox"><img alt="psoc_sd_04.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_04-thumb.gif" width="400" height="326" align="left" /></a>
そして「SDCard_1」が追加されたら、アイコンを右クリックして現れるメニューから「Rename」を選択して名前を「SDCard」に変更する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_06.gif" rel="lightbox"><img alt="psoc_sd_06.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_06-thumb.gif" width="400" height="326" align="left" /></a>
名前を変更したら「Config」メニューの「Interconnect」を選択して配線設定画面に切り替える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_07.gif" rel="lightbox"><img alt="psoc_sd_07.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_07-thumb.gif" width="400" height="326" align="left" /></a>
そして「SDCard」のアイコンを右クリックして現れるメニューから「Place」を選択して配置する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_08.gif" rel="lightbox"><img alt="psoc_sd_08.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_08-thumb.gif" width="400" height="326" align="left" /></a>
「VC1=SysClk/N」を「6」に、
「VC2=VC1/N」を「8」に、
「Clock」を「VC2」に、
「SD_DO」を「Row_0_Input_1」に、
「SD_DI」を「Row_0_Output_3」に、
「SD_SClk」を「Row_0_Output_0」に、
「SD_CS_Port」を「Port_0」に、
「SD_CS_Pin」を「Port_0_2」にする。「SDCard」モジュールに供給するクロックは最大4MHzまで対応しているが、今回はその8分の1の500Hzを供給している。4MHzを供給した場合はSDカードの内容が消えてしまったからだ。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_09.gif" rel="lightbox"><img alt="psoc_sd_09.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_09-thumb.gif" width="400" height="326" align="left" /></a>
さらに内部配線をする。今回はSDカード関連の信号をポート0にまとめた。
ポート02にSD_CS、
ポート03にSD_DI、
ポート04にSD_SCLK、
ポート05にSD_DOを接続した。さらにポート02～04の「Drive」を「Strong」から「Open Drain Low」に変更する。PSoCを5Vで使う場合は変更を忘れないように。
なおポート0内で利用していないポートにLEDなどを接続してもきちんとコントロールできない。どうやらSDCardモジュール内で未使用ポートも書き換えているようだ。そのためポート０内の未使用端子は使わない方がいい。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_10.gif" rel="lightbox"><img alt="psoc_sd_10.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_10-thumb.gif" width="400" height="326" align="left" /></a>
かなり作業が多かったのでもう一度間違えていないか確認してから、「View」メニューの「Application Editor」を選択してソースコード編集画面に切り替える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_11.gif" rel="lightbox"><img alt="psoc_sd_11.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_11-thumb.gif" width="400" height="326" align="left" /></a>
そして「Source Files」の「main.c」に処理を書く。今回は「SDCard」モジュール内のサンプルコードを流用して、「Hello Worldx」という文字を10行出力するようにした。また、ポート1にLEDを2つ用意してビジー信号が分かるようにした。PSoCのSDカードアクセスは非常に遅いので、ビジー状態を見るためのLEDは省略せずに用意した方がいい。
<br clear=left>
<pre class=SourceCode>//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include &lt;m8c.h&gt;        // part specific constants and macros
#include &quot;PSoCAPI.h&quot;    // PSoC API definitions for all User Modules

#include &quot;stdlib.h&quot;


char helloFile[] = &quot;hello.txt&quot;;  
  
void main()  
{  
	char   cardInfo;                      // Card information  
	char   fp;                            // File Pointer  
	int		i;
	char	pszBuff[10];

	// make Port16 an Port18 to &quot;strong&quot; for LED
	PRT1DM0 |= (0x40 | 0x80);
	PRT1DM1 &amp;= ~(0x40 | 0x80);
	PRT1DM2 &amp;= ~(0x40 | 0x80);

	SDCard_Start(  );                      // initialize hardware and SDCard_lib buffers  
  
	PRT1DR |= 0x80;		//nEnd LED On
	for(i = 0; i &lt; 10; i++)
	{
		PRT1DR |= 0x40;		//Busy LED On

		SDCard_Select(SDCard_ENABLE); // Select card  
		cardInfo = 0;  
		while ( ! cardInfo )          // Wait for card to communicate  
		{  
			// initialize card, determine card type and file system type  
			cardInfo = SDCard_InitCard();  
		}  

		fp = SDCard_fopen(helloFile,&quot;a&quot;);      // Open file to append data  
		SDCard_fputcs(&quot;Hello World&quot;, fp);  // Write string   
		itoa(pszBuff,i,10);
		SDCard_fputs(pszBuff, fp);  // Write string   
		SDCard_fputcs(&quot;\r\n&quot;, fp);  // Write string   
		SDCard_fclose(fp);                     // Close file  
		SDCard_Select(SDCard_DISABLE);         // Deselect card  
		
		PRT1DR &amp;= ~0x40;		//Busy LED Off
	}
	PRT1DR &amp;= ~0x80;		//nEnd LED Off
} </pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/10/_DSC9255.JPG" rel="lightbox"><img alt="_DSC9255.JPG" src="http://www.dinop.com/2007/07/10/_DSC9255-thumb.JPG" width="400" height="268" align="left" /></a>
これでPSoCへ書き込んで動かしてみた。10行書き込むのにおよそ30秒かかった。SDカード内にほかのファイルが多く入っている場合はさらに遅くなるようだ。遅いのはSDCard_InitCard();の部分のようなので、一度SDカードを捕まえたらPSoCの電源を切るまで離さないようにした方がいいのかもしれない。
<br clear=left>


<a href="http://www.dinop.com/2007/07/10/psoc_sd_12.gif" rel="lightbox"><img alt="psoc_sd_12.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_12-thumb.gif" width="400" height="232" align="left" /></a>
SDカードの中を見てみると「hello.txt」というファイルができていた。
<br clear=left>

<a href="http://www.dinop.com/2007/07/10/psoc_sd_13.gif" rel="lightbox"><img alt="psoc_sd_13.gif" src="http://www.dinop.com/2007/07/10/psoc_sd_13-thumb.gif" width="400" height="333" align="left" /></a>
開いてみると確かに書き込まれていた。<br>
しかしその後、1回ファイルを開いてから大量に書き込んだりバイナリ書き込みなどのテストをしてみると、まれに書き込み文字が化けていたり、fopenを使い追記モードでファイルを開いたとたんにそれまであったファイル内容がすべて文字化けしたり、ファイル名が「07071000.txt」のようにゼロから始まると(?)失敗したり．．．というトラブルが生じた。どうもPSoCのSDカードモジュールは使い物にならないようだ。簡単に使えて便利だと思ったのだが非常に残念。
<br clear=left>


]]></description>
         <link>http://www.dinop.com/elec/psoc_sdcard_write.html</link>
         <guid>http://www.dinop.com/elec/psoc_sdcard_write.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">電子工作</category>
        
        
         <pubDate>Tue, 10 Jul 2007 21:05:20 +0900</pubDate>
      </item>
            <item>
         <title>FPGAでグラフィックス液晶モジュール用の信号を生成する（その3）</title>
         <description><![CDATA[<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_01.gif" rel="lightbox"><img alt="fpga_glcd_03_01.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_01-thumb.gif" width="400" height="326" align="left" /></a>
前回の「<a href="http://www.dinop.com/elec/fpga_glcd_02.html" target="_blank">FPGAでグラフィックス液晶モジュール用の信号を生成する（その2）</a>」で鈴商で販売されている384×192ドットのモノクロ液晶モジュールにDesign Wave Magazine 2007年7月号付録のSpartan3Eで縦線を表示できるようになった。
今回はさらにFPGAのブロックRAMに画像データを格納して、任意の画像を表示できるようにする。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_02.gif" rel="lightbox"><img alt="fpga_glcd_03_02.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_02-thumb.gif" width="400" height="326" align="left" /></a>
Xilinx ISE WebPackで前回までに作成したプロジェクトを開く。そして画像データをプロジェクトに追加するため「Project」メニューの「New Source」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_03.gif" rel="lightbox"><img alt="fpga_glcd_03_03.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_03-thumb.gif" width="400" height="326" align="left" /></a>
これまではソースコードの追加時は「VHDL Module」を選択したていたが、今回は「IP (Coregen & Archtecture Wizard)」を利用する。ファイル名は「ImageROM」とした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_04.gif" rel="lightbox"><img alt="fpga_glcd_03_04.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_04-thumb.gif" width="400" height="326" align="left" /></a>
するとツリー形式でIPの選択画面が開く。ここで「Memories & Storage Elements」の「RAMs & ROMs」にある「Single Port Block Memory v6.2」を選択する。本当はDual Portのものを利用した方が後々使いやすいのだろうが、ブロックRAMを使うのは初めてなので単純なSingle Portのものにした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_05.gif" rel="lightbox"><img alt="fpga_glcd_03_05.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_05-thumb.gif" width="400" height="326" align="left" /></a>
確認画面が出たら「Finish」でウイザードを終える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_06.gif" rel="lightbox"><img alt="fpga_glcd_03_06.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_06-thumb.gif" width="400" height="326" align="left" /></a>
ウイザードが閉じると画面下部に「Customizing IP...」という表示がされ、バックで作業が行われる。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_07.gif" rel="lightbox"><img alt="fpga_glcd_03_07.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_07-thumb.gif" width="400" height="326" align="left" /></a>
そして20秒程度待つとブロックメモリーの設定画面が開く。この設定ウインドウではメモリーサイズや初期データの指定などをする。
まず「Memory Size」の「Width」を「4」、「Depth」を「18432」にする。これはメモリーサイズの指定で、今回は4ビット×18432（＝384x192÷4）のメモリーを確保した。さらに今回は「Write Mode」を「No Read On Write」にした。設定が済んだら「Next」ボタンで次へ進む。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_08.gif" rel="lightbox"><img alt="fpga_glcd_03_08.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_08-thumb.gif" width="400" height="326" align="left" /></a>
ここではEnableやハンドシェイクなどの有無などを設定できる。今回はそのまま次へ進む。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_09.gif" rel="lightbox"><img alt="fpga_glcd_03_09.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_09-thumb.gif" width="400" height="326" align="left" /></a>
ここではクロックの立ち上がりを使うか立下りを見るかなどのタイミング設定ができる。ここもそのまま次へ進む。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_10.gif" rel="lightbox"><img alt="fpga_glcd_03_10.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_10-thumb.gif" width="400" height="326" align="left" /></a>
最後の画面ではメモリーの初期データの設定などができる。ここで画像データを初期データとして指定する。「Load Init File」にチェックを入れて、「Load File」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_11.gif" rel="lightbox"><img alt="fpga_glcd_03_11.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_11-thumb.gif" width="400" height="326" align="left" /></a>
するとファイル選択画面が開く。ここで用意した初期データのファイル「rom_data.coe」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_12.gif" rel="lightbox"><img alt="fpga_glcd_03_12.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_12-thumb.gif" width="400" height="313" align="left" /></a>
用意した初期データはテキストファイルで、内容はこのようになっている。3行目から16進数でデータを並べている。今回はブロックRAMを4ビットとしたので、上位4ビットはゼロのままにしておく。<br>
<br>
<a href="http://www.dinop.com/2007/07/04/_rom_data.coe">今回利用した初期データファイルをダウンロード</a>

<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_13.gif" rel="lightbox"><img alt="fpga_glcd_03_13.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_13-thumb.gif" width="400" height="326" align="left" /></a>
初期データファイルの読み込みが終わったら、最後に「Generate」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_14.gif" rel="lightbox"><img alt="fpga_glcd_03_14.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_14-thumb.gif" width="400" height="326" align="left" /></a>
これで画面下部に「Generating IP...」と表示されてブロックRAMのデータが生成される。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_15.gif" rel="lightbox"><img alt="fpga_glcd_03_15.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_15-thumb.gif" width="400" height="326" align="left" /></a>
30秒程度すると「Finished Generating.」のように表示され、データ生成が終わるとともに左上の「Synthesis/Implementation」ウインドウ内に作成したブロックRAMを示す「ImageROM (ImageROM.xco)」という項目が追加される。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_16.gif" rel="lightbox"><img alt="fpga_glcd_03_16.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_16-thumb.gif" width="400" height="326" align="left" /></a>
さらにプロジェクトの保存されているフォルダを見ると複数のファイルが生成されている。このうち「ImageROM.vho」を開いてみると．．．
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_17.gif" rel="lightbox"><img alt="fpga_glcd_03_17.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_17-thumb.gif" width="400" height="326" align="left" /></a>
生成したブロックRAMをVHDLで利用するためのテンプレートが用意されている。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_18.gif" rel="lightbox"><img alt="fpga_glcd_03_18.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_18-thumb.gif" width="400" height="326" align="left" /></a>
次に生成したブロックRAMデータを使って液晶パネルへのD信号を生成するためのソースコードを作る。「Project」メニューの「New Source」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_19.gif" rel="lightbox"><img alt="fpga_glcd_03_19.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_19-thumb.gif" width="400" height="326" align="left" /></a>
そしてソースコードの形式から「VHDL Module」を選択しする。ファイル名は「GenerateD」とした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_20.gif" rel="lightbox"><img alt="fpga_glcd_03_20.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_20-thumb.gif" width="400" height="326" align="left" /></a>
信号の設定画面では「CLK」、「CP」と「D」を用意し、それぞれ「in」、「in」、「out」に設定した。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_21.gif" rel="lightbox"><img alt="fpga_glcd_03_21.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_21-thumb.gif" width="400" height="326" align="left" /></a>
そしてソースコードが生成されたらブロックRAMのデータを用いてD信号を生成する。

<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    02:31:08 07/04/2007 
-- Design Name: 
-- Module Name:    GenerateD - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateD is
    Port ( CLK : in  STD_LOGIC;
           CP : in  STD_LOGIC;
           D : out  STD_LOGIC_VECTOR(3 downto 0));
end GenerateD;

architecture Behavioral of GenerateD is

component ImageROM
	port (
	addr: IN std_logic_VECTOR(14 downto 0);
	clk: IN std_logic;
	din: IN std_logic_VECTOR(3 downto 0);
	dout: OUT std_logic_VECTOR(3 downto 0);
	we: IN std_logic);
end component;


signal	CLK_COUNT	: STD_LOGIC_VECTOR(4 downto 0) := &quot;00000&quot;;	--5bit for CP
signal	ADDR			: STD_LOGIC_VECTOR(14 downto 0) := &quot;000000000000000&quot;;
signal	DATA_IN		: STD_LOGIC_VECTOR(3 downto 0) := &quot;0000&quot;;
signal	DATA_OUT		: STD_LOGIC_VECTOR(3 downto 0) := &quot;0000&quot;;
signal	WE				: STD_LOGIC;
signal	CP_COUNT		: STD_LOGIC_VECTOR(6 downto 0) := &quot;0000000&quot;;

begin
	WE &lt;= '0';				--read only
	DATA_IN &lt;= &quot;0000&quot;;

	u1 : ImageROM
			port map (
				addr =&gt; ADDR,
				clk =&gt; CLK,
				din =&gt; DATA_IN,
				dout =&gt; DATA_OUT,
				we =&gt; WE);

	process (CLK)
	begin
		if CLK'event and CLK='1' then
			CLK_COUNT &lt;= CLK_COUNT + &quot;00001&quot;;
			if CLK_COUNT = &quot;00010&quot; then
				D &lt;= DATA_OUT;
			end if;
		end if;
	end process;

	process (CP)
	begin
		if CP'event and CP='1' then
			CP_COUNT &lt;= CP_COUNT + &quot;0000001&quot;;

			if CP_COUNT = &quot;1100011&quot; then		--99
				CP_COUNT &lt;= &quot;0000000&quot;;
			end if;

			if CP_COUNT &lt; &quot;1100000&quot; then		--96(=100-4)
				ADDR &lt;= ADDR + &quot;000000000000001&quot;;
			end if;

			if ADDR = &quot;100011111111111&quot; then		--18431(=384x192/4-1)
				ADDR &lt;= &quot;000000000000000&quot;;
			end if;
		end if;
	end process;

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_22.gif" rel="lightbox"><img alt="fpga_glcd_03_22.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_22-thumb.gif" width="400" height="326" align="left" /></a>
次にD信号を生成するためのソースコードを、これまでに作成したCPやLOADなどほかの信号と同期させる。左側のウインドウの「GenerateSignals - Behavioral (GenerateSignals.vhd)」をダブルクリックして開く。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_23.gif" rel="lightbox"><img alt="fpga_glcd_03_23.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_23-thumb.gif" width="400" height="326" align="left" /></a>
これまではD信号は固定値を指定していたが、先ほど作成したソースコードからの出力を使うように変える。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:45:42 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateSignals - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateSignals is
    Port ( CLOCK : in  STD_LOGIC;
           LOAD : out  STD_LOGIC;
           CP : out  STD_LOGIC;
           D : out  STD_LOGIC_VECTOR(3 downto 0);
           IO1 : out  STD_LOGIC;
           DF : out  STD_LOGIC);
end GenerateSignals;

architecture Behavioral of GenerateSignals is

signal	CP_TMP		: STD_LOGIC;
signal	LOAD_TMP		: STD_LOGIC;
signal	DF_TMP		: STD_LOGIC;
signal	IO1_TMP		: STD_LOGIC;
signal	LINECLOCK	: STD_LOGIC;

component GenerateCP
    Port ( CLK : in  STD_LOGIC;
           CP : out  STD_LOGIC);
end component;

component GenerateLOAD
    Port ( CP : in  STD_LOGIC;
           LOAD : out  STD_LOGIC);
end component;

component GenerateIO1
    Port ( LINECLK: in  STD_LOGIC;
           IO1 : out  STD_LOGIC);
end component;

component GenerateDF
    Port ( LINECLK : in  STD_LOGIC;
           DF : out  STD_LOGIC);
end component;

component	GenerateLineClk
    Port ( CP : in  STD_LOGIC;
           LINECLK : out  STD_LOGIC);
end component;

component	GenerateD
    Port ( CLK : in  STD_LOGIC;
			  CP : in  STD_LOGIC;
           D : out  STD_LOGIC_VECTOR(3 downto 0));
end component;

begin

	LOAD &lt;= LOAD_TMP;
	CP &lt;= CP_TMP;
	IO1 &lt;= IO1_TMP;
	DF &lt;= DF_TMP;

	u0:	GenerateCP	port map(
					CLK =&gt; CLOCK,
					CP =&gt; CP_TMP);

	u1:	GenerateLOAD	port map(
					CP =&gt; CP_TMP,
					LOAD =&gt; LOAD_TMP);

	u2:	GenerateIO1	port map(
					LINECLK =&gt; LINECLOCK,
					IO1 =&gt; IO1_TMP);

	u3:	GenerateDF	port map(
					LINECLK =&gt; LINECLOCK,
					DF =&gt; DF_TMP);

	u4:	GenerateLineClk	port map(
					CP =&gt; CP_TMP,
					LINECLK =&gt; LINECLOCK);

	u5:	GenerateD	port map(
					CLK =&gt; CLOCK,
					CP =&gt; CP_TMP,
					D =&gt; D);

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_24.gif" rel="lightbox"><img alt="fpga_glcd_03_24.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_24-thumb.gif" width="400" height="326" align="left" /></a>
これで一通りソースコードの修正が終わったのでFPGAに書き込むためのビットストリームファイルを作成する。「Generate Programming File」を右クリックして現れたメニューから「Run」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_25.gif" rel="lightbox"><img alt="fpga_glcd_03_25.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_25-thumb.gif" width="400" height="326" align="left" /></a>
保存を問う画面が開いたら「OK」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/fpga_glcd_03_26.gif" rel="lightbox"><img alt="fpga_glcd_03_26.gif" src="http://www.dinop.com/2007/07/04/fpga_glcd_03_26-thumb.gif" width="400" height="326" align="left" /></a>
これで数分待つと論理合成などが終わりビットストリームファイルが生成される。
<br clear=left>

<a href="http://www.dinop.com/2007/07/04/_DSC9186.JPG" rel="lightbox"><img alt="_DSC9186.JPG" src="http://www.dinop.com/2007/07/04/_DSC9186-thumb.JPG" width="400" height="268" align="left" /></a>
これでFPGAへ書き込むとグラフィックス液晶モジュールに用意したビットマップデータが画像として表示された。今回用意したデータはISE WebPackのキャプチャー画像を2値化したものに、画像処理ソフトであとから線や文字を加えたデータになる。キャプチャー画像はやはり汚くはっきりとしないが、後から加えた線や文字はくっきりしている。この手の液晶パネルは表示するデータの用意が難しいなぁ。
この液晶は2値のものだが1秒間に異なるフレームを何回か表示すれば多階調表示することもできる。例えば4種類の画像を1秒間に3回ずつ表示すれば1ドット当たり16階調表示ができる．．．ということも考えられるが、こうすると用意するデータ量が増えてしまう。データ量が増えてもいいのであればカラー液晶を使った方が表現力が大きくていい。やはりせっかくモノクロ液晶を使うのだから2値表示を採用した方がいいかな。
<br clear=left>]]></description>
         <link>http://www.dinop.com/elec/fpga_glcd_03.html</link>
         <guid>http://www.dinop.com/elec/fpga_glcd_03.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">電子工作</category>
        
        
         <pubDate>Wed, 04 Jul 2007 03:43:41 +0900</pubDate>
      </item>
            <item>
         <title>FPGAでグラフィックス液晶モジュール用の信号を生成する（その2）</title>
         <description><![CDATA[<a href="http://www.dinop.com/2007/07/03/_DSC9180.JPG" rel="lightbox"><img alt="_DSC9180.JPG" src="http://www.dinop.com/2007/07/03/_DSC9180-thumb.JPG" width="400" height="268" align="left" /></a>
前回の「<a href="http://www.dinop.com/elec/fpga_glcd_01.html" target="_blank">FPGAでグラフィックス液晶モジュール用の信号を生成する（その1）</a>」では鈴商で販売されているグラフィック液晶（384x192ドット、モノクロ）を利用するための信号の内、CPとLOAD信号生成部分をVHDLで作成し、ModelSimで信号のシュミレーションまでをした。
今回はさらにほかのIO1、DF信号の生成部も作成し、実際にFPGA（Spartan3E）へ書き込み動作を確認する。Spartan3EはDesign Wave Magazine 2007年7月号に付属していた基板を利用した。
<br clear=left>


<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_01.gif" rel="lightbox"><img alt="fpga_glcd_02_01.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_01-thumb.gif" width="400" height="326" align="left" /></a>
前回のプロジェクトをISE WebPackで開き、さらに信号を作るためソースコードを追加する。「Project」メニューの「New Source」を選択する。
<br clear=left>


<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_02.gif" rel="lightbox"><img alt="fpga_glcd_02_02.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_02-thumb.gif" width="400" height="326" align="left" /></a>
ソースコードの形式は「VHDL Module」、ファイル名は「GenerateLineClk」とした。残る信号はIO1、DF、Dの3信号だが、これらのうちIO1とDF信号は行単位（Y軸方向）の信号になる。CP信号からこれらを生成してもいいのだが、カウントするクロックするが大きくなるので1行ごとに1クロック出力するラインクロックを作って、それに基づいてIO1とDF信号を作ることにした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_03.gif" rel="lightbox"><img alt="fpga_glcd_02_03.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_03-thumb.gif" width="400" height="326" align="left" /></a>
「CP」と「LINECLK」を追加してそれぞれ「in」と「out」に設定する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_04.gif" rel="lightbox"><img alt="fpga_glcd_02_04.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_04-thumb.gif" width="400" height="326" align="left" /></a>
ラインクロックは1行につき1クロック生成したいので、1行（CP信号100クロック）でHighとLowが起きるように7ビットカウンターを作成した。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:59:58 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateLineClk - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateLineClk is
    Port ( CP : in  STD_LOGIC;
           LINECLK : out  STD_LOGIC);
end GenerateLineClk;

architecture Behavioral of GenerateLineClk is

signal TMP : STD_LOGIC_VECTOR( 6 downto 0 ) := &quot;0000000&quot;;
begin

	process (CP)
	begin
		if CP'event and CP='1' then
			TMP &lt;= TMP + &quot;0000001&quot;;
			if TMP &lt; &quot;0110010&quot; then			-- 50
				LINECLK &lt;= '1';
			else
				LINECLK &lt;= '0';
				if TMP = &quot;1100011&quot; then		-- 99
					TMP &lt;= &quot;0000000&quot;;
				end if;
			end if;
		end if;
	end process;

end Behavioral;</pre>
<br>
<br>


<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_05.gif" rel="lightbox"><img alt="fpga_glcd_02_05.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_05-thumb.gif" width="400" height="326" align="left" /></a>
次にIO1信号を生成するためのソースコードを追加する。「Project」メニューの「New Source」を選択して「VHDL Module」でファイル名が「GenerateIO1」とする。
そして「LINECLK」と「IO1」を入力してそれぞれ「in」と「out」に設定する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_06.gif" rel="lightbox"><img alt="fpga_glcd_02_06.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_06-thumb.gif" width="400" height="326" align="left" /></a>
ソースコードが生成したらIO1信号生成用のVHDLを記述する。IO1信号は画面内で1行目に該当するときのみHighとなる信号のため、8ビットカウンターで0のときHigh、191以下のときにLowになるようにする。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:02:18 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateIO1 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateIO1 is
    Port ( LINECLK : in  STD_LOGIC;
           IO1 : out  STD_LOGIC);
end GenerateIO1;

architecture Behavioral of GenerateIO1 is

signal TMP : STD_LOGIC_VECTOR( 7 downto 0 ) := &quot;00000000&quot;;
begin

	process (LINECLK)
	begin
		if LINECLK'event and LINECLK='1' then
			TMP &lt;= TMP + &quot;00000001&quot;;

			if TMP &lt; &quot;00000001&quot; then
				IO1 &lt;= '1';
			else
				IO1 &lt;= '0';
				if TMP = &quot;10111111&quot; then		-- 191
					TMP &lt;= &quot;00000000&quot;;
				end if;
			end if;
		end if;
	end process;

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_07.gif" rel="lightbox"><img alt="fpga_glcd_02_07.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_07-thumb.gif" width="400" height="326" align="left" /></a>
さらにDF信号を生成するためのソースコードを追加する。「Project」メニューの「New Source」を選択して「VHDL Module」でファイル名が「GenerateDF」とする。
そして「LINECLK」と「DF」を入力してそれぞれ「in」と「out」に設定する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_08.gif" rel="lightbox"><img alt="fpga_glcd_02_08.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_08-thumb.gif" width="400" height="326" align="left" /></a>
ソースコードが生成したらDF信号生成用のVHDLを記述する。DF信号は連続した2画面を見たときに最初の画面のときにHigh、次の画面のときにLowとなる信号のため、ラインクロックが192未満のときにHigh、383（＝192×2）以下のときにLowになるようにする。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:04:05 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateDF - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateDF is
    Port ( LINECLK : in  STD_LOGIC;
           DF : out  STD_LOGIC);
end GenerateDF;

architecture Behavioral of GenerateDF is

signal TMP : STD_LOGIC_VECTOR( 8 downto 0 ) := &quot;000000000&quot;;
begin

	process (LINECLK)
	begin
		if LINECLK'event and LINECLK='1' then
			TMP &lt;= TMP + &quot;000000001&quot;;

			if TMP &lt; &quot;11000000&quot; then		-- 192
				DF &lt;= '1';
			else
				DF &lt;= '0';
				if TMP = &quot;101111111&quot; then	-- 383(=192x2-1)
					TMP &lt;= &quot;000000000&quot;;
				end if;
			end if;
		end if;
	end process;

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_09.gif" rel="lightbox"><img alt="fpga_glcd_02_09.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_09-thumb.gif" width="400" height="326" align="left" /></a>
これでCP、LOAD、IO1、DFの各信号生成用のVHDLができた。最後にGenerateSignals.vhdを編集して、これらのモジュールを関連付ける。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:45:42 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateSignals - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateSignals is
    Port ( CLOCK : in  STD_LOGIC;
           LOAD : out  STD_LOGIC;
           CP : out  STD_LOGIC;
           D : out  STD_LOGIC_VECTOR(3 downto 0);
           IO1 : out  STD_LOGIC;
           DF : out  STD_LOGIC);
end GenerateSignals;

architecture Behavioral of GenerateSignals is

signal	CP_TMP		: STD_LOGIC;
signal	LOAD_TMP		: STD_LOGIC;
signal	DF_TMP		: STD_LOGIC;
signal	IO1_TMP		: STD_LOGIC;
signal	LINECLOCK	: STD_LOGIC;

component GenerateCP
    Port ( CLK : in  STD_LOGIC;
           CP : out  STD_LOGIC);
end component;

component GenerateLOAD
    Port ( CP : in  STD_LOGIC;
           LOAD : out  STD_LOGIC);
end component;

component GenerateIO1
    Port ( LINECLK: in  STD_LOGIC;
           IO1 : out  STD_LOGIC);
end component;

component GenerateDF
    Port ( LINECLK : in  STD_LOGIC;
           DF : out  STD_LOGIC);
end component;

component	GenerateLineClk
    Port ( CP : in  STD_LOGIC;
           LINECLK : out  STD_LOGIC);
end component;

begin

	LOAD &lt;= LOAD_TMP;
	CP &lt;= CP_TMP;
	D(0) &lt;= '1';
	D(1) &lt;= '1';
	D(2) &lt;= '0';
	D(3) &lt;= '0';
	IO1 &lt;= IO1_TMP;
	DF &lt;= DF_TMP;

	u0:	GenerateCP	port map(
					CLK =&gt; CLOCK,
					CP =&gt; CP_TMP);

	u1:	GenerateLOAD	port map(
					CP =&gt; CP_TMP,
					LOAD =&gt; LOAD_TMP);

	u2:	GenerateIO1	port map(
					LINECLK =&gt; LINECLOCK,
					IO1 =&gt; IO1_TMP);

	u3:	GenerateDF	port map(
					LINECLK =&gt; LINECLOCK,
					DF =&gt; DF_TMP);

	u4:	GenerateLineClk	port map(
					CP =&gt; CP_TMP,
					LINECLK =&gt; LINECLOCK);

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_10.gif" rel="lightbox"><img alt="fpga_glcd_02_10.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_10-thumb.gif" width="400" height="326" align="left" /></a>
ここまでできたら一度保存してシュミレーションしてみる。「File」メニューの「Save All」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_11.gif" rel="lightbox"><img alt="fpga_glcd_02_11.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_11-thumb.gif" width="400" height="326" align="left" /></a>
そして「ModelSim」を起動する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_12.gif" rel="lightbox"><img alt="fpga_glcd_02_12.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_12-thumb.gif" width="400" height="326" align="left" /></a>
ModelSimが起動したら「Compile」メニューの「Compile」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_13.gif" rel="lightbox"><img alt="fpga_glcd_02_13.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_13-thumb.gif" width="400" height="326" align="left" /></a>
そしてISE WebPackで作成したプロジェクトのフォルダを開き、「GenerateCP.vhd」、「GenerateDF.vhd」、「GenerateIO1.vhd」、「GenerateLineClk.vhd」、「GenerateLOAD.vhd」、「GenerateSignals.vhd」を選択して「Compile」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_14.gif" rel="lightbox"><img alt="fpga_glcd_02_14.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_14-thumb.gif" width="400" height="326" align="left" /></a>
コンパイルが終わったら「Done」ボタンを押して選択画面を閉じる。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_15.gif" rel="lightbox"><img alt="fpga_glcd_02_15.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_15-thumb.gif" width="400" height="326" align="left" /></a>
するとコンパイルしたファイルがツリー内の「work」ライブラリーに追加される。ここから「GenerateSignals」を右クリックして現れたメニューから「Simulate」を選択し、シュミレーション画面に切り替える。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_16.gif" rel="lightbox"><img alt="fpga_glcd_02_16.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_16-thumb.gif" width="400" height="326" align="left" /></a>
シュミレーション画面が開いたら「View」メニューの「Wave」で波形表示用ウインドウを開く。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_17.gif" rel="lightbox"><img alt="fpga_glcd_02_17.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_17-thumb.gif" width="400" height="326" align="left" /></a>
そしてシュミレーションしたい信号をドラッグ・アンド・ドロップする。今回はLOAD、CP、IO1、DFの各信号をシュミレートする。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_18.gif" rel="lightbox"><img alt="fpga_glcd_02_18.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_18-thumb.gif" width="400" height="326" align="left" /></a>
ドラッグ・アンド・ドロップしたらクロックの設定をする。「clock」を右クリックして現れたメニューから「Clock」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_19.gif" rel="lightbox"><img alt="fpga_glcd_02_19.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_19-thumb.gif" width="400" height="326" align="left" /></a>
そして「Period」欄に「2」と入力する。今回も前回と同様にパルスのタイミングだけ見れればいいためクロックを2ピコ秒とした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_20.gif" rel="lightbox"><img alt="fpga_glcd_02_20.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_20-thumb.gif" width="400" height="326" align="left" /></a>
クロックの設定まで終わったら、下の「Transcript」欄に「run 100000」と入力して10万ピコ秒のシュミレーションを行う。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_21.gif" rel="lightbox"><img alt="fpga_glcd_02_21.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_21-thumb.gif" width="400" height="326" align="left" /></a>
すると画面にシュミレーション結果が表示される。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_22.gif" rel="lightbox"><img alt="fpga_glcd_02_22.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_22-thumb.gif" width="400" height="326" align="left" /></a>
画面を見やすいように広げた。さらに全体が分かるように右クリックして現れたメニューから「Zoom Full」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_23.gif" rel="lightbox"><img alt="fpga_glcd_02_23.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_23-thumb.gif" width="400" height="326" align="left" /></a>
すると現在のシュミレーション全体10万ピコ秒分が画面に表示される。IO1が1行目のみHigh、LOADが1行ごとにHighなどの信号状態を見れる。さらに必要に応じて「run 1000000」のようにシュミレーションし、拡大縮小表示して信号の生成タイミングが意図した通りか確認する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_24.gif" rel="lightbox"><img alt="fpga_glcd_02_24.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_24-thumb.gif" width="400" height="326" align="left" /></a>
信号のシュミレーションが確認できたら、シュミレーターを終了して「ISE WebPack」の画面に戻る。そして次にユーザー制約ファイルによるピン配置の設定をする。
「Use Constraints」にある「Assign Package Pins」を右クリックして現れるメニューから「Run」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_25.gif" rel="lightbox"><img alt="fpga_glcd_02_25.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_25-thumb.gif" width="400" height="326" align="left" /></a>
するとピン配置を設定するための「Xilinx PACE」が起動する。ここで左側の「Design Object List」ウインドウ内の「Loc」欄で使用するピンを指定する。
「CLOCK」を「P88」に、
「CP」を「P49」に、
「D<0>」を「P47」に、
「D<1>」を「P40」に、
「D<2>」を「P35」に、
「D<3>」を「P33」に、
「DF」を「P26」に、
「IO1」を「P23」に、
「LOAD」を「P18」に設定する。これらの内「CLOCK」以外の液晶パネル用信号線はDisign Wave Magazine 2007年7月号付録基板のCN2上のA17～A08に相当する。ほかのポートを使いたい場合は適宜変更する。設定が終わったら「Xilinx PACE」を閉じる。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_26.gif" rel="lightbox"><img alt="fpga_glcd_02_26.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_26-thumb.gif" width="400" height="326" align="left" /></a>
そして「Generate Programming File」を右クリックして現れるメニューから「Run」を選択してビルド（論理合成など）を行う。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_02_27.gif" rel="lightbox"><img alt="fpga_glcd_02_27.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_02_27-thumb.gif" width="400" height="326" align="left" /></a>
待つこと数分。無事に論理合成などが終わりビットストリームファイルが生成した。
<br clear=left>


<a href="http://www.dinop.com/2007/07/03/_DSC9184.JPG" rel="lightbox"><img alt="_DSC9184.JPG" src="http://www.dinop.com/2007/07/03/_DSC9184-thumb.JPG" width="400" height="268" align="left" /></a>
これでbitファイルからXSVFファイルを生成してFPGAに書き込み動かしてみた。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/_DSC9185.JPG" rel="lightbox"><img alt="_DSC9185.JPG" src="http://www.dinop.com/2007/07/03/_DSC9185-thumb.JPG" width="400" height="268" align="left" /></a>
かなり無駄な部分の多いVHDLソースコードになってしまったが画面にきちんと縦線を表示できた。
縦線なのはソースコード（GenerateSignals.vhd）内で固定値「0011」を指定しているためだ。CP信号が1MHzでは遅すぎるからか若干ちらつきが見られるがバックライトを点灯しなくてもくっきりと表示された。
<br clear=left>]]></description>
         <link>http://www.dinop.com/elec/fpga_glcd_02.html</link>
         <guid>http://www.dinop.com/elec/fpga_glcd_02.html</guid>
                  <category domain="http://www.sixapart.com/ns/types#category">電子工作</category>
        
        
         <pubDate>Tue, 03 Jul 2007 19:09:46 +0900</pubDate>
      </item>
            <item>
         <title>FPGAでグラフィックス液晶モジュール用の信号を生成する（その1）</title>
         <description><![CDATA[

<a href="http://www.dinop.com/2007/07/03/_DSC9180.JPG" rel="lightbox"><img alt="_DSC9180.JPG" src="http://www.dinop.com/2007/07/03/_DSC9180-thumb.JPG" width="400" height="268" align="left" /></a>
今回は鈴商で販売されているグラフィック液晶（384x192ドット、モノクロ）を利用するための信号をFPGAで生成する。この液晶パネルは鈴商で1300円、対応する18ピンコネクターは5個で300円。液晶パネル3枚とコネクター5個で送料を含めてちょうど5000円だった。
この液晶パネルを利用するにあたって以下のホームページを参考にしました。これらがなければまず映像を出せることはなかった。どうもありがとうございます。
・「<a href="http://fishblue.jp/denshi/graphiclcd.html" target=_blank>Graphic LCD Contoller</a>」（液晶パネルの概要）
・「<a href="http://blogs.yahoo.co.jp/gomisai/8147767.html" target=_blank>鈴商dotLCD ～中間まとめ前半</a>」（回路図など）
・「<a href="http://blogs.yahoo.co.jp/gomisai/8164184.html" target=_blank>鈴商dotLCD ～中間まとめ後半</a>」（端子説明など）
・「<a href="http://blog.goo.ne.jp/sim00/e/db90c2b530cfecc16d9588580515d156" target=_blank>鈴商液晶(4) タイミングチャート(仮) </a>」（信号線のタイミング表：間違えてるバージョン）
・「<a href="http://blog.goo.ne.jp/sim00/e/2b557bce1be1e50e9fea92603f6d7b15" target=_blank>鈴商液晶(5) (真)タイミングチャート</a>」（信号線のタイミング表：正しいというバージョン＝しかし私はこのタイミング表では動かせなかった。なぜ？）
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/_DSC9181.JPG" rel="lightbox"><img alt="_DSC9181.JPG" src="http://www.dinop.com/2007/07/03/_DSC9181-thumb.JPG" width="400" height="268" align="left" /></a>
この液晶パネルではコントローラーとして「M5299C」と「M5298」が使われている。これらのデータシートはGoogleで検索すればダウンロード可能だが．．．私には理解できなかった。これらのデータシートだけで動かせる人は本当にすごいと思う。
液晶パネルからはバックライト用の2本の端子（未使用でOK）と写真の18ピンフラットケーブルが出ている。フラットケーブルは左側から1～18ピンで、その内訳は以下のようになっている。
 1:LOAD(CL1)
 2:CP(CL2)
 3:IO1(FRM)
 4:DF(M)
 5:D0
 6:D1
 7:D2
 8:D3
 9:DISP（Vccへ接続）
10:Vee1（Vccへ接続）
11:Vee2（Vccへ接続）
12:Vee3（Vccへ接続）
13:CTRL（GNDへ接続＝Vccへ接続すると写りません！）
14:SHL（GNDへ接続）
15:GND
16:GND
17:Vcc
18:Vcc
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_02.gif" rel="lightbox"><img alt="fpga_glcd_01_02.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_02-thumb.gif" width="400" height="326" align="left" /></a>
「Xilinx ISE WebPack」を起動したら、新しいプロジェクトを作るため「File」メニューの「New Project」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_01.gif" rel="lightbox"><img alt="fpga_glcd_01_01.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_01-thumb.gif" width="400" height="326" align="left" /></a>
ウイザードが開いた。今回はプロジェクト名を「GLCD」とした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_03.gif" rel="lightbox"><img alt="fpga_glcd_01_03.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_03-thumb.gif" width="400" height="326" align="left" /></a>
次の画面ではデバイスの設定をする。今回もFPGAとしてDesign Wave Magazine 2007年7月号に付属していたSpartan3Eを使うことにした。
「Family」を「Spartan3E」に、
「Device」を「XC3S250E」に、
「Package」を「VQ100」に、
「Speed」を「-4」にする。これで設定が終わりだ。あとはデフォルト設定のまま「Next」ボタンで進み、「Finish」ボタンでウイザードを閉じる。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_04.gif" rel="lightbox"><img alt="fpga_glcd_01_04.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_04-thumb.gif" width="400" height="326" align="left" /></a>
プロジェクトが作れたら次にソースコードを追加する。「Project」メニューの「New Source」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_05.gif" rel="lightbox"><img alt="fpga_glcd_01_05.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_05-thumb.gif" width="400" height="326" align="left" /></a>
ソースコードの形式は「VHDL Module」、ファイル名は「GenerateCP」とした。このソースコードは液晶パネルのCP信号（液晶に供給するクロック信号）を生成するのに使う。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_06.gif" rel="lightbox"><img alt="fpga_glcd_01_06.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_06-thumb.gif" width="400" height="326" align="left" /></a>
FPGA内のクロック信号を使って、液晶用のCP信号を生成するので、ポート名は「CLK」と「CP」、「Direction」はそれぞれ「in」と「out」にする。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_07.gif" rel="lightbox"><img alt="fpga_glcd_01_07.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_07-thumb.gif" width="400" height="326" align="left" /></a>
ソースコードが生成したら、CP信号を生成するためのVHDLを記述する。今回利用するSpartan3Eには33MHzの水晶発振子を接続している。このままではクロックが速すぎるので、5ビットのカウンターで32分周することにした。これによりCP信号は33MHz÷32＝1.031MHzのクロックになる。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:43:32 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateCP - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateCP is
    Port ( CLK : in  STD_LOGIC;
           CP : out  STD_LOGIC);
end GenerateCP;

architecture Behavioral of GenerateCP is

signal TMP : STD_LOGIC_VECTOR(4 downto 0) := &quot;00000&quot;;
begin

	process (CLK)
	begin
		if CLK'event and CLK='1' then
			TMP &lt;= TMP + &quot;00001&quot;;

			if TMP &lt; &quot;10000&quot; then
				CP &lt;= '1';
			else
				CP &lt;= '0';
			end if;
		end if;
	end process;

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_08.gif" rel="lightbox"><img alt="fpga_glcd_01_08.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_08-thumb.gif" width="400" height="326" align="left" /></a>
さらに信号を生成するためソースコードを追加する。「Project」メニューの「New Source」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_09.gif" rel="lightbox"><img alt="fpga_glcd_01_09.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_09-thumb.gif" width="400" height="326" align="left" /></a>
先ほどと同じようにソースコードの形式を「VHDL Module」にする。ファイル名は「GenerateLOAD」とした。これは液晶パネル用のLOAD信号生成用に使う。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_10.gif" rel="lightbox"><img alt="fpga_glcd_01_10.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_10-thumb.gif" width="400" height="326" align="left" /></a>
LOAD信号はCP信号を元に生成するので、ポート名で「CP」と「LOAD」を入力し、それぞれ「in」と「out」にする。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_11.gif" rel="lightbox"><img alt="fpga_glcd_01_11.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_11-thumb.gif" width="400" height="326" align="left" /></a>
ソースコードが生成したら、LOAD信号を作るためのVHDLを記述する。
LOAD信号はCP信号が100クロックごとに1クロック出るパルスとなる。生成タイミングは1列目のデータを液晶パネルに送る直前になる。タイミングチャートではCPがLowのときのみHighになるパルスだが、うまく動かなかったので最後のCP信号がHigh-Low両方のときにHighになるようにした。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:44:20 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateLOAD - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateLOAD is
    Port ( CP : in  STD_LOGIC;
           LOAD : out  STD_LOGIC);
end GenerateLOAD;

architecture Behavioral of GenerateLOAD is

signal TMP : STD_LOGIC_VECTOR( 7 downto 0 ) := &quot;00000000&quot;;
begin

	process (CP)
	begin
		if CP'event and CP='1' then
			TMP &lt;= TMP + &quot;00000001&quot;;

			if TMP = &quot;01100011&quot; then		--99
				TMP &lt;= &quot;00000000&quot;;
				LOAD &lt;= '1';
			else
				LOAD &lt;= '0';
			end if;
		end if;

	end process;

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_12.gif" rel="lightbox"><img alt="fpga_glcd_01_12.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_12-thumb.gif" width="400" height="326" align="left" /></a>
これでCPとLOAD信号を生成するためのVHDLソースができた。さらに処理をするためソースコードを追加する。
「Project」メニューの「New Source」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_13.gif" rel="lightbox"><img alt="fpga_glcd_01_13.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_13-thumb.gif" width="400" height="326" align="left" /></a>
今回はとりあえず先に作ったCPとLOAD信号を生成するモジュール同士を関連付けるためのソースコードを作る。ソースコードの形式で「VHDL Module」を、ファイル名を「GenerateSignals」にした。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_14.gif" rel="lightbox"><img alt="fpga_glcd_01_14.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_14-thumb.gif" width="400" height="326" align="left" /></a>
まだCPとLOAD信号用のVHDLしか作っていないが、実際に液晶パネルに出力することを考えて、すべての信号を定義しておく。「CLOCK」、「LOAD」、「CP」、「D」、「IO1」、「DF」を追加して、「CLOCK」を「in」に、ほかを「out」に設定する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_15.gif" rel="lightbox"><img alt="fpga_glcd_01_15.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_15-thumb.gif" width="400" height="326" align="left" /></a>
これでソースコードを修正する。ソースコード内でほかのソースコードで記述したルーチンを使うにはcomponent定義をすればいい。IO1やDFなどまだ生成用のVHDLを用意していない信号は適当な固定値を出力するようにした。
<br clear=left>
<pre class=SourceCode>----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    13:28:17 07/03/2007 
-- Design Name: 
-- Module Name:    GenerateSignals - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity GenerateSignals is
    Port ( CLOCK : in  STD_LOGIC;
           LOAD : out  STD_LOGIC;
           CP : out  STD_LOGIC;
           D : out  STD_LOGIC_VECTOR(3 downto 0);
           IO1 : out  STD_LOGIC;
           DF : out  STD_LOGIC);
end GenerateSignals;

architecture Behavioral of GenerateSignals is

signal	CP_TMP		: STD_LOGIC;
signal	LOAD_TMP		: STD_LOGIC;

component GenerateCP
    Port ( CLK : in  STD_LOGIC;
           CP : out  STD_LOGIC);
end component;

component GenerateLOAD
    Port ( CP : in  STD_LOGIC;
           LOAD : out  STD_LOGIC);
end component;

begin

	LOAD &lt;= LOAD_TMP;
	CP &lt;= CP_TMP;
	D(0) &lt;= '1';
	D(1) &lt;= '1';
	D(2) &lt;= '0';
	D(3) &lt;= '0';
	IO1 &lt;= '0';
	DF &lt;= '0';

	u0:	GenerateCP	port map(
					CLK =&gt; CLOCK,
					CP =&gt; CP_TMP);

	u1:	GenerateLOAD	port map(
					CP =&gt; CP_TMP,
					LOAD =&gt; LOAD_TMP);

end Behavioral;</pre>
<br>
<br>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_16.gif" rel="lightbox"><img alt="fpga_glcd_01_16.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_16-thumb.gif" width="400" height="326" align="left" /></a>
とりあえずここまでのソースコードの変更を保存しておく。「File」メニューの「Save All」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_17.gif" rel="lightbox"><img alt="fpga_glcd_01_17.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_17-thumb.gif" width="400" height="326" align="left" /></a>
次にこれまでに作成したCP信号とLOAD信号の生成用VHDLがきちんと意図した通りに動くかどうかPC内でシュミレーションしてみる。
「ModelSim」というシュミレーターソフトを起動する。このソフトはXilinxから無料ダウンロードできる（ただし制限が多いらしい）。Xilinx ISE WebPackにもシュミレーション機能が備わっているようだが使い方がよく分からなかったため今回はModelSimを利用した。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_18.gif" rel="lightbox"><img alt="fpga_glcd_01_18.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_18-thumb.gif" width="400" height="326" align="left" /></a>
ModelSimが起動したら「Compile」メニューの「Compile」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_19.gif" rel="lightbox"><img alt="fpga_glcd_01_19.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_19-thumb.gif" width="400" height="326" align="left" /></a>
するとファイル選択画面が開くので、ISE WebPackで作成したプロジェクトのフォルダ内にある「GenerateCP.vhd」、「GenerateLOAD.vhd」、「GenerateSignals.vhd」の3ファイルを選択して「Compile」ボタンを押す。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_20.gif" rel="lightbox"><img alt="fpga_glcd_01_20.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_20-thumb.gif" width="400" height="326" align="left" /></a>
「work」ライブラリーがないから作るかと問われたら「Yes」を選択する。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_21.gif" rel="lightbox"><img alt="fpga_glcd_01_21.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_21-thumb.gif" width="400" height="326" align="left" /></a>
これでコンパイルが終わった。「Done」ボタンを押してこの画面を閉じる。
<br clear=left>

<a href="http://www.dinop.com/2007/07/03/fpga_glcd_01_22.gif" rel="lightbox"><img alt="fpga_glcd_01_22.gif" src="http://www.dinop.com/2007/07/03/fpga_glcd_01_22-thumb.gif" width="400" height="326" align="left" /></a>
初めてModelSimを使う