
FT245RLモジュールの実験 2007.07.01(日)〜![]()
2007.11.19(月) FT245 AVRライターでATtuny26L,ATtiny2313,ATmega8,AT90S2313全てのボーレートを 9600に統一しました。 使用環境による書込み、読み出しの不安定性が改善されます。 20071119版のダウンロードはこちらです。 2007.10.05(金) FT245 AVRライター製作のページを作成しました。 2007.10.01(月) AVRライターWindows Appのダウンロードページです。 2007.09.14(金) AVRライター基板のマウント図です。IC1は半田面にマウントします。 2007.09.13(木) AVRライター基板を少しコンパクトにしました。
下は初回の切削基板。2007.09.09(日)にマウント。 2007.09.09(日) AVRライター基板に部品をマウントしました。
インサーキットプログラム用ケーブル先端のICソケットにAT90S2313が載っています。 ATtiny2313と差し換えができます。
FT245RLは半田面側にマウントします。 基板の動作テストでAT90S2313の読み出しエラーがあり、BitBangモードのボーレート を9600ボーに変更しました。 19200ボー : ATtiny26L 14400ボー : ATtiny2313, ATmega8 9600ボー : AT90S2313 2007.09.07(金) AVRライター基板のパターンとFT245RL端子です。(未半田)
パッケージはSSOP。端子ピッチ=0.65mm。端子幅=0.30mm。 2007.09.04(火) ROMライタにAT90S2313を追加しました。
2007.08.31(金) AVRアセンブラーの練習資料を作成しました。 LessonAをご覧下さい。 2007.08.26(日) AVRライター用基板のパターンを切削しました。
2007.08.25(土)
AVRライター用片面プリント基板のパターンです。 大きさは50×55です。 2007.08.24(金) AVRライターの回路図(pdf)です。 FT245RLの端子番号はIC(SSOPパッケージ)に対応しています。 2007.08.21(火) PCの電源をオンしてからのFT245のPWREN#とRXF#の信号波形です。
上:PWREN# 下:RXF# PC電源オン ↓ ┌─┬─┬──┬───┬┬┐ │ │ │ │ │││ PWREN# ──┘ └┴┴─────── ┌─────── ┌─┬─┼──┬───┬┬┤ RXF# ──┘ →│ │←56.8sec エニュメレーション期間 FT245のデータシートでは、PWREN#で周辺デバイスへの電源を制御することを推奨して います。 エニュメレーション期間中のRWREN#は不安定ですが、ATmega8の電源供給の制御を行 うようにしました。 USB 5V ──────●──┐ │ ┌┴┐2SA1015 │ │E │ R10K │C ├──→ ATmega8のVccへ │ │B │ │ └┬┘ PWREN# ── R2.2K─●──┘ ATmega8のリセットスタートで各種の初期化後、1秒間連続したRXF#=1を確認してから データ受信やコマンド解析に移行するようにしました。 2007.08.20(月)
ATmega8がFT245から1000バイトを読み出してSRAMに格納している時の、 FT245のRD信号波形です。 →│ │←4.24msec ──┬─┬┬──────┬────── RD └─┘└──────┘ →│ │←1.04msec →││←0.28msec →│ │←2.92msec USB回線かWindows OSの都合で、0.28msecの休止期間があります。 読み出しレートは、233.6Kbyte/sec。 4.28usec/byte。 これには、SRAMへのデータ格納と平行してSRAMからデータを読み出して、 コマンドを解析する処理も含みます。 ┌─────┐RD ┌────┐ │FT245 FIFO├──→┤ATmega8 │ └─────┘格納 │ SRAM │読み出し │ 1Kbyte ├────→ コマンド解析 └────┘ リングバッファー構成 2007.08.19(日) ATmega8でステッピングモータを回しました。 SLA7078を16分割マイクロステップに設定。 | ATmega8のステップ倍率 | 8倍 16倍 回転数(rpm) | 偏差% 偏差% 備考 ------------+-------+-------+-------------------- 100 2.9 3.0 500 1.9 3.0 1000 -2.3 -2.3 1200 -0.6 -3.4 1500 -5.3 -3.8 1600 * -4.7 1700 * -5.7 コッキング気味 *はモータ回転せず 2007.08.18(土) リングバッファーのデータ読み出しと書き込みタイミングです。
→│ │←3.6usec ┌──┐ 読出 ──┘ └───────────── →││←1.76usec ──────┐┌──┐┌─────── 書込 └┘ └┘ (FT245 RD) →│ │←4.4usec 読出は、ステップパルス出力コマンドと続くステップパルスデータの2バイト分です。 書込は、FT245のRDを2回操作し、2バイトをリングバッファーに書き込みます。 ニブル転送からバイト転送に変更したことで、FT245のFIFOから2バイトを読み出す時 間が7.2usecから4.4usecに改善できました。 リングバッファーの容量増で、1バイト長から2バイト長に拡張したデータポインター や残量カウンタの処理で命令数が増加し、7.2usec/2よりも時間が掛ります。 2007.08.16(木) ATtiny2313からATmega8へマイコンの変更を検討中です。 ROMライタにATmega8を追加しました。
ATtiny231とATmega8の比較(概要) 項目 ATtiny2313 ATmega8 ---------------+-------------------------+---------------------------- ROM 1Kバイト 8Kバイト SRAM 128バイト 1Kバイト EEPROM 128バイト 512バイト CLOCK 内蔵RC発振8MHz 内蔵RC発振8MHz 最大20MHz。20MIPS。 最大16MHz。16MIPS。 I/O 汎用17ポート 汎用23ポート PA0-1,PB0-7,PD0-6 PB0-7,PC0-6,PD0-7 PWM 4ch 3ch パッケージ 20ピンDIP 28ピンDIP 単価 \120 \399 改善点: 1) データ転送レートが約2倍。ニブル単位のデータ送信をバイト単位に変更。 2) リングバッファーの容量が約8.3倍。120バイトから1000バイトに変更。 3) 残りのポート数が増える。2ポートから4ポートに。 2007.08.12(日) CNCの実験では、200ステップ/回転のステッピングモータを1-2相駆動で使用し、 送りネジのピッチが1mm、最小の送り量は2.5umで、基板加工機としては十分に実用的 な分解能です。 16分割マイクロステップ駆動による滑らかなモータ回転と、分解能2.5u/stepを少な いデータ量で実現する為に、ステップn倍モードを検討しました。 1) ドライバー(SLA7078)を16分割のマイクロステップに設定。 2) PCで生成するステップパルスは、400パルス/回転。1-2相駆動と同じです。 3) PCからの1ステップ指示で、ATtiny2313は8倍(個)のステップパルスを出力。 PCから2ステップを指示すると16ステップでモータは1.8°回転。 PCが生成するステップパルス ┌┐ ┌┐ ┌┐ ─┘└──────────────┘└──────────────┘└── ATtiny2313が出力するステップパルス(クロック) ┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐┌┐ ─┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└┘└ ATtiny2313リングバッファー残量モニタ波形
1500rpm。16分割マイクロステップ。ATtiny2312はステップ8倍モード。 フォームのメニューバー上でマウスカーソルを左右に移動しました。 時間軸:2mse/DIV。電圧軸:1V/DIV。データフルで約1.8V。 3.44msecで400mV降下する事から、120バイト:1.8V=X:0.4V → X=27バイト。 残量は93バイトです。 16分割マイクロステップとステップn倍モードの組合せは、送りの分解能、高速な送 り、ハードの簡易性、ソフトの容易性、データ送信の軽量化、静かな回転、のいずれ にも好ましい結果が得られそうです。 2007.08.10(金) マウスカーソルを動かしリングバッファーのデータ残量をモニターしました。
16分割、500rpmで測定。 9.4msec周期でデータ残量が減少します。 フォームのフォーカスを切り換えた場合も、リングバッファーにデータの補充が行わ れず、フォームのサイズが大きいとその期間は300msec以上になります。 2007.08.08(水) ATtiny2313のSRAMをリングバッファー構成にしました。 バッファーが常にフルになるように、FT245から読み出したデータを格納します。 ステップパルスインターバルに同期して読み出し、順次PORTBへ出力します。 リングバッファーへの書き込みポインターにXレジスター、読み出しポインターにYレ ジスターを使用。 リングバッファーのデータ残量はR20レジスタに割り当てました。 バッファーの容量は120バイトで、SRAMの残り8バイトはスタック用です。 $60 120バイト $D7 │←───────────〜───────────→│ X↓ →書き込み方向 ┌─┬─┬─┬─┬─┬─┬〜┬─┬─┬─┬─┬─┬─┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │→先頭へ繋ぎます┐ └─┴─┴─┴─┴─┴─┴〜┴─┴─┴─┴─┴─┴─┘ │ Y↓ →読み出し方向 │ ↑ │ └──────────────────────────────────┘ 750rpmに於けるデータ残量をPWMで出力した時の波形です。
およそ17.2msec毎に残量が少なくなります。 PC→FT245へのデータ送信が停滞すると残量が減少します。 右端では残量が0バイトになり、ステップ用クロックが欠落した可能性があります。 700rpmではデータ残量の変動幅が減少し、データフルの状態が多くなります。 ステップ用クロックの欠落はありません。
リングバッファーを使用しない方式では、340rpmを超えるとステップ用クロックが 欠落します。 測定条件:1) 16分割マイクロステップ。フルステップ角=1.8°(200ステップ/回転)。 2) PWM出力は積分フィルターR=47K,C=0.01uFで平滑。 3) PWMのカウンタークロック=8MHz。 4) Windows Appでは Application.DoEvents(); をコメントアウトし、 マウス操作等のイベントによるデータ送信の途切れを防止。 2007.08.05(日) RDを4回操作して2バイトのコマンドをATtiny2313が読み出します。
上:COLCK。SLA7078MPRへのクロック信号。 下:RD。FT245RLへの読み出し制御信号。 →│ │←19.4usec(実測966rmp/設定1000rpm) →││←2usec ┌┐ ┌┐ CLOCK ───┘└───────────┘└────────── ──────┐┌┐┌┐┌┐┌─────┐┌┐┌┐┌┐┌─ RD └┘└┘└┘└┘ └┘└┘└┘└┘ →│ │←6usec →│ │←7.2usec →│ │←6.2usec 2バイトのコマンド読み出しは、次のCLOCK出力の前に完了します。 条件:16分割マイクロステップ。フルステップ角=1.8°(200ステップ/回転) で1000rpmに設定。 コマンドの1バイト目 上位4ビット 下位4ビット ┌─────┬─────┐ │コマンド長│ コマンド │ └─────┴─────┘ コマンドの2バイト目 ┌───────────┐ │ DIRとCLOCK │X,Y,Z,Aの4軸分の設定が可能です。 └───────────┘ PCからFT245のFIFOへのデータ転送が間に合わ無い場合に、ATtiny2313が擬似CLOCKを 出力するようにしました。 擬似クロック出力のモニタパルス波形です。
┌──┐ ┌──┐ モニタパルス ──┴──┴────────┴──┴───── →│ │←520usec →│ │←2.96msec 擬似クロックを併用し、1500rpmでステップモータを回しました。 動画はbriefcase.yahooから削除されました。2009.02.01。 2007.08.04(土) ATtiny2313用のプログラムをCからasmに置き換えて回転速度偏差を測定しました。 偏差(%)=(パルス幅計算値-パルス幅実測値)÷パルス幅計算値×100 モータはステップ数/回転=200ステップ、回転角度/ステップ=1.8°を想定。 1) 1-2相制御 rpm 100 1000 2000 3000 4000 -------+------+------+------+------+------ 偏差(%) +2.2 +1.3 +0.4 0.0 +0.4 2) 16分割マイクロステップ制御 rpm 100 200 500 700 800 900 975 -------+------+------+------+------+------+------+------- 偏差(%) +2.9 +1.0 -0.2 -1.5 -2.5 -3.7 不安定 3) プログラムサイズ比較 言語 プログラムバイト数 ------+--------------------- C 516 asm 248 4) マイコンクロック 内蔵RC発振 8MHzを使用。 2007.08.02(木) ATtiny2313用のプログラムをCからasmへの置き換えを検討中。 プログラムバイト数の比較 言語 プログラムバイト数 ------+--------------------- C 516 asm 254 命令数の減少で、モータの最高回転数が上がりそうです。 2007.07.31(火) 回転方向、駆動方式の選択機能を設けました。
1) 1-2相駆動 各相出力信号(CW)。ステップ/回転=400。200rpm。
上からA相、-A相、B相、-B相 →│ │←2.18msec(3step分) ┌─────┐ ┌─ A相 ───┘ └─────────┘ ┌─────┐ -A相 ───────────┘ └─── ┌─────┐ B相 ───────┘ └─────── ─────┐ ┌───── -B相 └─────────┘ │ │ │ │ │ │ │ │ │ │ │ 回転速度偏差(%)。ステップ/回転=400。 rpm 100 200 500 1000 2000 -----+-------+-------+-------+-------+-------- 偏差 +3.1 +3.1 +3.1 -0.4 -4.0 2) マイクロステップ 16分割(CCW→CW)
上:DIR信号 下:クロック信号 ┌────────── DIR ───┘ ┌──┐ クロック─────┘ └───── →│ │←2.12usec →│ │←3.16usec クロック信号。ステップ/回転=200。16分割。回転数=200rpm。
→│──────│←96usec ┌┐ ┌┐ クロック ──┘└─────┘└──── 回転速度偏差(%)。ステップ/回転=200。16分割。 rpm 100 200 500 550 600 650 -----+-------+-------+--------+--------+--------+--------- 偏差 +1.3 -3.2 -10.1 -13.7 -15.2 不安定 *速度偏差はステップパルス幅の実測値から求めました。 ATtiny2313用プログラム (WinAVR) 注) シフト演算子<<は全角で表示しています。 //***************************************************************************** // Project : IO // Version : 001 // Date : 2007.07.23 - 2007.07.29 // Author : Yoshitomo Nakano // Company : ioio // Compiler : WinAVR // Chip type : ATtiny2313 // Clock frequency : 内蔵RC8MHz(8MHz*1/1) // 機能 : FT245からデータを受信し、ステップモータ回転パルスを発生 //***************************************************************************** // 変更履歴 // 2007.07.23(月) 作成開始 // 2007.07.28(土) rx_command関数を追加 // //***************************************************************************** // 機能 : インクルード // 作成開始 : 2007.07.23(月) //***************************************************************************** #include "io.h" #include "interrupt.h" #include "signal.h" //***************************************************************************** // 機能 : 関数 // 作成開始 : 2007.07.28(土) // 最新修正 : // 注意 : //***************************************************************************** unsigned char rx_command(void); //***************************************************************************** // 機能 : 広域変数 // 作成開始 : 2007.07.26(木) // 最新修正 : 2007.07.30(月) //***************************************************************************** static unsigned char volatile tccr0b_tmp; // プリスケーラー値保存 static unsigned char volatile tcnt0_tmp; // タイマ0カウンタ値保存 static unsigned char volatile port_buf; // PORTB出力値保存 static unsigned char volatile rx_data[16]; // 受信データ static unsigned char volatile rx_enable; // コマンド受信許可 static unsigned char volatile micro_step; // マイクロステップ //***************************************************************************** // 機能 : 定数 // 作成開始 : 2007.07.23(月) // 最新修正 : 2007.07.28(土) //***************************************************************************** #define WR PD4 // FT245 WR Out #define RD PD5 // FT245 RD Out #define RXF PD6 // FT245 RXF In #define PD_READ 0x30 // FT245 READ, b6=In,b5-b4=Out,b3-b0=In #define PD_WRITE 0x3F // FT245 WRITE, b6=In,b5-b4=Out,b3-b0=OUt #define T100USEC 256 - 3 // タイマー0設定値=約100usec #define T1MSEC 256 - 31 // タイマー0設定値=約1msec #define PA_OUT 1 #define PA_IN 2 #define PB_OUT 3 #define PB_IN 4 #define PD_OUT 5 #define PD_IN 6 #define SET_TIMER0 7 #define PHASE_STEP 8 #define MICRO_STEP 9 //***************************************************************************** // 機能 : ポートマップ // 作成開始 : 2007.07.31(火) // 最新修正 : 2007.07.31(火) //***************************************************************************** // Name Pin I/O Use // PB0 12 O A相 / CLOCK // PB1 13 O -A相 / DIR // PB2 14 O B相 // PB3 15 O -B相 // // PD0 2 I Data0/Data4 // PD1 3 I Data1/Data5 // PD2 6 I Data2/Data6 // PD3 7 I Data3/Data7 // PD4 8 O WR# 立下りでデータ書き込み // PD5 9 O RD# 立下りでデータ読み出し // PD6 11 I RXF Lowで読み出し可 //***************************************************************************** // 機能 : 割込み関数 // 作成開始 : 2007.07.26(木) // 概要 : iotn2313.h参照 //***************************************************************************** //SIGNAL (SIG_TIMER0_OVF){} // タイマー0 //***************************************************************************** // 機能 : メイン関数 // 関数 : int main( void ) // 引数 : 無し // 戻値 : 無し // 作成開始 : 2007.07.23(月) // 最新修正 : 2007.07.29(日) // 概要 : コマンド分析 //***************************************************************************** int main(void) { // ローカル変数 // 入出力ポート初期化 // Port A 初期化 // b0-b1=Out, b2=In //PORTA=0x00; //DDRA=0x03; // Port B 初期化 // b0-b7=Out PORTB=0x00; DDRB=0xFF; // Port D 初期化 // b6=In,b5-b4=Out,b3-b0=In, b3-b0=PU, b6(RXF)=PU PORTD= 0xFF; DDRD=PD_READ; // Timer/Counter 0 初期化 //TCCR0A=0x00; // 標準動作 TIMSK |= (1<<TOIE0); // タイマ0 オーバーフロー割込み許可 TCNT0 = T1MSEC; // タイマ0カウンタ=0.992msec=32usec*31 TCCR0B = 0x04; // タイマ0スタート。プリスケール1/256。32usec。 // アナログ比較器初期化 ACSR=(1<<ACD); // アナログ比較器電源オフ // ウォッチドッグ(WD)禁止 __asm__ ("WDR" ::); // WD タイマリセット MCUSR &= ~(1<<WDRF); // WD リセットフラグ(WDRF)解除 WDTCSR |= (1<<WDCE)|(1<<WDE); // WDCEとWDEに論理1書き込み WDTCSR = 0x00; // WD禁止 sei(); // 全割り込み許可 port_buf = 0; // ポートバッファー設定 PORTB = port_buf; // ポートBへ出力 tcnt0_tmp = T1MSEC; // タイマ0カウンタ値保存 TCCR0B = 0x04; // タイマ0スタート。プリスケール1/256。32usec。 tccr0b_tmp = 0x04; // プリスケーラー値保存 rx_enable = 1; // コマンド受信許可 micro_step = 0; // 1,2,1-2相駆動に設定 while (1){ if(rx_command() > 0){ switch(rx_data[0] & 0x0F){ case PB_OUT: port_buf = rx_data[1]; break; case SET_TIMER0: cli(); tccr0b_tmp = rx_data[1]; // プリスケーラー値保存 tcnt0_tmp = rx_data[2]; // タイマ0カウンタ値保存 sei(); break; case PHASE_STEP: micro_step = 0; break; case MICRO_STEP: micro_step = 1; break; default: break; } } } } //***************************************************************************** // 機能 : コマンド受信 // 引数 : 無し // 戻値 : コマンドバイト長 // 作成開始 : 2007.07.28(土) // 最新修正 : 2007.07.28(土) // 概要 : ニブルごとに受信 //***************************************************************************** unsigned char rx_command(void) { unsigned char in_buf = 0; // 入力バッファー unsigned char temp; // 入力データ一時保管 unsigned char rx_len = 0; // 受信バイト長 unsigned char byte_count = 0; // 受信バイトカウンタ unsigned char *rx_data_ptr; // 受信データ格納先ポインター struct { unsigned rx:1; // 受信有無 unsigned odd:1; // 奇数フラグ } flg; flg.rx = 0; // 受信無し flg.odd = 0; // 偶数から開始 rx_data_ptr = &rx_data; // 受信データ格納先設定 while(rx_enable){ if(!(PIND & (1<<RXF))){ // RXF=0なら PORTD &= ~(1<<RD); // RD立下げ __asm__ ("nop" ::); // 出力安定待ち in_buf = (PIND & 0x0F); // 下位4ビット読み出し PORTD |= (1<<RD); // RD立上げ if(flg.odd == 0){ // 0,2,4,6...偶数回目なら temp = in_buf; // 入力を一時保存 flg.odd = 1; // 次は奇数回目 }else{ // 1,3,5,7...奇数回目なら byte_count++; // 受信バイトカウンタ更新 if(byte_count == 1){ // 1バイト目なら rx_len = in_buf; // バイト長保存 } in_buf <<= 4; // 上位4ビットへシフト temp |= in_buf; // 1バイトに合成 *rx_data_ptr = temp; // バイトデータ格納 rx_data_ptr++; // 格納先更新 if(byte_count >= rx_len){ // コマンドバイト長に一致したら rx_enable = 0; // コマンド受信禁止 break; // while分終了 } flg.odd = 0; // 次は偶数回目 } flg.rx = 1; }else if(flg.rx == 0){ // RXF=1で受信無しなら break; // while分終了 } } return rx_len; // 受信バイト長が戻り値 } //***************************************************************************** // 機能 : タイマー0オーバーフロー割込み // 引数 : 無し // 戻値 : 無し // 作成開始 : 2007.07.26(木) // 最新修正 : 2007.07.28(土) // 概要 : プリスケーラー、タイマカウント、ポート出力 // 処理 : TOVFは自動リセット //***************************************************************************** SIGNAL (SIG_TIMER0_OVF) { TCNT0 = tcnt0_tmp; // タイマ0カウンタ設定 TCCR0B = tccr0b_tmp; // タイマ0プリスケーラー設定 if(micro_step == 1 && rx_enable == 0){ // マイクロステップで受信済みなら PORTB = port_buf & 0x02; // DIR=ON, CLOCK=OFF dly2u(); // 2usec遅延 PORTB = port_buf; // DIR=ON, CLOCK=ON port_buf &= 0xAA; // CLOCKビット=0 dly2u(); // 2usec遅延 PORTB = port_buf; // DIR=ON, CLOCK=OFF }else{ // 1,2,1-2相駆動なら PORTB = port_buf; // ステップデータ設定 } rx_enable = 1; // 次のコマンド受信許可 } //***************************************************************************** // 機能 : 2usec遅延 // 作成開始 : 2007.07.30(月) // 最新修正 : 2007.07.30(月) // 概要 : クロック8MHz(8MHz*1/1)。callとret命令を含めて概略2usec。 //***************************************************************************** void dly2u(void) { __asm__ ( "nop" ::); __asm__ ( "nop" ::); __asm__ ( "nop" ::); __asm__ ( "nop" ::); __asm__ ( "nop" ::); __asm__ ( "nop" ::); __asm__ ( "nop" ::); } 2007.07.29(日) ステッピングモータを回しました。
5V、7.5°/stepのステッピングモータは、320rpmまで脱調せずに回りました。 PC AppからATtiny2313のタイマ0にステップ間隔の設定値と、PORTBにステップパルス データを送信します。 クロック8MHzの場合、ステップパルスの間隔は32usecから32msecです。 従って、 1-2相駆動方式で ステップ数/回転 96 400 -------------------+---------+--------- 最高回転速度(rpm) 19,532 4,688 最低回転速度(rpm) 19 4.7 マイクロステップ駆動で (200step/revモータの場合) 分割 4 8 16 -------------------+---------+--------+-------- ステップ数/回転 800 1600 3200 -------------------+---------+--------+-------- 最高回転速度(rpm) 2,344 1,171 586 最低回転速度(rpm) 2.4 1.2 0.6 の設定が可能です。 2007.07.27(金) PC AppからLED点滅データを送信し、ATtiny2313のタイマ0で約1msec毎にPORTBに出力 しました。
パルス幅=0.97msec。 立上りと立下りで計8回スイッチングします。 ATtiny2313用プログラム (WinAVR) 注) シフト演算子<<は全角で表示しています。 //***************************************************************************** // Project : IO // Version : 001 // Date : 2007.07.23 - 2007.07.27 // Author : Yoshitomo Nakano // Company : ioio // Compiler : WinAVR // Chip type : ATtiny2313 // Clock frequency : 内蔵RC8MHz(8MHz*1/1) // 機能 : FT245の汎用I/O //***************************************************************************** // 変更履歴 // 2007.07.23(月) 作成開始 // 2007.07.27(金) タイマ0割込みでポート出力 // //***************************************************************************** // 機能 : インクルード // 作成開始 : 2007.07.23(月) // 最新修正 : 2007.07.27(金) // 注意 : //***************************************************************************** #include "io.h" #include "interrupt.h" #include "signal.h" //***************************************************************************** // 機能 : 広域変数 // 作成開始 : // 最新修正 : // 注意 : //***************************************************************************** static unsigned char volatile in_buf; static unsigned char volatile port_buf; static unsigned char volatile in_count; //***************************************************************************** // 機能 : 定数 // 作成開始 : 2007.07.23(月) // 最新修正 : 2007.07.26(木) // 注意 : //***************************************************************************** #define WR PD4 // FT245 WR Out #define RD PD5 // FT245 RD Out #define RXF PD6 // FT245 RXF In #define PD_READ 0x30 // FT245 READ, b6=In,b5-b4=Out,b3-b0=In #define PD_WRITE 0x3F // FT245 WRITE, b6=In,b5-b4=Out,b3-b0=OUt #define T100USEC 256 - 3 // タイマー0設定値=約100usec #define T1MSEC 256 - 31 // タイマー0設定値=約1msec //***************************************************************************** // 機能 : 割込み関数 // 作成開始 : 2007.07.26(木) // 概要 : iotn2313.h参照 //***************************************************************************** //SIGNAL (SIG_TIMER0_OVF){} // タイマー0 //***************************************************************************** // 機能 : メイン関数 // 関数 : void main( void ) // 引数 : 無し // 戻値 : 無し // 作成開始 : 2007.07.23(月) // 最新修正 : 2007.07.26(木) //***************************************************************************** void main(void) { // 入出力ポート初期化 // Port B 初期化 // b0-b7=Out PORTB=0x00; DDRB=0xFF; // Port D 初期化 // b6=In,b5-b4=Out,b3-b0=In, b3-b0=PU, b6(RXF)=PU PORTD= 0xFF; DDRD=PD_READ; // Timer/Counter 0 初期化 //TCCR0A=0x00; // 標準動作 TIMSK |= (1<<TOIE0); // タイマ0 オーバーフロー割込み許可 TCNT0 = T1MSEC; // タイマ0カウンタ=0.992msec=32usec*31 TCCR0B = 0x04; // タイマ0スタート。プリスケール1/256。32usec。 // アナログ比較器初期化 ACSR=(1<<ACD); // アナログ比較器電源オフ // ウォッチドッグ(WD)禁止 __asm__ ("WDR" ::); // WD タイマリセット MCUSR &= ~(1<<WDRF); // WD リセットフラグ(WDRF)解除 WDTCSR |= (1<<WDCE)|(1<<WDE); // WDCEとWDEに論理1書き込み WDTCSR = 0x00; // WD禁止 sei(); // 全割り込み許可 in_buf = 0; in_count = 0; port_buf = 0; PORTB = port_buf; while (1){ if(!(PIND & (1<<RXF))){ if(in_count == 0){ PORTD &= ~(1<<RD); // RD立下げ __asm__ ("nop" ::); // 出力安定待ち in_buf = (PIND & 0x0F); // 下位4ビット読み出し PORTD |= (1<<RD); // RD立上げ in_count = 1; }else if(in_count == 1){ //TCNT0 = T1MSEC; PORTD &= ~(1<<RD); // RD立下げ __asm__ ("nop" ::); // 出力安定待ち in_buf |= (PIND<<4) & 0xF0; // 上位4ビット読み出し PORTD |= (1<<RD); // RD立上げ port_buf = in_buf; in_count = 2; } } } } //***************************************************************************** // 機能 : タイマー0オーバーフロー割込み // 作成開始 : 2007.07.26(木) // 最新修正 : 2007.07.26(木) // 処理 : TOVFは自動リセット //***************************************************************************** SIGNAL (SIG_TIMER0_OVF) { TCNT0 = T1MSEC; if(in_count == 2){ in_count = 0; PORTB = port_buf; } } Windows Appプログラム (VC#) //------------------------------------------ // スタートメニュークリックイベント //------------------------------------------ unsafe private void startSToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 writen = 0; int n; Byte [] data = new Byte[5120]; FT245_Open(); for (n = 0; n < 16; ) { data[n++] = 0x00; // even下位 data[n++] = 0x00; // even上位 data[n++] = 0x0F; // odd下位 data[n++] = 0x0F; // odd上位 } FT_Write(ftHandle, data, 16, &writen); FT245_Close(); } 2007.07.25(水) FIFO RXF/RD#ハンドシェークでLEDを点滅しました。 LED点滅波形
パルス幅=4.08usec 点滅データ512バイトを10回送信
FT_Write()実行毎にバーストします。 バーストON=1.12msec。バーストOFF=0.84msec。全長=19.6msec。 点滅データ5120バイトを1回で送信
連続してLEDが点滅します。 全長=11.0msec。 接続図 ┌──┐ ┌──┐ ┌──┐ │ │USBケーブル │FT- │ DB0-DB3 │AT │ PORTB0-7 │ PC ├──────┤245 ├──//──┤tiny├─//─R220─┐ │ │ │RL │ RXF,RD# │2313│ ▼ LED └──┘ └──┘ └──┘ ┬ │ ┴ データ送信の流れ ┌────┬────┐ │上位4bit│下位4bit│元データ └────┴────┘ │ └──────────┐ └────┐ │ ↓ ↓ ┌────┬────┐┌────┬────┐ │ │上位4bit││ │下位4bit│PCのAppで2バイトに分割 └────┴────┘└────┴────┘それぞれ下位バイトに設定します。 │ ↓ ↓ evenバイト送信 oddバイト送信 │ │ │ ┌─┘ ┌───────┘ ↓ ↓ ┌────┬────┐ │上位4bit│下位4bit│ATtiny2313で1バイトに合成 └────┴────┘ ↓ PORTBへ出力 タイミングチャート ───┐ ┌┐ ┌┐ ┌┐ RXF └───┘└───┘└───┘└─── ────┐ ┌─┐ ┌─┐ ┌─┐ RD# └──┘ └──┘ └──┘ └── ────┬──┬─┬──┬─┬──┬─┬── DB0-DB3 ────┴──┴─┴──┴─┴──┴─┴── even odd even odd FIFOにデータが入っている場合、RXFはRD#↑でHighになりMIN80nsecでLowになります 。 RXF=Highを確認した後にRD#をLowにしたいところですが、マイコンのクロックが 8MHzで0.125usec/命令では、80nsecの変化にポート入力チェックが追従できないため 、RXFがLowならば次のデータを読み込みます。 RXFの立下りエッジで割込みを利用する方法は次の課題です。 ポートマップ ATtiny2313のPORTDの下位4ビットを双方向のデータバスに、上位3ビットを制御信号と して使用します。 FT245 | ATtiny2313 | Asign | No | I/O | Asign | No | I/O | 機能 -------+----+-----+-------+----+-----+-------------------------------- RXF 23 O PD6 11 I 制御信号。Lowで読み出し可 RD# 12 I PD5 9 O 制御信号。立下りで読み出し WR# 18 I PD4 8 O 制御信号。立下りで書き込み TXE - - - - - 使用せず DB7 8 - - - - 使用せず DB6 7 - - - - 使用せず DB5 6 - - - - 使用せず DB4 5 - - - - 使用せず DB3 4 I/O PD3 7 O/I Data3/Data7 DB2 3 I/O PD2 6 O/I Data2/Data6 DB1 2 I/O PD1 3 O/I Data1/Data5 DB0 1 I/O PD0 2 O/I Data0/Data4 ATtiny2313用プログラム 注意:シフト記号<<は全角で表示しています。 利用する場合には半角に直して下さい。 //***************************************************************************** // Project : IO // Version : 001 // Date : 2007.07.23 - 2007.07.25 // Author : Yoshitomo Nakano // Company : ioio // Compiler : WinAVR // Chip type : ATtiny2313 // Clock frequency : 内蔵RC8MHz(8MHz*1/1) // 機能 : FT245の汎用I/O //***************************************************************************** // 変更履歴 // 2007.07.23(月) 作成開始 // //***************************************************************************** // 機能 : インクルード // 作成開始 : 2007.07.23(月) // 注意 : //***************************************************************************** #include "io.h" //***************************************************************************** // 機能 : 定数 // 作成開始 : // 最新修正 : // 注意 : //***************************************************************************** #define WR PD4 // FT245 WR Out #define RD PD5 // FT245 RD Out #define RXF PD6 // FT245 RXF In #define PD_READ 0x30 // FT245 READ, b6=In,b5-b4=Out,b3-b0=In #define PD_WRITE 0x3F // FT245 WRITE, b6=In,b5-b4=Out,b3-b0=OUt //***************************************************************************** // 機能 : メイン関数 // 関数 : void main( void ) // 引数 : 無し // 戻値 : 無し // 作成開始 : 2007.07.23(月) // 最新修正 : 2007.07.25(水) // 概要 : LEDのON・OFFデータを生成し、FT245RLへ出力します。 //***************************************************************************** void main(void) { // ローカル変数 unsigned char in_count = 0; unsigned char in_buf = 0; // Port B 初期化 // b0-b7=Out PORTB=0x00; DDRB=0xFF; // Port D 初期化 // b6=In,b5-b4=Out,b3-b0=In, b6(RXF)=PullUp PORTD=(1<<RD) | (1<<WR) | (1<<RXF); DDRD=PD_READ; // アナログ比較器初期化 ACSR=(1<<ACD); // アナログ比較器電源オフ // ウォッチドッグ(WD)禁止 __asm__ ("WDR" ::); // WD タイマリセット MCUSR &= ~(1<<WDRF); // WD リセットフラグ(WDRF)解除 WDTCSR |= (1<<WDCE)|(1<<WDE); // WDCEとWDEに論理1書き込み WDTCSR = 0x00; // WD禁止 while (1){ if(!(PIND & (1<<RXF))){ // 読み出し可なら PORTD &= ~(1<<RD); // RD立下げ if(in_count == 0){ in_buf = (PIND & 0x0F); // 下位4ビット読み出し PORTD |= (1<<RD); // RD立上げ in_count++; }else{ in_buf |= (PIND<<4) & 0xF0; // 上位4ビット読み出し PORTD |= (1<<RD); // RD立上げ PORTB = in_buf; // LEDへ出力 in_count = 0; } } } } Windows App(VC#) //------------------------------------------ // スタートメニュークリックイベント //------------------------------------------ unsafe private void startSToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 writen = 0; int n; int i; Byte [] data = new Byte[5120]; FT245_Open(); for (i = 0; i < 10; i++) { for (n = 0; n < 512; ) { data[n++] = 0xF0; // evenの下位4ビット data[n++] = 0xF0; // evenの上位4ビット data[n++] = 0x0F; // oddの下位4ビット data[n++] = 0x0F; // oddの上位4ビット } // データ送信 FT_Write(ftHandle, data, 512, &writen); } FT245_Close(); } //------------------------------------------ // FT245モジュールとの通信を開く //------------------------------------------ unsafe private bool FT245_Open() { UInt32 ftH; // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return false; } // デバイスハンドルをコピー ftHandle = ftH; return true; } //------------------------------------------ // FT245モジュールとの通信を閉じる //------------------------------------------ unsafe private void FT245_Close() { if(ftHandle != 0) { // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); } } 2007.07.23(月) ATtiny2313にプログラムを書き込みました。
ポートBに0xFFと0x00を繰返し出力します。
Hパルス幅=1usec。繰返し周期=3.96usec。 注記: 左シフト記号(<<)は、表示の関係で全角文字を使用しました。 コンパイルをする場合は、半角文字に変更してください。 //*************************************************************************** // Project : LED1 // Version : 001 // Date : 2007.07.22 - 2007.07.23 // Author : Yoshitomo Nakano // Company : ioio // Compiler : WinAVR // Chip type : ATtiny2313 // Clock frequency : 内蔵RC1MHz(8MHz*1/8) //*************************************************************************** // 変更履歴 // 2007.07.22(日) LED1 tiny26L版から移植。FT245 ROMライター確認用。 // //*************************************************************************** // 機能 : インクルード // 作成開始 : 2007.07.22(日) //*************************************************************************** #include "io.h" //*************************************************************************** // 機能 : メイン関数 // 関数 : void main( void ) // 引数 : 無し // 戻値 : 無し // 作成開始 : 2007.07.22(日) // 最新修正 : 2007.07.23(月) // 概要 : PORTBに接続したLEDの点滅 // 処理 : 1) 8ビット全部に1を出力。 // : 2) 8ビット全部に0を出力。 // : 3) 1)と2)を繰返す。 //*************************************************************************** void main(void) { // Port B 初期化 // b0-b7=Out PORTB=0x00; // ポートBの全ビットに0を出力 DDRB=0xFF; // ポートBの全ビットを出力に設定 // アナログ比較器初期化 ACSR=(1<<ACD); // アナログ比較器電源オフ // ウォッチドッグ(WD)禁止 __asm__ ("WDR" ::); // WDタイマリセット MCUSR &= ~(1<<WDRF); // WDリセットフラグ(WDRF)解除 WDTCSR |= (1<<WDCE)|(1<<WDE); // WDCEとWDEに論理1書き込み WDTCSR = 0x00; // WD禁止 while (1){ PORTB=0xFF; // ポートBの全ビットに1を出力 PORTB=0x00; // ポートBの全ビットに0を出力 }; } 2007.07.22(日) 「電源」「入り」「切り」を追加しました。
ROM書きこみ後、「電源」「入り」のクリックで プログラムの動作確認が出来て便利です。 「入り」タイミングチャート ┌───────────── 電源 ───┘ ┌───┐ リセット ─┘ └─────────── →│ │←20msec →│ │←20msec 「切り」タイミングチャート(電源入り状態から) ─────────┐ 電源 └─────── ┌───────── リセット ───────┘ →│ │←20msec FT245のMOSI、MISO、SCK用ポートは入力に設定します。 (通常FT245の入力ポートは、200KΩでプルアップされます。) //------------------------------------------ // 電源「入り」 //------------------------------------------ unsafe private void 入りoolStripMenuItem_Click(object sender, EventArgs e) { UInt32 ftH; UInt32 Writen = 0; // FUSE書込 メニューのクリック禁止 送信TToolStripMenuItem.Enabled = false; // ロックビット書込 メニューのクリック禁止 書込WToolStripMenuItem1.Enabled = false; // リストボックスをクリア listBox1.Items.Clear(); // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { MessageBox.Show("注意", "FT245との通信に失敗しました。"); return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定 ftStatus = FT_SetBitMode(ftHandle, 0x30, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // 20msec遅延 Msec_Delay(20); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET OFF port_buf = POWER_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // FT245との通信を閉じる ftStatus = FT_Close(ftHandle); } //------------------------------------------ // 電源「切り」 //------------------------------------------ unsafe private void 切りKToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 ftH; UInt32 Writen = 0; // FUSE書込 メニューのクリック禁止 送信TToolStripMenuItem.Enabled = false; // ロックビット書込 メニューのクリック禁止 書込WToolStripMenuItem1.Enabled = false; // リストボックスをクリア listBox1.Items.Clear(); // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { MessageBox.Show("注意", "FT245との通信に失敗しました。"); return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定 ftStatus = FT_SetBitMode(ftHandle, 0x30, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // 20msec遅延 Msec_Delay(20); if (port_buf == POWER_ON) { // POWER ON, RESET ON port_buf = POWER_ON | RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); } // POWER OFF, RESET ON port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // FT245との通信を閉じる ftStatus = FT_Close(ftHandle); } 2007.07.21(土) 「デバイス」「tiny26L」「tiny2313」を追加しました。
Formのタイトルを"デバイス名"+"ライター "+(日付)に変更。 tiny2313追加に伴う変更点: 1) tiny2313ではボーレートを14400ボーに設定。 19200ボーでの読み出し・書き込みエラー対策。 //------------------------------------------ // FT245モジュールとの通信をオープン //------------------------------------------ unsafe private bool FT245_Open() { UInt32 ftH; UInt32 Writen = 0; // FUSE書き込みメニュークリック禁止 送信TToolStripMenuItem.Enabled = false; // ロックビット書き込みメニュークリック禁止 書込WToolStripMenuItem1.Enabled = false; // リストボックスをクリア listBox1.Items.Clear(); // FT245モジュルとの通信をオープン ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { // オープンに失敗したら return false; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定。b1-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート選択 if(Device == TINY26L) { ftStatus = FT_SetBaudRate(ftHandle, 19200); } else if(Device == TINY2313) { ftStatus = FT_SetBaudRate(ftHandle, 14400); } // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラム許可 avr_prog_enable(); // 20msec遅延 Msec_Delay(20); // 砂時計カーソルを表示 this.Cursor = Cursors.WaitCursor; return true; // FT245モジュールとの通信オープンに成功 } 2) コマンド出力関数avr_command_out()の終了時に、クロックLOW設定を追加。 tiny2313の書き込みエラー対策。 //------------------------------------------ // コマンド出力 //------------------------------------------ unsafe private void avr_command_out(int tx_size) { Byte[] tx_buf = new Byte[4096]; // シリアルバッファー Byte temp; // データ一時保管用 UInt32 writesize = 0; // 送信済みバイト長 UInt32 tx_count; // 送信カウンタ int n, i; // ループカウンタ tx_count = 0; for (i = 0; i < tx_size; i++) { // tx_sizeバイト繰返し temp = command_buf[i]; for (n = 0; n < 16; n += 2) { // 8ビット繰返し // MSBから出力 tx_buf[tx_count] = (Byte)((temp & 0x80) | port_buf); tx_buf[tx_count + 1] = (Byte)(tx_buf[tx_count] | CLOCK_H); temp <<= 1; // 次の出力ビットをMSBへシフト tx_count += 2; // 送信カウンタを更新 } } // クロックビットをLOWに設定 tx_buf[tx_count] = tx_buf[tx_count - 2]; tx_count++; // tx_sizeバイトのシリアルデータと同期クロックを出力 ftStatus = FT_Write(ftHandle, tx_buf, tx_count, &writesize); } 3) FUSE BITの表示 tiny26Lとtiny2313で、それぞれ専用の表示関数をコール。 4) CK較正値読出 tiny26L時4バイト。tiny2313時2バイトを切換え。 EEPROMページ設定、EEPRMページ書込、拡張FUSE読出、拡張FUSE書込、 ビジーチェック、SIGバイト読出等は未対応です。 参考1: ATtiny26LとATtiny2313のシリアルプログラムコマンドの比較表で、○印は差異があ るコマンドです。 tiny28Lのxビットは0にセットしている為、多くのコマンドを変更せずに使えます。 FUSE BIT上位書き込みコマンドも、編集値(2バイト)をそのまま書き込むことで流用 出来ます。 コマンド名 tiny 第1 第2 第3 第4 差異 -----------------+-----+---------+---------+---------+---------+---- プログラム許可 26L 1010 1100 0101 0011 xxxx xxxx xxxx xxxx 2313 1010 1100 0101 0011 xxxx xxxx xxxx xxxx -----------------+-----+---------+---------+---------+---------+---- チップ消去 26L 1010 1100 100x xxxx xxxx xxxx xxxx xxxx 2313 1010 1100 100x xxxx xxxx xxxx xxxx xxxx -----------------+-----+---------+---------+---------+---------+---- ROM読み出し 26L 0010 P000 xxxx xxHH LLLL LLLL RRRR RRRR 2313 0010 P000 0000 00HH LLLL LLLL RRRR RRRR ○ -----------------+-----+---------+---------+---------+---------+---- ROM BUF設定 26L 0100 P000 xxxx xxxx xxxx LLLL WWWW WWWW 2313 0100 P000 000x xxxx xxxx LLLL WWWW WWWW ○ -----------------+-----+---------+---------+---------+---------+---- ROM書き込み 26L 0100 1100 xxxx xxHH LLLL xxxx xxxx xxxx 2313 0100 1100 0000 00HH LLLL xxxx xxxx xxxx ○ -----------------+-----+---------+---------+---------+---------+---- EEPROM読み出し 26L 1010 0000 xxxx xxxx xLLL LLLL RRRR RRRR 2313 1010 0000 000x xxxx xLLL LLLL RRRR RRRR ○ -----------------+-----+---------+---------+---------+---------+---- EEPROM書き込み 26L 1100 0000 xxxx xxxx xLLL LLLL WWWW WWWW 2313 1100 0000 000x xxxx xLLL LLLL WWWW WWWW ○ -----------------+-----+---------+---------+---------+---------+---- ロックビット読出 26L 0101 1000 0000 0000 xxxx xxxx xxxx xxRR 2313 0101 1000 0000 0000 xxxx xxxx xxxx xxRR -----------------+-----+---------+---------+---------+---------+---- ロックビット書込 26L 1010 1100 111x xxxx xxxx xxxx 1111 11WW 2313 1010 1100 111x xxxx xxxx xxxx 1111 11WW -----------------+-----+---------+---------+---------+---------+---- FUSE下位読出 26L 0101 0000 0000 0000 xxxx xxxx RRRR RRRR 2313 0101 0000 0000 0000 xxxx xxxx RRRR RRRR -----------------+-----+---------+---------+---------+---------+---- FUSE下位書込 26L 1010 1100 1010 0000 xxxx xxxx WWWW WWWW 2313 1010 1100 1010 0000 xxxx xxxx WWWW WWWW -----------------+-----+---------+---------+---------+---------+---- FUSE上位読出 26L 0101 1000 0000 1000 xxxx xxxx xxxR RRRR 2313 0101 1000 0000 1000 xxxx xxxx RRxR RRRR ○ -----------------+-----+---------+---------+---------+---------+---- FUSE上位書込 26L 1010 1100 1010 1000 xxxx xxxx xxxW WWWW 2313 1010 1100 1010 1000 xxxx xxxx WW0W WWWW ○ -----------------+-----+---------+---------+---------+---------+---- SIGバイト読出 26L 0011 0000 xxxx xxxx xxxx xxLL RRRR RRRR 2313 0011 0000 000x xxxx xxxx xxLL RRRR RRRR -----------------+-----+---------+---------+---------+---------+---- CK較正値読出 26L 0011 1000 xxxx xxxx 0000 00LL RRRR RRRR 2313 0011 1000 000x xxxx 0000 000L RRRR RRRR ○ -----------------+-----+---------+---------+---------+---------+---- EEPROMページ設定 26L 2313 1100 0001 0000 0000 0000 00LL WWWW WWWW ○ -----------------+-----+---------+---------+---------+---------+---- EEPRMページ書込 26L 2313 1100 0010 00xx xxxx xLLL LL00 xxxx xxxx ○ -----------------+-----+---------+---------+---------+---------+---- 拡張FUSE読出 26L 2313 0101 0000 0000 1000 xxxx xxxx xxxx xxxR ○ -----------------+-----+---------+---------+---------+---------+---- 拡張FUSE書込 26L 2313 1010 1100 1010 0100 xxxx xxxx xxxx xxxW ○ -----------------+-----+---------+---------+---------+---------+---- ビジーチェック 26L 2313 1111 0000 0000 0000 xxxx xxxx xxxx xxxR ○ -----------------+-----+---------+---------+---------+---------+---- 参考2: 品名 特徴 内蔵クロック 単価(秋○調べ) ----------------+--------------+--------------+----------------- ATtiny26L A/D 11ch 1,2,4,8MHz \280 ATtiny2313-20PU PWM 4ch 1,4,8MHz \120 FT245との組合せも面白そうです。 2007.07.19(木) 「EEPROM」書き込みを追加しました。
ファイルオープンダイアログで選択したHEXファイルをバイナリに変換し、EEPROMに 書き込みます。 書き込み後は、EEPROMを読み出してベリファイを行います。 file_read() ROM書き込みのファイル読み込みとHEX-BINARY変換部分を関数化しました。 EEPROM書き込みと共通で使用します。 変換したBINARYデータは、広域変数file_data[]配列に格納します。 //------------------------------------------ // EEPROM書き込み //------------------------------------------ private void eEPROMToolStripMenuItem_Click(object sender, EventArgs e) { int i; int byte_size; int d = 0; // HEXファイル読み込み。バイナリに変換 if ((byte_size = file_read()) == 0) { // CANCEL釦クリックか該当ファイル無し return; } if (byte_size > 128) { byte_size = 128; } // FT245モジュール通信オープン // AVRプログラム許可 if (FT245_Open() == false) return; // 20msec遅延 Msec_Delay(20); // EEPROM書き込み listBox1.Items.Clear(); listBox1.Items.Add("EEROM書き込み中 Application.DoEvents(); progressBar1.Minimum = 0; progressBar1.Maximum = byte_size; progressBar1.Value = 0; // EEPROM書き込み for (d = 0; d < byte_size; d++) { i = 0; // EEPROM書き込みコマンド設定 command_buf[i++] = (Byte)((EEPROM_WR_COM >> 8) & 0xFF); command_buf[i++] = (Byte)(EEPROM_WR_COM & 0xFF); command_buf[i++] = (Byte)(d & 0x7F); command_buf[i++] = (Byte)file_data[d]; // コマンド送信 avr_command_out(4); // 10msec遅延 Msec_Delay(10); progressBar1.Value = d; } // 全ポートLOW設定 // FT245モジュール通信クローズ Ft245_Close(); // EEPROM読み出しバッファーを初期化 for (i = 0; i < 512; i++) { EepromData[i] = 0xFF; } // EEPROM読み出し eEPROMEToolStripMenuItem_Click(sender, e); // ベリファイ progressBar1.Value = 0; d = 0; bool write_err = false; for (d = 0; d < byte_size; d++) { if (EepromData[d] != file_data[d]) { write_err = true; } progressBar1.Value = d; } listBox1.Items.Clear(); if (write_err == true) { listBox1.Items.Add("書き込みエラー"); } else { listBox1.Items.Add("書き込みOK"); } progressBar1.Value = 0; } 2007.07.18(水) 「LOCKBIT」書き込みを追加しました。
「編集」をクリックすると、LOCK BITを読込みフォームに表示します。
ロックビットの値を編集し、「OK]釦をクリックするとリストボックスに値を表示し、 LOCK BITの「書込」メニューがクリック出来るようになります。 書き込み後は、LOCK BITを読込みリストボックスに表示します。
FT245_Open() FT245モジュールの通信開始。BitBangモード設定。ボーレート設定。 POWERとRESETのポート制御。AVRプグラム許可。等をまとめました。 FT245_Close() 全ポートのLOW設定。FT245モジュールとの通信終了。等をまとめました。 //------------------------------------------ // ロックビット書き込み //------------------------------------------ unsafe private void 書込WToolStripMenuItem1_Click(object sender, EventArgs e) { // FT245モジュールとの通信を開き // AVRプログラムを許可 if (FT245_Open() == false) return; // LOCK BITの書き込みコマンドを設定 set_command((Byte)((LOCK_BIT_WR_COM >> 8) & 0xFF), (Byte)((LOCK_BIT_WR_COM & 0xFF)), (Byte)0x00, (Byte)((LockBit & 0x03) | 0xFC)); // コマンド送信 avr_command_out(4); // 全ポートをLOWに設定 // FT245モジュールとの通信を閉じる Ft245_Close(); // LOCK BITの読み出しと表示 lOCKBITLToolStripMenuItem_Click(sender, e); } 2007.07.17(火) 「LOCKBIT」読み出しを追加しました。
![]()
//------------------------------------------ // LOCK BIT読み出し //------------------------------------------ unsafe private void lOCKBITLToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 ftH; UInt32 Writen = 0; // リストボックスクリア listBox1.Items.Clear(); // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定。b1-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラム許可 avr_prog_enable(); // 20msec遅延 Msec_Delay(20); // 砂時計カーソル表示 this.Cursor = Cursors.WaitCursor; listBox1.Items.Add("LOCK BIT読み出し"); // LOCK BIT読み出しコマンド設定 set_command((Byte)((LOCK_BIT_RD_COM >> 8) & 0xFF), (Byte)((LOCK_BIT_RD_COM & 0xFF)), (Byte)0x00, (Byte)0x00); // コマンド送信、データ入力 LockBit = avr_data_in(); // LOCK BIT表示 lock_bit_dsp(); // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW設定 port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); // 通常カーソル表示 this.Cursor = Cursors.Default; } //------------------------------------------ // LOCK BITの表示 //------------------------------------------ private void lock_bit_dsp() { listBox1.Items.Clear(); listBox1.Items.Add("LOCK BIT:" + LockBit.ToString("X2")); switch (LockBit & 0x03) { case 3: listBox1.Items.Add("xxx xx11:ROM,EEPROM,FUSE 書込可・読出可"); break; case 2: listBox1.Items.Add("xxx xx10:ROM,EEPROM,FUSE 書込不可・読出可"); break; case 0: listBox1.Items.Add("xxx xx00:ROM,EEPROM,FUSE 書込不可・読出不可"); break; case 1: listBox1.Items.Add("xxx xx01:仕様外の設定です。"); break; } } 2007.07.16(月) 「FUSE」書き込みを追加しました。
「編集」で編集フォームが開き、 「OK」で編集した結果をリストに反映、 「FUSE」のサブメニュー「書込」をクリック出来るようになります。 //------------------------------------------ // FUSEビット書き込み //------------------------------------------ unsafe private void 騾∽ソ。TToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 ftH; UInt32 Writen = 0; // 書込メニューをクリック禁止に設定 送信TToolStripMenuItem.Enabled = false; // リストボックスをクリア listBox1.Items.Clear(); // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモードを設定。b1-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラミング許可 avr_prog_enable(); // 20msec遅延 Msec_Delay(20); // 砂時計カーソルを表示 this.Cursor = Cursors.WaitCursor; // FUSEビット書き込み // 下位バイト書き込みコマンド設定 set_command((Byte)((FUSE_BIT_LOW_WR_COM >> 8) & 0xFF), (Byte)((FUSE_BIT_LOW_WR_COM & 0xFF)), (Byte)0x00, (Byte)(FuseBit & 0xFF)); // コマンドとデータを送信 avr_command_out(4); // 上位バイト書き子mい set_command((Byte)((FUSE_BIT_HI_WR_COM >> 8) & 0xFF), (Byte)(FUSE_BIT_HI_WR_COM & 0xFF), (Byte)0x00, (Byte)((FuseBit >> 8) & 0x0F)); // コマンドとデータを送信 avr_command_out(4); // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW設定 port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); // FUSEビット読み出して表示 fUSEToolStripMenuItem_Click(sender, e); // 通常カーソルを表示 this.Cursor = Cursors.Default; } 2007.07.15(日) 「ROM」書き込みを追加しました。
1024ワード(2048バイト)の書き込み時間は5.3secです。 これには、hexファイルの読み込みとバイナリ変換、ROM書き込み、1バイト/16ワード 毎のベリファイなどの処理時間が含まれます。 //------------------------------------------ // ROM書き込み //------------------------------------------ unsafe private void rOMRToolStripMenuItem_Click(object sender, EventArgs e) { int i; UInt32 ftH; UInt32 Writen = 0; string fname = "d:\\"; Byte[] write_data = new Byte[2048]; int ptr_max; String input; // hexファイル読み込み文字列 Byte length; // 1-2 データ長 int address; // 3-6 オフセット Byte rec_type; // 7-8 レコードタイプ String tmp; int byte_size; // バイト長 openFileDialog1.InitialDirectory = fname; openFileDialog1.Filter = "HEXファイル(*.hex)|*.hex|全てのファイル(*.*)|*.*"; openFileDialog1.FilterIndex = 1; openFileDialog1.RestoreDirectory = true; // ファイル選択ダイアログを表示 if (openFileDialog1.ShowDialog() == DialogResult.Cancel ) { // キャンセル釦が押されたら return; } if (openFileDialog1.OpenFile() == null) { listBox1.Items.Add("ファイルを開けません。"); return; } fname = openFileDialog1.FileName; // ファイルを開く System.IO.StreamReader sr = new System.IO.StreamReader(fname); listBox1.Items.Clear(); // リストボックスをクリア listBox1.Items.Add("HEXファイルを読み込み中"); Application.DoEvents(); // 砂時計カーソルを表示 this.Cursor = Cursors.WaitCursor; // ROMデータ配列を初期化 for (i = 0; i < 2048; i++) { write_data[i] = 0xFF; } ptr_max = 0; // 配列格納最後尾 // HEX文字列をバイナリに変換し配列へ格納 while ((input = sr.ReadLine()) != null) { length = (Byte)hex2int(input.Substring(1, 2)); address = hex2int(input.Substring(3, 4)); tmp = address.ToString("X4") + ":"; rec_type = (Byte)hex2int(input.Substring(7, 2)); if (rec_type == 0x00) { // データレコードなら for (i = 0; i < length * 2; i += 4) { // 下位バイト変換 write_data[address++] = (Byte)hex2int(input.Substring(i + 9, 2)); // 上位バイト変換 write_data[address++] = (Byte)hex2int(input.Substring(i + 11, 2)); } } if (address > ptr_max) { ptr_max = address; } } // HEXファイルを閉じる sr.Close(); byte_size = ptr_max; // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { // 通常カーソルを表示 this.Cursor = Cursors.Default; return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定。b1-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラミング許可 avr_prog_enable(); // 20msec遅延 Msec_Delay(20); // チップ消去 set_command((Byte)((CHIP_ERASE_COM >> 8) & 0xFF), (Byte)(CHIP_ERASE_COM & 0xFF), (Byte)0x00, (Byte)0x00); avr_command_out(4); // 20msec遅延 Msec_Delay(20); // ROM listBox1.Items.Clear(); listBox1.Items.Add("ROM書き込み中"); Application.DoEvents(); int d = 0; int n; Byte buf_addr; UInt16 rom_addr = 0; // プログレスバー初期化 progressBar1.Minimum = 0; progressBar1.Maximum = byte_size; progressBar1.Value = 0; // ROM書き込み for (d = 0; d < byte_size; ) { i = 0; buf_addr = 0; for (n = 0; n < 16; n++) { // ページバッファーへ16ワード書き込み // 下位バイトコマンドとデータ設定 command_buf[i++] = (Byte)((PAGE_BUF_L_SET_COM >> 8) & 0xFF); command_buf[i++] = (Byte)(PAGE_BUF_L_SET_COM & 0xFF); command_buf[i++] = (Byte)(buf_addr & 0x0F); command_buf[i++] = (Byte)write_data[d++]; // 上位バイトコマンドとデータ設定 command_buf[i++] = (Byte)((PAGE_BUF_H_SET_COM >> 8) & 0xFF); command_buf[i++] = (Byte)(PAGE_BUF_H_SET_COM & 0xFF); command_buf[i++] = (Byte)(buf_addr & 0x0F); command_buf[i++] = (Byte)write_data[d++]; buf_addr++; } // コマンド送信 avr_command_out(128); // ページ書き込みコマンド送信 set_command((Byte)((PROG_PAGE_WR_COM >> 8) & 0xFF), (Byte)((rom_addr >> 8) & 0x03), (Byte)(rom_addr & 0xF0), (Byte)0x00); avr_command_out(4); // 5msec遅延 Msec_Delay(5); // ROMワードアドレス更新 rom_addr += 16; // プログレスバー位置更新 if (d > byte_size) { d = byte_size; } progressBar1.Value = d; } // データベリファイ。1バイト/16ワードごとに実施。 // リストボックスクリア listBox1.Items.Clear(); listBox1.Items.Add("ベリファイ中"); Application.DoEvents(); progressBar1.Value = 0; rom_addr = 0; Byte rx_data; bool write_err = false; for (rom_addr = 0; rom_addr < (byte_size / 2); rom_addr += 16) { // ROM読み出しコマンド設定 set_command((Byte)((PROG_LOW_RD_COM >> 8) & 0xFF), (Byte)((PROG_LOW_RD_COM & 0xFC) + ((rom_addr >> 8) & 0x03)), (Byte)(rom_addr & 0xFF), (Byte)0x00); // コマンド送信、データ入力 rx_data = avr_data_in(); if (rx_data != write_data[rom_addr*2]) { write_err = true; break; } progressBar1.Value = rom_addr * 2; } listBox1.Items.Clear(); if (write_err == true) { listBox1.Items.Add("書き込みエラー"); } else { listBox1.Items.Add("書き込みOK"); } // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW設定 port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); // 通常カーソルを表示 this.Cursor = Cursors.Default; progressBar1.Value = 0; } 2007.07.14(土) 「CalibrationByte」と「EEPROM」を追加しました。
//------------------------------------------ // キャリブレーションバイト読み出し //------------------------------------------ unsafe private void calibrationByteCToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 ftH; UInt32 Writen = 0; Byte calib; int n; // リストボックスクリア listBox1.Items.Clear(); // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定。b1-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラミング許可 avr_prog_enable(); // 20msec遅延 Msec_Delay(20); // 砂時計カーソルを表示 this.Cursor = Cursors.WaitCursor; listBox1.Items.Add("Calibration Byte"); // CALIBRATIONバイト読み出し for (n = 0; n < 4; n++) { // n番地読み出し set_command((Byte)((CALIB_RD_COM >> 8) & 0xFF), (Byte)((CALIB_RD_COM & 0xFF)), (Byte)n, (Byte)0x00); // コマンド出力とデータ入力 calib = avr_data_in(); listBox1.Items.Add((n + 1).ToString()+ "MHz:" + calib.ToString("X2")); } // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW設定 port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245との通信を閉じる ftStatus = FT_Close(ftHandle); // カーソルを通常に戻す this.Cursor = Cursors.Default; } //------------------------------------------ // EEPROMデータ読み出し //------------------------------------------ unsafe private void eEPROMEToolStripMenuItem_Click(object sender, EventArgs e) { Byte addr = 0x00; int n, i; Byte rx_data; String str; UInt32 ftH; UInt32 Writen = 0; // リストボックスクリア listBox1.Items.Clear(); // FT245モジュールとの通信を閉じる ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定。b1-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラミング許可 avr_prog_enable(); // 20msec遅延 Msec_Delay(20); // 砂時計カーソルを表示 this.Cursor = Cursors.WaitCursor; listBox1.Items.Add("EEPROM DATA"); // EEPROMデータ読み出し str = 0.ToString("X2") + ":"; i = 0; for (n = 0; n < 64; n++) { // 1バイト読み出し set_command((Byte)((EEPROM_RD_COM >> 8) & 0xFF), (Byte)(EEPROM_RD_COM & 0xFF), (Byte)addr, (Byte)0); // コマンド出力とデータ入力 rx_data = avr_data_in(); str += rx_data.ToString("X2") + " "; addr++; i++; if (i == 8) { i = 0; listBox1.Items.Add(str); str = ((n + 1) * 2).ToString("X2") + ":"; // 最終行を選択 listBox1.SetSelected(listBox1.Items.Count - 1, true); } if (stop_flg) break; // stopメニュークリック } // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); // カーソルを通常に戻す this.Cursor = Cursors.Default; } 2007.07.13(金) 「ROM読出」を「読出」のサブメニューに移動。「FUSE」を追加しました。
FUSE BIT=0xF7E1は、工場出荷時の値です。 //------------------------------------------ // FUSE BIT読み出し //------------------------------------------ unsafe private void fUSEToolStripMenuItem_Click(object sender, EventArgs e) { UInt32 ftH; UInt32 Writen = 0; Byte FuseHI = 0; Byte FuseLOW = 0; // リストボックスクリア listBox1.Items.Clear(); // FT24モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return; } // デバイスハンドルをコピー ftHandle = ftH; // BitBangモード設定。b2-b7=Out, b0=In ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラミング許可 // 第1コマンド設定 command_buf[0] = (Byte)((PROG_ENABLE_COM >> 8) & 0xFF); // 第2コマンド設定 command_buf[1] = (Byte)(PROG_ENABLE_COM & 0xFF); // 第3コマンド設定 command_buf[2] = (Byte)0x00; // 第4コマンド設定 command_buf[3] = (Byte)0x00; avr_command_out(4); // 20msec遅延 Msec_Delay(20); // 砂時計カーソル表示 this.Cursor = Cursors.WaitCursor; // ヒューズビット下位読み出し // 第1コマンド設定 command_buf[0] = (Byte)((FUSE_BIT_LOW_RD_COM >> 8) & 0xFF); // 第2コマンド設定 command_buf[1] = (Byte)((FUSE_BIT_LOW_RD_COM & 0xFF)); // 第3コマンド設定 command_buf[2] = 0x00; // データ読み出し FuseLOW = avr_data_in(); // ヒューズビット上位読み出し // 第1コマンド設定 command_buf[0] = (Byte)((FUSE_BIT_HI_RD_COM >> 8) & 0xFF); // 第2コマンド設定 command_buf[1] = (Byte)(FUSE_BIT_HI_RD_COM & 0xFF); // 第3コマンド設定 command_buf[2] = 0x00; // データ読み出し FuseHI = avr_data_in(); // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); // 結果表示 listBox1.Items.Add("FUSE BIT:" + FuseHI.ToString("X2") + " " + FuseLOW.ToString("X2")); switch (FuseHI & 0x10) { case 0x10: listBox1.Items.Add("xxx1xxxx xxxxxxxx RSTDISBL:PB7=RESET"); break; case 0x00: listBox1.Items.Add("xxx0xxxx xxxxxxxx RSTDISBL:PB7=PORT"); break; } switch (FuseHI & 0x08) { case 0x08: listBox1.Items.Add("xxxx1xxx xxxxxxxx SPIEN :シリアルプログラム許可"); break; case 0x00: listBox1.Items.Add("xxxx0xxx xxxxxxxx SPIEN :シリアルプログラム禁止"); break; } switch (FuseHI & 0x04) { case 0x04: listBox1.Items.Add("xxxxx1xx xxxxxxxx EESAV :EEPROM未保護"); break; case 0x00: listBox1.Items.Add("xxxxx0xx xxxxxxxx EESAV :EEPROM保護"); break; } switch (FuseHI & 0x02) { case 0x02: listBox1.Items.Add("xxxxxx1x xxxxxxxx BODLEVE :低電圧検出レベル=2.7V"); break; case 0x00: listBox1.Items.Add("xxxxxx0x xxxxxxxx BODLEVE :低電圧検出レベル=4.0V"); break; } switch (FuseHI & 0x01) { case 0x01: listBox1.Items.Add("xxxxxxx1 xxxxxxxx BODE :低電圧検出レベル禁止"); break; case 0x00: listBox1.Items.Add("xxxxxxx0 xxxxxxxx BODE :低電圧検出レベル許可"); break; } switch (FuseLOW & 0x80) { case 0x80: listBox1.Items.Add("xxxxxxxx 1xxxxxxx PLLC :PLL未使用"); break; case 0x00: listBox1.Items.Add("xxxxxxxx 0xxxxxxx PLLC :PLL使用"); break; } switch (FuseLOW & 0x40) { case 0x40: listBox1.Items.Add("xxxxxxxx x1xxxxxx CKOP :CK用コンデンサOFF"); break; case 0x00: listBox1.Items.Add("xxxxxxxx x0xxxxxx CKOP :CK用コンデンサON"); break; } switch (FuseLOW & 0x30) { case 0x00: listBox1.Items.Add("xxxxxxxx xx1xxxxx SUT1 :起動遅延(00)"); break; case 0x10: listBox1.Items.Add("xxxxxxxx xx0xxxxx SUT1 :起動遅延(01)"); break; case 0x20: listBox1.Items.Add("xxxxxxxx xxx1xxxx SUT0 :起動遅延(10)"); break; case 0x30: listBox1.Items.Add("xxxxxxxx xxx0xxxx SUT0 :起動遅延(11)"); break; } switch (FuseLOW & 0x0F) { case 0x01: listBox1.Items.Add("xxxxxxxx xxxx0001 CLKSEL :1MHz"); break; case 0x02: listBox1.Items.Add("xxxxxxxx xxxx0010 CLKSEL :2MHz"); break; case 0x03: listBox1.Items.Add("xxxxxxxx xxxx0011 CLKSEL :4MHz"); break; case 0x04: listBox1.Items.Add("xxxxxxxx xxxx0100 CLKSEL :8MHz"); break; } // 通常カーソル表示 this.Cursor = Cursors.Default; } 2007.07.12(木) ATtiny26LからプログラムROMデータを読み出しました。
1024ワード読み出しの実測時間は87.27secです。 参考:昨日の試算では76.19sec。 回路 FT245RLモジュール ATtiny26L ┌───┐ ┌────┐ │ │8 1│ │ │ b7├───────────────────┤MOSI │ │ │7 3│ │ │ b6├───────────────────┤SCK │ │ │1 2│ │ │ b0├───────────────────┤MISO │ │ │ │ │ │ │ 2SA1048 5│ │ │ │ c┌──────●──●─●─┤Vcc │ │ │15 e┌┴┐b │ │ │15│ │ │ Vcc├──●─┤ ├┐ │ │ └─┤AVcc │ │ │ │ └─┘│ │ │ │ │ │ │ R10K R2.2K │1u/ │ │ │ │ │ │ │ │50V │ │ │ │ │ └────● │┴│ │ │ │ │ │ c│ └┬┘ │ │ │ │ POWER│6 b┌┴┐e │ │ │ │ │ b5├─R10K─●─┤ ├┐2SC │ │ │ │ │ │ │ └─┘│1815│ │ │ │ │ │ R10K │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └────●──● R10K │ │ │ │ │ │ 10│ │ │ │ ┌───────●───┤-RESET │ │ │ c│ │ │ │ │ RESET│5 b┌┴┐e │ │ │ │ b4├─R10K─●─┤ ├┐2SC │ │ │ │ │ │ └─┘│1815│ │ │ │ │ R10K │ │ │ │ │ │9 │ │ │ 6│ │ │ GND├────●────●──●───●──┤GND │ │ │ │ 16│ │ └───┘ └──┤GND │ └────┘ プログラム 広域変数 port_buf に POWER、RESETのピン制御データを設定し、 avr_command_out()とavr_data_in()の関数内でシリアルデータビットに変換して 出力するようにしました。 2007.07.10(火)と2007.07.11(水)に掲載した2つの関数の変更箇所に△2007.07.12 を付記しました。 //------------------------------------------ // ROM読み出し // 「ROM読出」メニューのクリックイベント //------------------------------------------ unsafe private void rOM読出RToolStripMenuItem_Click(object sender, EventArgs e) { UInt16 addr = 0x0000; int n, i; Byte rx_data; String str, str1; UInt32 ftH; UInt32 Writen = 0; // リストボックスをクリア listBox1.Items.Clear(); // FT245モジュールとの通信を開く ftStatus = FT_Open(0, &ftH); if (ftStatus != FT_OK) { return; } // 取得したデバイスハンドルを広域変数にコピー ftHandle = ftH; // BitBangモードに設定。b0=In, b1-b7=Out ftStatus = FT_SetBitMode(ftHandle, 0xFE, 0x01); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // RESET ON, CLOCK LOW port_buf = RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // POWER ON, RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // AVRプログラミング許可 // 第1バイト設定 command_buf[0] = (Byte)((PROG_ENABLE_COM >> 8) & 0xFF); // 第2バイト設定 command_buf[1] = (Byte)(PROG_ENABLE_COM & 0xFF); // 第3バイト設定 command_buf[2] = (Byte)0x00; // 第4バイト設定 command_buf[3] = (Byte)0x00; avr_command_out(4); // 20msec遅延 Msec_Delay(20); // 砂時計カーソル表示 this.Cursor = Cursors.WaitCursor; // ダンプアドレス文字列を作成 str = 0.ToString("X4") + ":"; // ROM読み出し i = 0; // ダンプワードカウンタ初期化 for (n = 0; n < 128; n++) { // 下位バイト読み出しコマンド設定 // 第1バイト設定 command_buf[0] = (Byte)((PROG_RD_COM >> 8) & 0xFF); // 第2バイト設定 command_buf[1] = (Byte)((PROG_RD_COM & 0xFC) + ((addr >> 8) & 0x03)); // 第3バイト設定 command_buf[2] = (Byte)(addr & 0xFF); // コマンド送信とデータ入力 rx_data = avr_data_in(); // ダンプ用文字列に変換 str1 = rx_data.ToString("X2"); // 下位バイト読み出しコマンド設定 // 第1バイト設定 command_buf[0] = (Byte)(((PROG_RD_COM >> 8) & 0xFF) | 0x08); // 第2バイト設定 command_buf[1] = (Byte)((PROG_RD_COM & 0xFC) + ((addr >> 8) & 0x03)); // 第3バイト設定 command_buf[2] = (Byte)(addr & 0xFF); // コマンド送信とデータ入力 rx_data = avr_data_in(); addr++; // ワードアドレス更新 // ダンプ用文字列に変換 str += str1 + rx_data.ToString("X2"); // ダンプリスト表示 i++; if (i == 8) { i = 0; listBox1.Items.Add(str); // ダンプアドレス文字列を作成 str = ((n + 1)*2).ToString("X4") + ":"; // リストボックスの最終行を選択 listBox1.SetSelected(listBox1.Items.Count - 1, true); } // stopメニュークリックイベントチェック if (stop_flg) break; } // RESET ON port_buf = POWER_ON + RESET_ON; command_buf[0] = port_buf; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // 20msec遅延 Msec_Delay(20); // 全ポートLOW port_buf = ALL_LOW; command_buf[0] = ALL_LOW; ftStatus = FT_Write(ftHandle, command_buf, 1, &Writen); // FT245モジュールとの通信を閉じる ftStatus = FT_Close(ftHandle); // 通常カーソル表示 this.Cursor = Cursors.Default; } 2007.07.11(水) 1バイト受信関数を作成しました。 例:ATtiny26LのRead Program Memoryコマンド 第1バイト 第2バイト 第3バイト 第4バイト 0010 H000 xxxx xxaa bbbb bbbb oooo oooo H=0で1ワードの下位バイトを指定。 H=1で1ワードの上位バイトを指定。 aa bbbb bbbbはプログラムROMのアドレス。 oooo ooooはプログラムROMのデータ。 プログラム例: public const UInt16 PROG_RD_COM = 0x2000; // プログラムメモリ読み出し UInt16 addr = 0x0000; // ワードの下位バイト読み出しコマンドをバッファーに設定。 command_buf[0] = (Byte)((PROG_RD_COM >> 8) & 0xFF); // 第1バイト設定 command_buf[1] = (Byte)((PROG_RD_COM & 0xFF) // 第2バイト設定 + ((addr >> 8) & 0x03)); command_buf[2] = (Byte)(addr & 0xFF); // 第3バイト設定 // コマンド3バイト送信 avr_command_out(3); // データ1バイトシリアル入力 data = avr_data_in();
所用時間=37.2msec。 プログラムデータ1024ワード(2048バイト)の読み出し時間を試算すると、 37.2msec/byte×2048byte=76.19sec=1min16.19sec。 プログラムROMの書き込みで、全データのベリファイをした場合と、16ワードにつき 1バイトのベリファイをした場合の書き込み時間を比較しました。 ベリファイ方法 書き込み時間 試算式 -----------------+--------------+---------------------------- 全データ 78.2sec =76.19s+2.016s 1バイト/16ワード 4.4sec =37.2ms×1024÷16+2.016s 2.016sは2007.07.10(火)に求めた1024ワードの書き込み時間です。 4.4secで書き込みとベリファイが完了すれば、デバッグは快適です。 //------------------------------------------ // 1バイトのシリアルデータ入力 //------------------------------------------ unsafe private Byte avr_data_in() { Byte rx_buf = 0; Byte[] tx_buf = new Byte[2]; Byte[] temp = new Byte[1]; UInt32 writesize; int n; // 第1から第3コマンドまでを出力 // 3バイトのコマンドは関数の呼び出し前に設定します avr_command_out(3); // 1バイトをシリアルで受信 for (n = 0; n < 8; n++) { // 8ビット繰返し // MSBから入力 tx_buf[0] = port_buf; // △2007.07.12 tx_buf[1] = (Byte)(CLOCK_H | port_buf); // △2007.07.12 ftStatus = FT_Write(ftHandle, tx_buf, 2, &writesize); Application.DoEvents(); ftStatus = FT_GetBitMode(ftHandle, temp); rx_buf <<= 1; rx_buf |= (Byte)(temp[0] & 0x01); } return rx_buf; } 2007.07.10(火) 4バイトのコマンド送信関数を変更しました。 変更点: 1) 引数を送信バイト数に変更。最大値=128。 4バイト分のループ回数を引数分のループ回数にします。 旧引数のデバイスハンドルは既にpublic変数で定義済みのため、引数から削除し ました。 2) 送信バッファーを64バイトから2048バイトに変更。 ATtiny26Lのページバッファーは16ワード(32バイト)です。 16ワード分のコマンドのバイト数は 16ワード/ページ×2バイト/ワード×4バイト/コマンド=128バイト/ページ・コマ ンド。 128バイトのコマンドからシリアルデータと同期クロックを生成すると、 128バイト/ページ・コマンド×16バイト/バイト=2048バイト/ページ・コマンド。 が必要です。 プログラム例: // 16ワード(32バイト)のテストデータを生成 for(n = 0; n < 32; n++) { data[n] = (Byte)n; } int i = 0; int k = 0; Byte buf_addr = 0x00; // 16ワードをページバッファーへ書き込むコマンドを生成 for (n = 0; n < 16; n++) { // ページバッファー下位バイトへの書き込みコマンド生成 // 第1バイト設定 command_buf[i++] = (Byte)((PAGE_BUF_SET_COM >> 8) & 0xFF); // 第2バイト設定 command_buf[i++] = (Byte)(PAGE_BUF_SET_COM & 0xFF); // 第3バイト設定 command_buf[i++] = (Byte)(buf_addr); // 第4バイト設定 command_buf[i++] = (Byte)data[k++]; // ページバッファー上位バイトへの書き込みコマンド生成 // 第1バイト設定 command_buf[i++] = (Byte)(((PAGE_BUF_SET_COM >> 8) & 0xFF) | 0x08); // 第2バイト設定 command_buf[i++] = (Byte)(PAGE_BUF_SET_COM & 0xFF); // 第3バイト設定 command_buf[i++] = (Byte)(buf_addr++); // 第4バイト設定 command_buf[i++] = (Byte)data[k++]; } // シリアルに変換し送信 avr_command_out(128);
16ワードのクロック列の送信時間は27msec。 ビットレート=128×8÷27msec=37.9Kbit/sec。 1024ワードに要する送信時間=27msec/page×1024word÷16word/page=1.728sec。 1ページ書き込み後の待機時間が4.5msecの為、1024ワード書き込み時間は、 4.5msec/page×1024word÷16word/page+1.728sec=0.288sec+1.728sec=2.016sec。 // 128バイトまでのコマンド送信関数 // シリアルデータと同期クロックの生成と送信 unsafe private void avr_command_out(int tx_size) { Byte[] tx_buf = new Byte[2048]; // 送信バッファー Byte temp; // 一時保管用 UInt32 writesize = 0; // 送信済みカウンタ Uint32 tx_count; // 送信カウンタ int n, i; // ループカウンタ tx_count = 0; for (i = 0; i < tx_size; i++) { // tx_sizeバイトの繰返し temp = command_buf[i]; for (n = 0; n < 16; n += 2) { // 8ビット繰返し // MSBから順次出力 // △2007.07.12 tx_buf[tx_count] = (Byte)((temp & 0x80) | port_buf); // △2007.07.12 tx_buf[tx_count + 1] = (Byte)((tx_buf[tx_count] | CLOCK_H) | port_buf); tx_buf[tx_count + 1] = (Byte)(tx_buf[tx_count] | CLOCK_H); temp <<= 1; // 次の送信ビットをMSBへシフト tx_count += 2; // 送信カウンタ更新 } } // tx_sizeバイトシリアルデータと同期クロック送信 ftStatus = FT_Write(ftHandle, tx_buf, tx_count, &writesize); } 2007.07.09(月) 4バイトのコマンド送信関数を作成しました。 例:ATtiny26Lのチップ消去コマンド 第1バイト 第2バイト 第3バイト 第4バイト 1010 1100 100x xxxx xxxx xxxx xxxx xxxx // コマンド定義 public const UInt16 CHIP_ERASE_COM = 0xAC80; // チップ消去コマンド // 制御用 public const Byte CLOCK_L = 0xBF; // b6=クロックLOW public const Byte CLOCK_H = 0x40; // b6=クロックHIGH // バッファーへコマンド設定 command_buf[0] = (Byte)((CHIP_ERASE_COM >> 8) & 0xFF); // 第1バイト設定 command_buf[1] = (Byte)(CHIP_ERASE_COM & 0xFF); // 第2バイト設定 command_buf[2] = 0x00; // 第3バイト設定 command_buf[3] = 0x00; // 第4バイト設定 // コマンド送信 avr_command_out(ftHandle);
上:クロック 下:シリアルデータ 32ビットのシリアルデータを約784usecで送信します。 ビットレート=32bit/784usec=40.8Kbit/sec。 //------------------------------------------ // 4バイトコマンド送信関数 //------------------------------------------ unsafe private void avr_command_out(UInt32 ftHandle) { // b0=int, b2-b7=Out Byte[] tx_buf = new Byte[64]; // 送信バッファー Byte temp; // 一時保管用 UInt32 writesize = 0; // 送信済みカウンタ int tx_count; // 送信カウンタ int n, i; // ループカウンタ tx_count = 0; for (i = 0; i < 4; i++) { // 4バイト繰返し temp = command_buf[i]; for (n = 0; n < 16; n += 2) { // 8ビット繰返し // MSBから出力 tx_buf[tx_count] = (Byte)(temp & 0x80 & CLOCK_L); tx_buf[tx_count + 1] = (Byte)(tx_buf[tx_count] | CLOCK_H); temp <<= 1; // 次の送信ビットをMSBへシフト tx_count += 2; // 送信カウンタ更新 } } // 4バイトシリアルデータと同期クロック送信 ftStatus = FT_Write(ftHandle, tx_buf, (UInt32)tx_count, &writesize); } 2007.07.08(日) 1バイトのデータをクロックと同期してMSBからシリアルで出力します。 タイミングチャート ──┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ CLOCK ──┴─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └ ──┬───┬───┬───┬───┬───┬───┬───┬──── │ MSB │ │ │ │ │ │ │ LSB DATA ──┴───┴───┴───┴───┴───┴───┴───┴──── クロックの立下がりでデータを出力し、クロックの立上がりでターゲットデバイスが データを取り込みます。 ターゲットデバイスはATtiny26Lです。
上:8ビットのクロック列。50usec/dev。全長158usecから210usec。 下:クロックの拡大。5usec/dev。最小幅=3.2usec。 ボーレート=19200ボー。 ATtiny26Lの内蔵RC発振が1MHzの時、データ送信のクロックパルス幅の規格は2usec。 少し余裕があります。 プログラム(いくつかの変数の宣言を省略しました。) int n; Byte[] data = new Byte[16]; // FT245との通信を開きます ftStatus = FT_Open(0, &ftH); // ボーレート設定 ftStatus = FT_SetBaudRate(ftHandle, 19200); // クロックとシリアルデータ出力 // b0=int, b2-b7=Out Byte data_buf = 0x55; // 出力データ Byte clock_low = 0x00; // b6=クロックビット=LOW byte clock_high = 0x40; // b6=クロックビット=HIGH for (n = 0; n < 16; n += 2 ) { // MSBから出力するデータと、同期するクロックを生成 data[n] = (Byte)(data_buf & 0x80 + clock_low); data[n + 1] = (Byte)(data[n] + clock_high); data_buf <<= 1; // 次の出力ビットをMSBへシフト } 1バイトのシリアルデータとクロックを出力 ftStatus = FT_Write(ftHandle, data, (UInt32)n, &writesize); // FT245との通信を閉じます ftStatus = FT_Close(ftHandle); 2007.07.06(金) ポートの入力状態を取得する2種類の関数で、スイッチ入力の変化から出力変化まで の遅れ時間を測定しました。 1) FT_GetBitMode(ftHandle, data); 2) FT_Read(ftHandle, data, 64, &readsize); 3) FT_Read(ftHandle, data, 128, &readsize); 4) FT_Read(ftHandle, data, 256, &readsize); 遅れ時間 9600ボー | 57600ボー 最小 最大 | 最小 最大 ---+----------+-----------+----------+------------ 1) 3.4msec 9.6msec | 3.2msec 9.12msec 2) 1.98sec 1.98sec | 1.98sec 1.98sec 3) 33.6msec 53.6msec | 0.992sec 0.992sec 4) 24.8msec 55.2msec | 0.488sec 0.488sec 2007.07.05(木) Bit Bangモードで、ポート上位4ビットに接続したスイッチのオン・オフを、 ポートの下位4ビットに出力しました。
終了 :アプリケーションを終了します。 Start:スイッチ入力とデータ出力を繰返し実行します。 Stop :スイッチ入力とデータ出力の繰返しを停止します。
上:b4スイッチ入力信号 下:b0出力信号 スイッチ入力の変化から出力変化までの遅れ時間は、 実測で最小3.4msecから最大9.6msecの範囲でばらつきます。 プログラム while (true) { if (stop_flg) break; // stopメニュークリックイベントでフラグセット // ポート入力 ftStatus = FT_GetBitMode(ftHandle, data); data[0] >>= 4; // 下位4ビットへシフト // ポート出力 ftStatus = FT_Write(ftHandle, data, 1, &writesize); Application.DoEvents(); // メニュークリック等を許可 } // DLL参照用 // FT_GetBitMode(ポート入力用) [DllImport("ftd2xx.dll")] unsafe private static extern UInt32 FT_GetBitMode(UInt32 ftHandle, [MarshalAs(UnmanagedType.LPArray)] byte[] bdata); 2007.07.04(水) Bit Bangモードで、0xFF,0x00の順で合計256バイトを出力、ボーレートは9600です。 データは、ftStatus = FT_Write(ftHandle, data, 256, &writesize);で一括して送信 しました。
上:20usec/dev。 1パルス最小幅=7.2usec。1パルス最大幅=65.6usec。 下:2msec/dev。 全体長=6.8msec。 全体長は比較的安定しています。出力レートは256byte/6.8msec=37647.1byte/secで、 ボーレート設定値の37647.1(byte/sec)÷9600=3.92倍です。 1パルス幅はおよそ9倍ばらつきます。 下記の仕様から、最小パルス幅が6.5usec/byteで、最大パルス幅は1/9600=104.2usec くらいとした利用が考えられます。 CNCのステップパルスモータの駆動周期用としては不向きです。 資料 AN232R-01 Bit Bang Modes for the FT232R and FT245R から FT_SetBaudRate The rate of data transfer can be controlled by using the FT_SetBaudRate command. The maximum Baud rate is 3MBaud, but to allow time for thedata to be setup and held around the WR# strobe the Baud rate should be less than 1MBaud. The clock for the Asynchronous Bit Bang mode is actually 16 times the Baud rate. A value of 9600 Baud would transfer the data at (9600x16) = 153600 bytes per second, or 1 every 6.5 uS. 拙い訳です。 データ転送レートは、FT_SetBaudRateコマンドで制御します。 ボーレートの最大値は3Mボー。 実際はデータ設定やWR#ストローブ保持に要する時間 を許容する為、1Mボー以下です。 非同期Bit Bangモードの転送用クロックは、ボーレートの16倍です。 データ転送レートが9600ボーの時、9600x16=153600byte/secで、6.5usec/byteです。 2007.07.03(火) VC#でFT245出力テストAppを作成しました。
Startメニューをクリックするとパルスを出力します。
バイト型配列のデータを順次出力した時のビット0の波形です。 1バイト転送ごとに1msecの遅延の場合は、10個目の0x00は18msec後に出力されます。 10msecの遅延では、USB通信の影響が少なく99.2msecで10個目の0x00が出力されます。 プログラム抜粋 // [DllImport("ftd2xx.dll")]参照用のusing指定 using System.Runtime.InteropServices; // Startメニューのクリックイベントで10個のデータを出力します。 unsafe private void startSToolStripMenuItem_Click(object sender, EventArgs e) { const Uint32 FT_OK = 0; UInt32 ftHandle; UInt32 ftStatus; UInt32 writesize; Byte[] data = { 0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00 }; // FT245モジュールとの通信を開きます ftStatus = FT_Open(0, &ftHandle); if (ftStatus != FT_OK) { // 通信の開始に失敗したら return; } // BitBangモードに設定。b0-b7=出力に設定。 ftStatus = FT_SetBitMode(ftHandle, 0xFF, 0x01); // ボーレートを設定 ftStatus = FT_SetBaudRate(ftHandle, 9600); int n; Byte[] out_data = new Byte[1]; for (n = 0; n < 10; n++) { // データを出力 out_data[0] = data[n]; ftStatus = FT_Write(ftHandle, out_data, 1, &writesize); // 1msecの遅延 Msec_Delay(1); } // FT245との通信を終了 ftStatus = FT_Close(ftHandle); } //------------------------------------------ // FTD2XX.DLL呼び出し参照 // 2007.07.03(火) //------------------------------------------ // FT Open [DllImport("ftd2xx.dll")] unsafe private static extern UInt32 FT_Open(Int16 DeviceNumber, UInt32 *ftHandle); // FT Close [DllImport("ftd2xx.dll")] private static extern UInt32 FT_Close(UInt32 ftHandle); // FT_SetBitMode [DllImport("ftd2xx.dll")] private static extern UInt32 FT_SetBitMode(UInt32 ftHandle, Byte Mask, Byte Mode); // FT_SetBaudRate [DllImport("ftd2xx.dll")] private static extern UInt32 FT_SetBaudRate(UInt32 ftHandle, UInt32 BaudRate); // FT_Write [DllImport("ftd2xx.dll")] unsafe private static extern UInt32 FT_Write(UInt32 ftHandle, [MarshalAs(UnmanagedType.LPArray)] byte[] bdata, UInt32 BufferSize, UInt32 *BytesWriten); //------------------------------------------ // 1msec倍遅延 // 2007.07.03(火) //------------------------------------------ [DllImport("kernel32.dll")] extern static short QueryPerformanceCounter(ref long x); [DllImport("kernel32.dll")] extern static short QueryPerformanceFrequency(ref long x); public void Msec_Delay(int t) { long count1 = 0; long count2 = 0; long freq = 0; QueryPerformanceFrequency(ref freq); // システムの周波数取得 count2 = (long)t * freq / 1000; // カウント値計算 QueryPerformanceCounter(ref count1); // 計測開始カウント取得 count2 += count1; // 遅延後のカウント値計算 while (true) { QueryPerformanceCounter(ref count1); if (count1 >= count2) break; } } 2007.07.01(日) FT245RLモジュールを購入しました。 FTDIの[Driver][D2XX]からCDM 2.00.00.zipをダウンロードして解凍すると、 デバイスドライバーやDLLが展開されます。
モジュールにUSBケーブルを接続し、新しいハードウェアーが検出されてから、 解凍したドライバーが入っているフォルダーを指定し、 デバイスドライバーをインストールします。 インストール操作は2回行います。(DCXX BitBang modeとVCP modeの2回分) FT245RLモジュールの ● この商品のよくある質問(Q&A)からダウンロードした 20070301090913-FT245RL_SAMPLE.zipを解凍し、SETUP.exeでFT245RL.exeをインスト ールします。 FT245RL.exeを実行すると、入出力の実験が出来ました。
![]()
ページのTopへ
サイトのTopへ
法律条項 この資料により生じたいかなる障害や損害に対し、著者は全てを免責されるものとします。 この資料は、著作権法の下で保護され、入手先、著者、日付、法律条項を含んだ場合に複製が可能です。