目次

プロセッサファームウエア

 複数のプロセッサを利用するので、プロセッサごとに
 ファームウエアを作成します。


ACTUATOR

 ACTUATORは、BRAINからの指示でPWM波形を生成します。  ジェネラルフローは、次のように定義します。  I/O初期化では、リストの項目を指定します。  BRAINから送られる、パラメータを含んだコマンドを処理する目的で  ループの中にコマンドインタプリタを含ませます。  コマンドインタプリタを起動するため、フラグ(SFLAG)を使います。  フラグがセットされたなら、受信バッファ中のコマンドとパラメータ  を処理します。  受信割込みは、バッファへ受信文字を保存し、デリミタに  より、フラグをセットします。デリミタは\rとします。  タイマー割込みでは、カウンタと内部変数値を比較し  出力論理値を確定します。  周期動作のために、カウンタを更新し、指定値でゼロに戻します。  カウンタをゼロにすると同時に、DUTY比用カウンタを更新します。

ACTUATORソースコード

#include <avr/io.h> #include <avr/iotn2313.h> #include <avr/interrupt.h> #define FOSC 4000000 #define BAUD 9600 #define MYUBRR (FOSC/16/BAUD)-1 #define OFF 0 #define ON OFF+1 #define BUFSIZE 8 #define RMOTOR 0 #define LMOTOR 1 #define SERVO 2 #define LED 3 #define PMAX 200 #define SERVO_MID 15 #define LED_MAX 180 typedef unsigned char UBYTE ; typedef unsigned short UWORD ; typedef signed char SBYTE ; typedef signed short SWORD ; volatile UBYTE sflag ; volatile UBYTE lflag ; volatile UBYTE sbuf[BUFSIZE] ; volatile UBYTE sindex; volatile UBYTE bport; volatile UBYTE pcnt; volatile UBYTE duty[5] ; volatile UBYTE dutyx[4] ; volatile UBYTE cmd ; volatile UBYTE pduty; volatile UBYTE chx ; volatile UBYTE outv[2] ; volatile UBYTE lcnt ; volatile UBYTE msg_f[] = "Hi !" ; volatile UBYTE msg_h[] = "?:help" ; volatile UBYTE msg_d[] = "D:set ratio" ; volatile UBYTE msg_s[] = "S:show ratio" ; #define NO 0 #define YES NO+1 #define MASKFF 0xff #define MASK0F 0x0f #define MASKF0 0xf0 /*--------------------------------*/ /* Insert user functions protoype */ /*--------------------------------*/ void user_initialize(void); void command_interpret(void); void rs_putchar(UBYTE x); void rs_crlf(void); void rs_putstr(UBYTE *x); UBYTE get_decimal(UBYTE x); /*------*/ /* main */ /*------*/ int main(void) { /* disable interrupt */ cli(); /* initialize port and variables */ user_initialize(); /* enable interrupt */ sei(); /* rs_putstr((UBYTE *)msg_f ); */ /* endless loop */ while ( ON ) { /* SCI handling */ if ( sflag ) { sflag = OFF ; /* serial communication process */ command_interpret(); } /* monitor led */ if ( lflag ) { lflag = OFF ; lcnt++ ; PORTD |= (1 << 6) ; if ( lcnt & 1 ) { PORTD &= ~(1 << 6) ; } } } /* dummy */ return 0 ; } #/*-----------------------*/ /* Insert user functions */ /*-----------------------*/ void user_initialize(void) { UWORD tmp ; /* PORT B */ PORTB = 0b00000000 ; /* 00000000 */ DDRB = 0b11111111 ; /* oooooooo */ /* PORT D */ PORTD = 0b00000000 ; /* 00000000 */ DDRD = 0b11111110 ; /* oooooooi */ /* */ sflag = OFF ; /* initialize serial */ { /* set Baud Rate Registers */ tmp = MYUBRR ; UBRRH = (UBYTE)(tmp >> 8) ; UBRRL = (UBYTE)(tmp & MASKFF) ; /* Enable receive interrupt , receive module and transmit module */ UCSRB = (1 << RXCIE) | (1 << TXEN) | (1 << RXEN) ; /* 8 bits , 1 stop , non parity */ UCSRC = (3 << UCSZ0); } /* clear index */ sindex = 0 ; /* */ lflag = OFF ; /* initialize timer1 */ { /* clear counter */ TCNT1 = 0 ; /* initialize counter */ OCR1A = 49; OCR1B = 99; /* set prescaler (/8) */ /* select clock and prescaler (generate 10kHz) */ TCCR1B = (1 << WGM12) | (1 << CS11) ; /* Enable interrupt */ TIMSK = (1 << OCIE1A) ; } /* */ pcnt = 0 ; lcnt = 0 ; /* initialize duty */ *(duty+RMOTOR) = 0 ; *(duty+LMOTOR) = 0 ; *(duty+SERVO) = SERVO_MID ; *(duty+LED) = LED_MAX; /* initialize duty (interrupt) */ *(dutyx+RMOTOR) = 0 ; *(dutyx+LMOTOR) = 0 ; *(dutyx+SERVO) = SERVO_MID ; *(dutyx+LED) = LED_MAX; } /* command interpriter */ void command_interpret(void) { UBYTE i ; /* get command character */ cmd = *(sbuf+0) ; /* set duty */ if ( cmd == 'D' ) { /* get duty */ *(duty+4) = get_decimal( *(sbuf+1) ); *(duty+4) *= 10 ; *(duty+4) += get_decimal( *(sbuf+2) ); /* get channel number */ chx = get_decimal( *(sbuf+3) ); /* judge */ if ( chx != SERVO ) { *(duty+4) <<= 1 ; } /* store */ *(duty+chx) = *(duty+4) ; } /* show duty ratio */ if ( cmd == 'S' ) { for ( i = 0 ; i < 4 ; i++ ) { /* get duty */ *(duty+4) = *(duty+i) ; /* ajust */ if ( i != SERVO ) { *(duty+4) >>= 1 ; } /* generate code */ *(outv+0) = *(duty+4) / 10 + '0' ; *(outv+1) = *(duty+4) % 10 + '0' ; /* transfer code */ rs_putchar( *(outv+0) ); rs_putchar( *(outv+1) ); rs_crlf(); } } /* help */ if ( cmd == '?' ) { rs_putstr((UBYTE *)msg_h ); rs_putstr((UBYTE *)msg_d ); rs_putstr((UBYTE *)msg_s ); } /* new line */ rs_crlf(); } /* UART receive interrupt */ ISR(USART_RX_vect) { volatile UBYTE ch ; if ( bit_is_clear(UCSRA,FE) ) { /* get 1 charactoer */ ch = UDR ; /* store */ *(sbuf+sindex) = ch ; sindex++ ; /* judge */ if ( ch == '\r' ) { sflag = ON ; sindex = 0 ; } } } void rs_putchar(UBYTE x) { while ( !(UCSRA & (1 << UDRE)) ) ; UDR = x ; } void rs_crlf(void) { rs_putchar('\r'); rs_putchar('\n'); } void rs_putstr(UBYTE *x) { /* send charactor one by one */ while ( *x != '\0' ) { rs_putchar( *x ) ; /* pointer increment */ x++ ; } rs_crlf(); } /* Timer1 interrupt */ ISR(TIMER1_COMPA_vect) { /* initialize */ bport = 0 ; /* judge */ if ( pcnt <= *(dutyx+RMOTOR) ) { bport |= 1 ; } if ( pcnt <= *(dutyx+LMOTOR) ) { bport |= 2 ; } if ( pcnt <= *(dutyx+SERVO) ) { bport |= 4 ; } if ( pcnt <= *(dutyx+LED) ) { bport |= 8 ; } /* set */ PORTB = bport ; /* increment */ pcnt++ ; if ( pcnt == PMAX ) { pcnt = 0 ; /* update */ *(dutyx+RMOTOR) = *(duty+RMOTOR) ; *(dutyx+LMOTOR) = *(duty+LMOTOR) ; *(dutyx+SERVO) = *(duty+SERVO) ; *(dutyx+LED) = *(duty+LED) ; /* monitor */ lflag = ON ; } } UBYTE get_decimal(UBYTE x) { UBYTE result ; /* default */ result = 0 ; /* judge */ if ( '0' <= x && x <= '9' ) { result = x - '0' ; } return result; }

