/**********************************************************/ /* */ /* CMOS-EYE ATmega128二値化サンプルプログラム */ /* Target Board:BestTechnorogy BTC068 */ /* Environment:GDL1.7.4.0 */ /* Since:2006.9.12 */ /* (c) AsakusaGiken Co., LTD. T.Ishii */ /* */ /**********************************************************/ /*----------------------------------------------------------------------------------- ピンアサイン (CMOS-EYE - ATmega128) A0 PA0 A1 PA1 A2 PA2 A3 PA3 A4 PA4 A5 PA5 A6 PA6 A7 PA7 A8 PC0 A9 PC1 A10 PC2 A11 PC3 A12 PC4 A13 PC5 A14 PC6 A15 PC7 A16 PG0 A17 PG1 A18 PG2 D0 PF0 D1 PF1 D2 PF2 D3 PF3 D4 PF4 D5 PF5 D6 PF6 D7 PF7 M0 PE5 M1 PE6 M2 PE7 CE PE2 WE PE3 OE PE4 ST PB0 BSY PB1 RX PD3/TXD1 *CMOS-EYEシリアル命令用 TX PD2/RXD1 (BTC068上ですでに配線されているもの) LED PB7 *BTC068上のLED (オシロ<-ATmega128) TEST PB2 *TESTは処理時間測定用、オシロスコープで波形を計測 ------------------------------------------------------------------------------------------*/ /*-----------------------------------------------*/ /* ヘッダファイルインクルード */ /*-----------------------------------------------*/ #include /* ATmega128の内部I/O定義をインクルード(GDL付属のヘッダファイル) */ #include // USART通信ライブラリ #include #include // 割り込み関連 char txb[100],rxb[100]; /*-----------------------------------------------*/ /* 名称定義 */ /*-----------------------------------------------*/ /*---ピン---*/ #define ADDR1 PORTA #define ADDR2 PORTC #define ADDR3 PORTG #define DATA_IN PINF #define DATA_OUT PORTF #define M0 PE5 #define M1 PE6 #define M2 PE7 #define CE PE2 #define WE PE3 #define OE PE4 #define ST PB0 #define BSY PB1 #define RX PD3 #define TX PD2 #define LED PB7 #define TEST PB2 /*---IO方向---*/ #define DATA_DIR DDRF //#define INPUT 0 #define ALL_INPUT 0x00 //#define OUTPUT 1 #define ALL_OUTPUT 0xFF /*---その他---*/ #define LOW 0 #define HIGH 1 /*-----------------------------------------------*/ /* グローバル変数 */ /*-----------------------------------------------*/ int R,G,B; /*色平均値格納変数*/ unsigned char pix9[9]; /*周囲8ピクセルデータ格納配列*/ /*-----------------------------------------------*/ /* アドレスセット */ /*-----------------------------------------------*/ void set_address(long myAddr) { /*引数は19ビット以上必要なのでlong 型(32ビット)*/ ADDR1 = (unsigned char)(0x000000FF & myAddr); ADDR2 = (unsigned char)((0x0000FF00 & myAddr)>>8); ADDR3 = (unsigned char)((0x00070000 & myAddr)>>16); } /*-----------------------------------------------*/ /* 設定 (M0-M2,CE,WE,OEのみ) */ /*-----------------------------------------------*/ void set_high(unsigned char myPin) { PORTE |= (1<>BSY; } /*-----------------------------------------------*/ /* LED (LOWで点灯、HIGHで消灯) */ /*-----------------------------------------------*/ void LED_ON(void) { PORTB &= ~(1< threRef) myThre_lo = 0; /* しきい値下限値設定 */ else myThre_lo = threRef - myDiff; if ( (threRef+myDiff) > 255) myThre_hi = 255; /* しきい値上限値設定 */ else myThre_hi = threRef + myDiff; data = 255; /* 開始時は「前処理が白」に設定 */ cnt = 0; /* 相対アドレスを0(320x240の場合はlong型でないとNG)*/ set_low(CE); /* SRAMを有効 */ for (cnt=0; cnt myThre_hi) data = 255; /* しきい値=しきい値+許容値 */ else data = 0; }else{ /* 前回処理結果が白(255)だった場合 */ if (getPixData(stAddr + cnt) > myThre_lo) data = 255; /* しきい値=しきい値-許容値 */ else data = 0; } DATA_DIR = ALL_OUTPUT; /* データバスを出力へ */ setPixData(toAddr + cnt, data); /* 結果(白か黒)を書き込み */ } DATA_DIR = ALL_OUTPUT; /* データバスを入力へ(出力衝突回避) */ set_high(CE); /* SRAMを無効 */ } /*-----------------------------------------------*/ /* 周囲8ピクセルデータ格納関数 */ /*-----------------------------------------------*/ void getPix8(unsigned char* myP, long myAddr, int xSize) { myP[0] = getPixData(myAddr + 1); /*右*/ myP[1] = getPixData(myAddr + 1 - xSize); /*右上*/ myP[2] = getPixData(myAddr - xSize); /*上*/ myP[3] = getPixData(myAddr - 1 - xSize); /*左上*/ myP[4] = getPixData(myAddr - 1); /*左*/ myP[5] = getPixData(myAddr - 1 + xSize); /*左下*/ myP[6] = getPixData(myAddr + xSize); /*下*/ myP[7] = getPixData(myAddr + 1 + xSize); /*右下*/ } /*-----------------------------------------------*/ /* 連結数計算関数 */ /*-----------------------------------------------*/ /* 現在位置が黒で、一個前が白なら連結数+1(反時計周り、右上から始める)*/ int connect(unsigned char* myP) { int i,result; myP[8] = myP[0]; /* 最後の参照は一番目なので一個追加して一番目をコピー */ result = 0; for (i=1; i<9; i++){ /* 二番目の配列からスタートして8回ループ */ if (myP[i] == 0 && myP[i-1] == 255) result++; /* 連結数判定 */ } return result; } /*-----------------------------------------------*/ /* 画面コピー */ /*-----------------------------------------------*/ void copy(long fmAddr, long toAddr, int mySize) { int cnt; unsigned char tempData; for (cnt=0; cnt= 2 && sum <= 5){ /* 周囲黒が2-5個の場合 */ if (connect(pa) == 1 && connect(pb) == 1){ /* 対象と結果両領域とも連結数が1か? */ con_flg = 1; /* 対象発見が有ったか?フラグ 最後まで1だったら有り */ for (cnt=1; cnt<5; cnt++){ /* 上3つと左の4箇所を調査 */ if (b[cnt] == 255){ /* 今までで白になっていて、 */ tempData = a[cnt]; a[cnt] = 255; /* 「そこ」を白にしてみて、 */ if (connect(pa) != 1){ /* 連結数=1かどうか? */ con_flg = 0; /* 白にできない場合、フラグを0へ */ } a[cnt] = tempData; /* 調査後は「そこ」元にもどす。 */ } } /* 4箇所調査end */ if (con_flg == 1){ /* 対象が有ったら白をセット */ myData = 255; find++; } } /* 両方連結数1か?end */ } /* 周囲黒が2-5 end */ DATA_DIR = ALL_OUTPUT; /* 結果書き込み */ setPixData(workAddr + adPointer, myData); DATA_DIR = ALL_INPUT; } /*自ピクセルが黒か?end*/ } /*xループend*/ } /*yループend*/ DATA_DIR = ALL_OUTPUT; copy(workAddr, stAddr, mySize); /* 結果画像を次の元画像へ(結果をコピー) */ } /*対象発見?end*/ DATA_DIR = ALL_INPUT; /* 後処理 */ set_high(CE); } /*-----------------------------------------------*/ /* メイン */ /*-----------------------------------------------*/ void main(void) { unsigned char cnt; /* ループカウント用変数 */ unsigned char diff,x,y; unsigned long length,picAddr; /* ---IO初期化--- */ init_io(); /* ---LED3回点滅--- */ for (cnt=0; cnt<3; cnt++){ LED_ON(); wait_ms(100); LED_OFF(); wait_ms(100); } /* ---CMOS-EYEが立ち上がるまで待つ--- */ wait_ms(3000); /*---画像モード設定---*/ PORTE |= 0x1C; /*80x60白黒モード*/ wait_ms(200); /*設定終了まで待つ*/ /*-----------------------------*/ /* メインループ */ /*-----------------------------*/ diff = 50; /*誤差*/ x = 80; /*画面幅*/ y = 60; /*画面縦*/ length = 4800; /*画面サイズ*/ picAddr = 0; /*撮影開始アドレス*/ set_address(picAddr); /*アドレスを指定*/ shatter(); /*撮影*/ twoValue(picAddr, 4800, length, 80, 5); /* しきい値80、幅5でニ値化(結果は4800番地-) */ /*ここは、二値化画像を保存するデバック用。実際には不用*/ set_low(CE); DATA_DIR = ALL_OUTPUT; copy(4800,19200,length); DATA_DIR = ALL_INPUT; set_high(CE); set_TEST_high(); /*時間計測開始*/ Thinning(4800, 9600,length, x, y); /* 4800番地の二値化画像を細線化(作業領域は9600番地) */ set_TEST_low(); /*時間計測修了*/ while(1); /*終了*/ }