/**********************************************************/ /* */ /* CMOS-EYE H8/3687接続例サンプルプログラム */ /* Target:H8Tiny/3687F(BestTechnorogy BTC065) */ /* Environment:GDL1.5.0.52 */ /* Since:2006.8.10 */ /* (c) AsakusaGiken Co., LTD. */ /* */ /**********************************************************/ /*----------------------------------------------------------------------------------- ピンアサイン (CMOS-EYE - H8/3687) A0 P30 A1 P31 A2 P32 A3 P33 A4 P34 A5 P35 A6 P36 A7 P37 A8 P10 A9 P11 A10 P12 A11 P14 A12 P15 A13 P16 A14 P17 A15 P70 A16 P74 A17 P75 A18 P76 D0 P60 D1 P61 D2 P62 D3 P63 D4 P64 D5 P65 D6 P66 D7 P67 M0 P53 M1 P54 M2 P55 CE P50 WE P51 OE P52 ST P24 BSY P23 (PC<-H8/3687)*プログラム転送用(BTC065は標準でSCI3経由でPGをダウンロード) RX P21/RXD TX P22/TXD (オシロ<-H8/3687)*TESTは処理時間測定用、オシロスコープで波形を計測 TEST P20 (AGB65<-H8/3687)*CMOS-EYEシリアル命令及び、AGB65シリーズを動かす用 RX P71/RXD_2 TX P72/TXD_2 (その他H8側の空き) P56/SDA P57/SCL PB0/AN0-PB7/AN7 ------------------------------------------------------------------------------------------*/ /*-----------------------------------------------*/ /* インクルード */ /*-----------------------------------------------*/ #include <3687.h> /* H8 Tinyの内部I/O定義をインクルード(GDL付属のヘッダファイル) */ /*-----------------------------------------------*/ /* 名称定義 */ /*-----------------------------------------------*/ /*---ピン---*/ #define ADDR1 IO.PDR3.BYTE #define ADDR2 IO.PDR1.BYTE #define ADDR3 IO.PDR7.BYTE #define DATA IO.PDR6.BYTE #define M0 IO.PDR5.BIT.B3 #define M1 IO.PDR5.BIT.B4 #define M2 IO.PDR5.BIT.B5 #define CE IO.PDR5.BIT.B0 #define WE IO.PDR5.BIT.B1 #define OE IO.PDR5.BIT.B2 #define ST IO.PDR2.BIT.B4 #define BSY IO.PDR2.BIT.B3 #define TEST IO.PDR2.BIT.B0 #define RX_2 IO.PDR7.BIT.B1 #define TX_2 IO.PDR7.BIT.B2 /*---IO方向---*/ #define DATA_DIR IO.PCR6 #define INPUT 0 #define ALL_INPUT 0x00 #define OUTPUT 1 #define ALL_OUTPUT 0xFF /*---その他---*/ #define LOW 0 #define HIGH 1 /*-----------------------------------------------*/ /* アドレスセット */ /*-----------------------------------------------*/ void set_address(long long myAddr) { /*3687はビット3が抜けているポートが多いので、アドレッシングは少し面倒です。*/ /*今回はポート1、3、7を使って19ビットのアドレスを出力しています。*/ /*引数は19ビット以上必要なのでlong long 型(32ビット)*/ ADDR1 = (unsigned char)(0x000000FF & myAddr); ADDR2 = (unsigned char)( ((0x00000700 & myAddr)>>8) + ((0x00007800 & myAddr)>>7) ); ADDR3 = (unsigned char)( ((0x00008000 & myAddr)>>15) + ((0x00070000 & myAddr)>>12) ); } /*-----------------------------------------------*/ /* IO初期化 */ /*-----------------------------------------------*/ void init_io(void) { /*---アドレスバス---*/ IO.PCR3 = ALL_OUTPUT; /*P30-P37を出力へ*/ IO.PCR1 = ALL_OUTPUT; /*P10-P17を出力へ*/ IO.PCR7 = ALL_OUTPUT; /*P70-P76を出力へ*/ /*---データバス---*/ IO.PCR6 = ALL_INPUT; /*P60-P67をとりあえず入力へ*/ /*---シリアルポート---*/ IO.PMR1.BIT.TXD = 1; /*TXDをシリアル端子に設定*/ SCI3.SCR3.BIT.RE = 1; /*RXDを有効(P21をシリアル端子に設定)*/ IO.PMR1.BIT.TXD2 = 1; /*TXD_2をシリアル端子に設定*/ SCI3_2.SCR3.BIT.RE = 1; /*RXDを有効(P21をシリアル端子に設定)*/ /*---SCI3_2のシリアル設定---*/ SCI3_2.SMR.BIT.COM = 0; /*調歩同期(非同期)*/ SCI3_2.SMR.BIT.CHR = 0; /*データ長8ビット*/ SCI3_2.SMR.BIT.PE = 0; /*パリティなし*/ SCI3_2.SMR.BIT.STOP = 0; /*ストップビット1*/ SCI3_2.SMR.BIT.CKS = 0; /*クロック分周 0:0 1:CLK/4 2:CLK/16 3:CLK/64*/ SCI3_2.BRR = 64; /*ボーレート設定、クロック20MHz時9600bpsの設定値=64(データシートより) H8で"クロック20MHzの場合"は正確な115200bpsは出ません。*/ SCI3_2.SCR3.BIT.TE = 1; /*SCI3_2送信有効*/ /*---コントロール線---*/ IO.PMR5.BYTE = 0x00; /*PORT5を全て汎用IOへ*/ IO.PCR5 = ALL_OUTPUT; /*P50-P55(M0-2,CE.OE.WE)を出力へ*/ IO.PCR2 = 0x15; /*P24,P22,P20(ST,TXD,TEST)を出力へ、P23,P21(BSY,RXD)を入力へ*/ /*---タイマ設定(ウェイト用)---*/ TV.TCRV0.BIT.CCLR = 1; // コンペアマッチAでTCNVクリア TV.TCRV0.BIT.CKS = 0; // 停止 TV.TCRV1.BIT.ICKS = 1; // 上記CKS=3と併用で φ/128=156.25kHz TV.TCSRV.BIT.CMFA = 0; // フラグクリア TV.TCNTV = 0; // タイマカウンタクリア TV.TCORA = 156-1; // タイムコンスタントレジスタA設定 156.25kHz/125≒1ms /*---初期値---*/ set_address(0); M0 = LOW; M1 = LOW; M2 = LOW; CE = HIGH; WE = HIGH; OE = HIGH; ST = HIGH; } /*-----------------------------------------------*/ /* msウェイト */ /*-----------------------------------------------*/ void wait_ms(long num) { long i; TV.TCRV0.BIT.CKS = 3; // カウント開始 for (i = 0; i < num; i++) { while (!TV.TCSRV.BIT.CMFA) ; // TCNTV=TCORAフラグ待ち TV.TCSRV.BIT.CMFA = 0; // フラグクリア } TV.TCRV0.BIT.CKS = 0; // カウント停止 } /*-----------------------------------------------*/ /* メイン */ /*-----------------------------------------------*/ void main(void) { /*---初期設定---*/ init_io(); /*IO初期化*/ wait_ms(3000); /*CMOS-EYEが立ち上がるまで待つ*/ M0 = LOW; /*80x60カラーモード*/ M1 = LOW; M2 = HIGH; CE = HIGH; /*SRAMコントロール端子初期状態*/ WE = HIGH; OE = HIGH; wait_ms(200); /*設定終了まで待つ*/ /*---書き込みテスト---*/ int i; /*ループ変数*/ DATA_DIR = ALL_OUTPUT; /*データバスを出力へ*/ CE = LOW; /*SRAM有効*/ for (i=0; i<11; i++){ /*11回ループ*/ set_address( (long long)i );/*アドレスセット 一応、long long型に変換してるが、GDLの場合、変換しなくても自動で変換してくれます。*/ DATA = (unsigned char)i; /*データバスに値を出力*/ WE = LOW; /*WEをLOWで書き込み*/ WE = HIGH; /*終わったらHIGHに戻す*/ } CE = HIGH; /*SRAM無効*/ DATA_DIR = ALL_INPUT; /*データバスを入力へ(念のため。出力衝突を避ける)*/ /*---読み込み&書き込みテスト---*/ unsigned char my_data; /*読み込み値一時保存変数*/ CE = LOW; /*SRAM有効*/ for (i=0; i<11; i++){ /*11回ループ*/ DATA_DIR = ALL_INPUT; /*データバスを入力へ*/ set_address( i ); /*アドレスセット*/ OE = LOW; /*OE=LOWでデータバスにデータが表れる*/ my_data = DATA; /*データを変数へ保存*/ OE = HIGH; /*読み込みが終わったらOEをHIGHに戻す*/ DATA_DIR = ALL_OUTPUT; /*データバスを出力へ*/ set_address(i+20); /*アドレスセット(読み込みアドレス+20の位置に書き込むことにした)*/ DATA = my_data+10; /*データバスに値を出力*/ WE = LOW; /*WEをLOWで書き込み*/ WE = HIGH; /*終わったらHIGHに戻す*/ } CE = HIGH; /*SRAM無効*/ DATA_DIR = ALL_INPUT; /*データバスを入力へ(念のため。出力衝突を避ける)*/ /*---シリアル命令経由で10秒ごとに19200番地に撮影させるテスト---*/ set_address(19200); /*アドレスを19200番地に指定*/ unsigned char snd_data[17]; /*送信データ格納配列*/ snd_data[0] = 255; /*シンクロバイト*/ snd_data[1] = 98; /*CMOS-EYE ID(初期値は98)*/ snd_data[2] = 1; /*送信データ長*/ snd_data[3] = 10; /*命令10(撮影)*/ int snd_cnt; /*ループ変数*/ while(1){ /*無限ループ開始*/ wait_ms(10000); /*10秒待つ*/ for (snd_cnt=0; snd_cnt<4; snd_cnt++){ /*データ送信ループ*/ while(SCI3_2.SSR.BIT.TDRE == 0){}; /*送信データがエンプティになるまで待つ*/ SCI3_2.TDR = snd_data[snd_cnt]; /*送信データをセット(この後、自動で送信される)*/ } } }