ACTUATORテストデバッグ

 ACTUATORが指定したパルスを出力しているかをテストします。  OSにWindowsXPを持ったパーソナルコンピュータからTeraTermで  ACTUATORにコマンドを送信します。  送信コマンドとパラメータで、指定チャネルの出力波形が変わる  ので、マルチメータでDUTY比を測定します。  これは、単体テストですが、マルチプロセッサで動作する場合  BRAINからコマンドを与えます。  今回利用したLOGIC CONVERTERは、トランジスタを利用した簡易版  です。回路図は、次のようになります。  NPNトランジスタは、小信号タイプであれば、何でもOKです。  廃品種になった2SC1815、2SC945などの大量購入すると\10にも  満たないトランジスタで充分です。

SENSOR DATA LATCH(SDL)

 SENSOR DATA LATCH(SDL)は、SENSORが与える、2つの4ビット値を  結合して8ビットにします。  データ、上下位置指定を与えて、外部割込みで値を入力します。  入力値のビット4、ビット5を右に2ビットシフトし、全体が 4ビットになるように操作します。

SENSOR DATA LATCH(SDL)ソースコード

#include <avr/io.h> #include <avr/iotn2313.h> #include <avr/interrupt.h> #define OFF 0 #define ON OFF+1 typedef unsigned char UBYTE ; typedef unsigned short UWORD ; typedef signed char SBYTE ; typedef signed short SWORD ; volatile UBYTE eflag ; volatile UBYTE dh ; volatile UBYTE dl ; volatile UBYTE bport; #define NO 0 #define YES NO+1 #define MASKFF 0xff #define MASK0F 0x0f #define MASKF0 0xf0 /*------*/ /* main */ /*------*/ int main(void) { UBYTE tmp ; /* disable interrupt */ cli(); /* initialize port and variables */ /* PORT B */ DDRB = 0b11111111 ; /* oooooooo */ PORTB = 0b00000000 ; /* 00000000 */ /* PORT D */ DDRD = 0b00000000 ; /* iiiiiiii */ PORTD = 0b00000000 ; /* 00000000 */ /* */ eflag = OFF ; /* enable INT0 */ MCUCR = (1 << ISC01) ; /* enable INT0 (global) */ GIMSK = (1 << INT0) ; /* enable interrupt */ sei(); /* endless loop */ while ( ON ) { if ( eflag == OFF ) continue ; eflag = OFF ; /* get data */ tmp = PIND ; /* generate code */ dl = ((tmp >> 2) & 12) | (tmp & 3) ; dh = (dl << 4) & MASKF0 ; /* judge */ if ( tmp & 8 ) { bport = (bport & MASK0F) | dh ; } else { bport = (bport & MASKF0) | dl ; } PORTB = bport ; } /* dummy */ return 0 ; } /* EXTERNAL */ ISR(INT0_vect) { eflag = ON ; }

SENSOR DATA LATCH(SDL)テストデバッグ

 SDLが仕様を満たしているかをテストします。  8ビットのデータをON/OFFできるスイッチボードと8個のLEDがあるLEDボードを  利用します。  スイッチは、SDLの入力と次のように接続します。  スイッチボードとは、10ピンケーブルで接続します。  SW3(SEL)をONかOFFにしてSW2(LT)をクリックします。  スイッチ操作とLEDの点灯で、ファームウエアが仕様通りに  動作しているのかを確認します。  SW3(SEL)=ON (SW5,SW4,SW1,SW0)=(H,H,H,H)でSW2クリック 上4ビットのLED=(点、点、点、点) (SW5,SW4,SW1,SW0)=(H,H,H,L)でSW2クリック 上4ビットのLED=(点、点、点、消) (SW5,SW4,SW1,SW0)=(H,H,L,L)でSW2クリック 上4ビットのLED=(点、点、消、消) (SW5,SW4,SW1,SW0)=(H,L,L,L)でSW2クリック 上4ビットのLED=(点、消、消、消) (SW5,SW4,SW1,SW0)=(L,L,L,L)でSW2クリック 上4ビットのLED=(消、消、消、消)  SW3(SEL)=OFF (SW5,SW4,SW1,SW0)=(H,H,H,H)でSW2クリック 下4ビットのLED=(点、点、点、点) (SW5,SW4,SW1,SW0)=(H,H,H,L)でSW2クリック 下4ビットのLED=(点、点、点、消) (SW5,SW4,SW1,SW0)=(H,H,L,L)でSW2クリック 下4ビットのLED=(点、点、消、消) (SW5,SW4,SW1,SW0)=(H,L,L,L)でSW2クリック 下4ビットのLED=(点、消、消、消) (SW5,SW4,SW1,SW0)=(L,L,L,L)でSW2クリック 下4ビットのLED=(消、消、消、消)

SENSOR

 SENSORには、次の機能を持たせます。  3機能のうち、カメラ制御、センサーデータ生成は、これまでの章で  説明したので、BRAINとのインタフェースを考えます。  BRAINとSENSORは、SPIとパラレルインタフェースを利用すると  考えましたが、極力配線を減らすため、SPIだけとします。  SPIは、シリアルインタフェースバスなので、通信プロトコルを  決めなければなりません。  今回は、次のように物理仕様を規定しました。  コマンドは、以下とします。  付加情報は、次の4種とします。  ステータスは、カメラ撮影に関連情報とします。  プロトコルを決めたので、ソースコードを記述します。

SENSORソースコード

#include <avr/io.h> #include <avr/interrupt.h> #define FOSC 16000000 #define BAUD 57600 #define MYUBRR (FOSC/16/BAUD)-1 #define OFF 0 #define ON OFF+1 #define BUFSIZE 8 #define SPI_0 0x01 #define SPI_1 0x02 #define SPI_I 0x03 #define SPI_C 0x04 #define SPI_A 0x05 #define SPI_D 0x06 #define SPI_S 0x07 typedef unsigned char UBYTE ; typedef unsigned short UWORD ; typedef unsigned long ULONG ; typedef signed char SBYTE ; typedef signed short SWORD ; typedef union { struct { unsigned char B0:1; unsigned char B1:1; unsigned char B2:1; unsigned char B3:1; unsigned char B4:1; unsigned char B5:1; unsigned char B6:1; unsigned char B7:1; } BIT ; unsigned char DR ; } FLAGSP ; volatile FLAGSP x_flags ; #define SFLAG x_flags.BIT.B0 #define BFLAG x_flags.BIT.B1 #define CFLAG x_flags.BIT.B2 #define ZFLAG x_flags.BIT.B3 #define GFLAG x_flags.BIT.B4 #define DFLAG x_flags.BIT.B7 volatile FLAGSP s_flags ; #define SBUSY s_flags.BIT.B0 #define SESTABLISH s_flags.BIT.B1 #define SINITIALIZE s_flags.BIT.B2 #define STHRESOLD s_flags.BIT.B3 #define SZFLAG s_flags.BIT.B4 #define SCRANK s_flags.BIT.B5 #define SLANERIGHT s_flags.BIT.B6 #define SLANELEFT s_flags.BIT.B7 #define RING_BSIZE 256 typedef struct { UBYTE data[RING_BSIZE]; UWORD capacity; UWORD rdp; UWORD wrp; } RINGP ; volatile RINGP rings; volatile UBYTE sbuf[BUFSIZE] ; volatile UBYTE sindex; volatile UBYTE spicmd ; volatile UBYTE spicnt ; #define DAT_MAX 480 #define LINE_MAX 60 volatile UBYTE dummy[12]; volatile UBYTE gdat[DAT_MAX] ; volatile UBYTE senx[LINE_MAX] ; volatile UBYTE gindex ; volatile UBYTE threshold ; volatile ULONG tickcount ; #define NO 0 #define YES NO+1 #define MASKFF 0xff #define MASK0F 0x0f #define MASKF0 0xf0 /*--------------------------------*/ /* Insert user functions protoype */ /*--------------------------------*/ void user_initialize(void); void rs_putchar(UBYTE x); void spi_interpret(void); UBYTE establish_c328(void); void send_c328(UBYTE x,UWORD p0,UWORD p1); void send_sync(void); void send_ack(UBYTE x); void send_init(void); void send_snapshot(void); void send_get_img(void); void delay_ms(UBYTE x); void put_ring(UBYTE x); UBYTE get_ring(void); UWORD get_ring_cap(void); void init_ring(void); UBYTE init_c328(void); UBYTE get_c328(void); UBYTE generate_threshold(void); UBYTE is_middle(UWORD x); UBYTE is_edge(UWORD x); /*------*/ /* main */ /*------*/ int main(void) { /* disable interrupt */ cli(); /* initialize port and variables */ user_initialize(); /* enable interrupt */ sei(); /* establish communication bitween c328 and mega328 */ SESTABLISH = establish_c328() ; /* initialzie c328 (dummy shot) */ SINITIALIZE = init_c328() ; /* generate threshold (dummy shot) */ STHRESOLD = generate_threshold() ; /* initialzie c328 */ SINITIALIZE = init_c328() ; /* generate threshold */ STHRESOLD = generate_threshold() ; /* endless loop */ while ( ON ) { /* SPI */ if ( SFLAG == ON ) { SFLAG = OFF ; /* serial communication process */ spi_interpret(); } } /* dummy */ return 0 ; } #/*-----------------------*/ /* Insert user functions */ /*-----------------------*/ void user_initialize(void) { UWORD tmp ; /* PORT B */ PORTB = 0b00000000 ; /* 00000000 */ DDRB = 0b00001011 ; /* iiiioioo */ /* PORT C */ PORTC = 0b00000000 ; /* 00000000 */ DDRC = 0b00111111 ; /* iioooooo */ /* PORT D */ PORTD = 0b00000000 ; /* 00000000 */ DDRD = 0b11111110 ; /* oooooooi */ /* */ x_flags.DR = 0 ; s_flags.DR = 0 ; gindex = 0 ; spicnt = 0 ; tickcount = 0 ; /* initialize timer1 */ { /* clear counter */ TCNT1 = 0 ; /* set compare value */ OCR1A = 1999 ; OCR1B = 3200 ; /* prescaler /8 => 2MHz */ TCCR1B = (1 << WGM12) | (1 << CS11) ; /* enable compare match */ TIMSK1 = (1 << OCIE1A) ; } /* initialize SPI */ { /* Interrupt , MSB first , SLAVE , fosc/2 = 8MHz */ SPCR = 0b11100000 ; SPSR = 0b00000000 ; } /* clear index */ sindex = 0 ; /* clear buffer */ *(sbuf+0) = 0 ; /* initialize serial */ { /* set Baud Rate Registers */ tmp = MYUBRR ; UBRR0H = (UBYTE)((tmp >> 8) & MASKFF) ; UBRR0L = (UBYTE)(tmp & MASKFF) ; /* Enable receive interrupt , receive module and transmit module */ UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0) ; /* 8 bits , 1 stop bit , no parity */ UCSR0C = (3 << UCSZ00); } /* */ init_ring(); } /* UART receive interrupt */ ISR(USART_RX_vect) { volatile UBYTE ch ; if ( !(UCSR0B & (1 << FE0)) ) { /* get 1 charactoer */ ch = UDR0 ; /* store */ put_ring( ch ); } } void rs_putchar(UBYTE x) { while ( !(UCSR0A & (1 << UDRE0)) ) {} UDR0 = x ; } /* SPI receive interrupt */ ISR(SPI_STC_vect) { /* counter increment */ spicnt++ ; spicnt &= 1 ; /* get data */ spicmd = SPDR ; /* set flag */ SFLAG = ON ; } #define SEL_BIT 5 #define LT_BIT 4 #define FLG_BIT 3 #define KEEP_INDEX 30 #define MASK0F 0x0f void spi_interpret(void) { /* judge */ if ( spicnt == 0 ) return ; /* set mode */ if ( spicmd == SPI_0 ) { ZFLAG = ON ; SZFLAG = ZFLAG ; } if ( spicmd == SPI_1 ) { ZFLAG = OFF ; SZFLAG = ZFLAG ; } /* get additional information */ if ( spicmd == SPI_I ) { SPDR = (s_flags.DR >> 4) & MASK0F ; } /* get image */ if ( spicmd == SPI_C ) { GFLAG = get_c328(); } /* clear address */ if ( spicmd == SPI_A ) { gindex = 0 ; } /* show data */ if ( spicmd == SPI_D ) { /* concrete index */ if ( ZFLAG ) { gindex = KEEP_INDEX ; } /* get data */ SPDR = *(senx+gindex); /* increment */ gindex++ ; } /* status */ if ( spicmd == SPI_S ) { SPDR = s_flags.DR & MASK0F ; } } UBYTE establish_c328(void) { UWORD i ; UWORD length ; UBYTE result ; UBYTE gflag ; UBYTE yflag0 ; UBYTE yflag1 ; /* default */ gflag = OFF ; yflag0 = OFF ; yflag1 = OFF ; /* if ( DFLAG ) { rs_puts_txd1((UBYTE *)" _SYNC") ; } */ /* flush */ length = get_ring_cap() ; if ( length ) { for ( i = 0 ; i < length ; i++ ) { result = get_ring() ; } } /* looping */ for ( i = 0 ; i < 60 ; i++ ) { /* send SYNC command */ send_sync(); /* wait */ delay_ms( 10 ) ; /* judge */ if ( get_ring_cap() < 12 ) continue ; /* get data from buffer */ length = get_ring_cap() ; for ( i = 0 ; i < length ; i++ ) { if ( i > 11 ) { result = get_ring() ; } else { *(dummy+i) = get_ring() ; } } /* */ gflag = ON ; if ( gflag ) break ; } /* judge */ if ( *(dummy+1) == 0x0E && *(dummy+2) == 0x0D ) { yflag0 = ON ; } if ( *(dummy+7) == 0x0D && *(dummy+8) == 0x00 ) { yflag1 = ON ; } /* send ACK */ result = gflag & yflag0 & yflag1 ; if ( result ) { send_ack( 0x0D ) ; } return result ; } void send_c328(UBYTE x,UWORD p0,UWORD p1) { rs_putchar( 0xAA ); rs_putchar( x ); rs_putchar( (UBYTE)((p0 >> 8) & MASKFF) ); rs_putchar( (UBYTE)(p0 & MASKFF) ); rs_putchar( (UBYTE)((p1 >> 8) & MASKFF) ); rs_putchar( (UBYTE)(p1 & MASKFF) ); } void send_sync(void) { send_c328(0x0D,0x0000,0x0000); } void send_ack(UBYTE x) { send_c328(0x0D,(x << 8) | 0x00,0x0000); } /* Timer1 interrupt */ ISR(TIMER1_COMPA_vect) { /* increment */ tickcount++ ; } void delay_ms(UBYTE x) { ULONG target ; /* set target */ target = tickcount + (ULONG)x ; /* wait */ while( target > tickcount ) ; } void put_ring(UBYTE x) { UWORD ptmp ; /* store data */ rings.data[rings.wrp] = x ; /* pointer increment */ ptmp = rings.wrp ; ptmp++ ; if ( ptmp == RING_BSIZE ) { rings.wrp = 0 ; } /* capacity increment */ ptmp = rings.capacity ; ptmp++ ; rings.capacity = ptmp ; } UBYTE get_ring(void) { UWORD ptmp ; UBYTE result ; /* default */ result = 0 ; /* judge */ ptmp = rings.rdp ; if ( rings.capacity == 0 ) { return result ; } /* read data */ result = rings.data[ptmp] ; /* pointer increment */ ptmp++ ; if ( ptmp == RING_BSIZE ) { rings.rdp = 0 ; } /* capacity decrement */ ptmp = rings.capacity ; if ( ptmp > 0 ) { rings.capacity = ptmp - 1 ; } return result ; } UWORD get_ring_cap(void) { return rings.capacity ; } void init_ring(void) { /* clear capacity */ rings.capacity = 0 ; /* initialize read pointer */ rings.rdp = 0 ; /* initialize write pointer */ rings.wrp = 0 ; } UBYTE init_c328(void) { UWORD i ; UWORD length ; UBYTE yflag0 ; UBYTE yflag1 ; /* set BUSY */ BFLAG = ON ; /* default */ yflag0 = OFF ; /* send SYNC command */ send_init(); /* wait response */ delay_ms(20) ; /* get data from buffer */ length = get_ring_cap() ; for ( i = 0 ; i < 6 ; i++ ) { *(dummy+i) = get_ring() ; } if ( *(dummy+1) == 0x0E && *(dummy+2) == 0x01 ) { yflag0 = ON ; } /* send snap shot */ send_snapshot(); /* wait response */ delay_ms(20) ; /* get data from buffer */ length = get_ring_cap() ; for ( i = 6 ; i < 12 ; i++ ) { *(dummy+i) = get_ring() ; } if ( *(dummy+7) == 0x0E && *(dummy+8) == 0x05 ) { yflag1 = ON ; } /* reset BUSY */ BFLAG = OFF ; return yflag1 & yflag0 ; } void send_init(void) { send_c328(0x01,0x0003,0x0100); } void send_snapshot(void) { send_c328( 0x05 , 0x0100 , 0x0000 ); } void send_get_img(void) { send_c328(0x04,0x0100,0x0000); } UBYTE get_c328(void) { UWORD i ; UWORD j ; ULONG length ; UBYTE k ; UBYTE resx ; UBYTE result ; UBYTE yflag0 ; UBYTE yflag1 ; /* set BUSY */ BFLAG = ON ; /* set status */ SBUSY = ON ; /* sweap */ length = get_ring_cap(); if ( length ) { for ( i = 0 ; i < (UWORD)length ; i++ ) { result = get_ring() ;} } /* send get picture command */ send_get_img(); /* wait */ while ( ON ) { result = get_ring_cap() ; if ( result >= 12 ) break ; delay_ms(1); } /* copy */ for ( i = 0 ; i < 12 ; i++ ) { *(dummy+i) = get_ring() ; } /* judge */ yflag0 = OFF ; yflag1 = OFF ; if ( *(dummy+1) == 0x0E && *(dummy+2) == 0x04 ) { yflag0 = ON ; } if ( *(dummy+7) == 0x0A && *(dummy+8) == 0x01 ) { yflag1 = ON ; } /* calculate size */ length = *(dummy+11) ; length <<= 8 ; length += *(dummy+10) ; length <<= 8 ; length += *(dummy+9 ) ; if ( length > 32767 ) { /* flush */ length = get_ring_cap(); for ( i = 0 ; i < length ; i++ ) { result = get_ring(); } return OFF ; } /* get image data */ k = 0 ; resx = 0 ; for ( i = 0 ; i < (UWORD)length ; i++ ) { /* wait receive graphic data */ while ( get_ring_cap() <= 0 ) ; /* get 1 pixel */ result = get_ring(); /* judge */ if ( result > threshold ) { resx++ ; } /* block summuation */ j = i % 10 ; if ( j == 9 ) { /* store summuation */ *(gdat+k) = resx ; /* clear block summuation */ resx = 0 ; /* pointer increment */ k++ ; } } /* send ACK */ send_ack( 0x0A ); /* generate sensor data */ SCRANK = OFF ; SLANERIGHT = OFF ; SLANELEFT = OFF ; for ( i = 0 ; i < LINE_MAX ; i++ ) { /* index */ j = (i << 3) ; /* summuation */ resx = 0 ; resx += *(gdat+j+0) ; resx += *(gdat+j+1) ; resx += *(gdat+j+2) ; resx += *(gdat+j+3) ; resx += *(gdat+j+4) ; resx += *(gdat+j+5) ; resx += *(gdat+j+6) ; resx += *(gdat+j+7) ; /* average */ resx >>= 3 ; /* convert */ result = 0 ; if ( *(gdat+j+0) > result ) { result |= 0x80 ; } if ( *(gdat+j+1) > result ) { result |= 0x40 ; } if ( *(gdat+j+2) > result ) { result |= 0x20 ; } if ( *(gdat+j+3) > result ) { result |= 0x10 ; } if ( *(gdat+j+4) > result ) { result |= 0x08 ; } if ( *(gdat+j+5) > result ) { result |= 0x04 ; } if ( *(gdat+j+6) > result ) { result |= 0x02 ; } if ( *(gdat+j+7) > result ) { result |= 0x01 ; } /* reverse store */ *(senx+59-i) = result ; /* judge CRANK */ if ( result == 0xff ) { SCRANK = ON ; } if ( result == 0xf0 || result == 0xf8 ) { SLANELEFT = ON ; } if ( result == 0x0f || result == 0x1f ) { SLANERIGHT = ON ; } } /* */ BFLAG = OFF ; /* reset status */ SBUSY = OFF ; return ON ; } UBYTE generate_threshold(void) { UWORD i ; ULONG length ; UBYTE resx ; UBYTE resy ; UBYTE result ; UBYTE yflag0 ; UBYTE yflag1 ; /* set BUSY */ BFLAG = ON ; /* set status */ SBUSY = ON ; /* sweap */ length = get_ring_cap(); if ( length ) { for ( i = 0 ; i< (UWORD)length ; i++ ) { result = get_ring() ;} } /* send get picture command */ send_get_img(); /* wait */ while ( ON ) { result = get_ring_cap() ; if ( result >= 12 ) break ; delay_ms(1); } /* copy */ for ( i = 0 ; i < 12 ; i++ ) { *(dummy+i) = get_ring() ; } /* judge */ yflag0 = OFF ; yflag1 = OFF ; if ( *(dummy+1) == 0x0E && *(dummy+2) == 0x04 ) { yflag0 = ON ; } if ( *(dummy+7) == 0x0A && *(dummy+8) == 0x01 ) { yflag1 = ON ; } /* calculate size */ length = *(dummy+11) ; length <<= 8 ; length += *(dummy+10) ; length <<= 8 ; length += *(dummy+9 ) ; if ( length > 32767 ) { /* flush */ length = get_ring_cap(); for ( i = 0 ; i < length ; i++ ) { result = get_ring(); } return OFF ; } /* get image data */ resx = 0 ; resy = 0 ; for ( i = 0 ; i < (UWORD)length ; i++ ) { /* wait receive graphic data */ while ( get_ring_cap() <= 0 ) ; /* get 1 pixel */ result = get_ring(); /* judge */ if ( is_middle(i) ) { resx += result ; } if ( is_edge(i) ) { resy += result ; } /* calculate threshold and store it */ if ( i == 4799 ) { resx >>= 3 ; resy >>= 3 ; threshold = ((resx+resy) >> 1) ; } } /* send ACK */ send_ack( 0x0A ); /* */ BFLAG = OFF ; /* reset status */ SBUSY = OFF ; return ON ; } UBYTE is_middle(UWORD x) { UBYTE result ; result = OFF ; if ( x == 1159 ) { result = ON ; } if ( x == 1160 ) { result = ON ; } if ( x == 2359 ) { result = ON ; } if ( x == 2360 ) { result = ON ; } if ( x == 3559 ) { result = ON ; } if ( x == 3540 ) { result = ON ; } if ( x == 4759 ) { result = ON ; } if ( x == 4760 ) { result = ON ; } return result ; } UBYTE is_edge(UWORD x) { UBYTE result ; result = OFF ; if ( x == 1120 ) { result = ON ; } if ( x == 1179 ) { result = ON ; } if ( x == 2320 ) { result = ON ; } if ( x == 2399 ) { result = ON ; } if ( x == 3520 ) { result = ON ; } if ( x == 3599 ) { result = ON ; } if ( x == 4720 ) { result = ON ; } if ( x == 4799 ) { result = ON ; } return result ; }

SENSORテストデバッグ

SENSORをテストするために、STM8Sを利用せずに、ATmega328の  予備ボードを使いました。 SENSORとATmega328をSPIで接続し、さらにATmega328をパーソナル コンピュータと接続し、TeraTermでコマンドを与えてSPI接続が うまくいっているかを検証します。

BRAIN

under construction

BRAINソースコード

under construction

BRAINテストデバッグ

under construction
目次

inserted by FC2 system