プリミティブ関数定義
階層構造で機能を実現したいので、基本となる関数(プリミティブ関数)
を定義します。
I/O初期化
ポート4、A、9、Bの初期値、入出力方向等を設定します。
void user_initialize(void)
{
/* PORT 4 */
P4DR = MASKFF ; /* disable all */
P4DDR = MASKFF ; /* all outputs */
/* PORT 9 */
PADR = 0 ;
PADDR = MASKFF ; /* all outputs */
/* PORT 9 */
P9DR = 0 ;
P9DDR = 0x03 ;
/* P90,P91 outputs others are inputs */
/* PORT B */
PBDR = 0xca ;
PBDDR = MASKCF ; /* PB5,PB4 inputs , others are outputs */
/* initialize timers */
init_timer0();
/* initialize SCI */
init_SCI0( br14400 );
init_SCI1( br57600 );
/* */
x_flags.DR = 0 ;
pre_ah = 0 ;
/* clear SCI buffer */
*(sbuf+0) = 0 ; sindex = 0 ;
/* system parameters */
/*
2^0 uncompressed 1 / compressed 0
2^1 gray scale 1 8bits / 0 2bits(binary)
2^2 size 1 160 x 128 / 0 80 x 64
2^3 preview 1 / snapshot 0
*/
sysparam = 0x03 ; /* sysparam = 0x07 ; */
init_ring();
pwm_cnt = left_duty = right_duty = 0 ;
dcount = 0 ;
}
タイマー初期化
c328にコマンドを送信し、応答があるまでは若干時間が必要です。
その時間を待つには、タイマー・カウンタを利用します。
タイマー・カウンタを初期化する関数を定義します。
void init_timer0(void)
{
/* stop timer */
ITU.TSTR.BIT.STR0 = OFF ;
/* TOER : Timer Output Enable Register
7 **** -> 0
6 **** -> 0
5 EXB4 -> 0
4 EXA4 -> 0
3 EB3 -> 0
2 EB4 -> 0
1 EA4 -> 0
0 EA3 -> 0
*/
ITU.TOER.BYTE = 0 ;
/* TIOR : Timer I/O Control Register
7 **** -> 0
6 IOB2 -> 0 GRB is not output compare match register
5 IOB1 -> 0
4 IOB0 -> 0
3 **** -> 0
2 IOA2 -> 0 GRA is not output compare match register
1 IOA1 -> 0
0 IOA0 -> 0
*/
ITU0.TIOR.BYTE = 0 ;
/* TCR : Timer Control Register
7 **** -> 0
6 CCLR1 -> 0 clear TCNT if GRA = TCNT
5 CCLR0 -> 1
4 CKEG1 -> 0 rising edge
3 CKEG0 -> 0
2 TPSC2 -> 0 φ利用
1 TPSC1 -> 0
0 TPSC0 -> 0
*/
ITU0.TCR.BYTE = 0x20 ;
/* TIER : Timer Interrupt Enable Register
7 **** -> 0
6 *** -> 0
5 *** -> 0
4 *** -> 0
3 *** -> 0
2 OVIE -> 0
1 IMIEB -> 0
0 IMIEA -> 1 select compare match interrupt
*/
ITU0.TIER.BIT.IMIEA = ON ;
/* reference */
ITU0.GRA = ITU0_AREG ;
ITU0.GRB = MASKFFFF ;
/* counter */
ITU0.TCNT = 0 ;
/* start timer */
ITU.TSTR.BIT.STR0 = ON ;
}
タイマー割込みが発生した場合の処理を記述します。
関数delay_msのために、1msごとにカウンタをディクリメントします。
PWMのDUTY比率を指定するため、変数をインクリメントし、指定値と比較
することで、出力論理値を決定します。
void int_imia0(void)
{
UBYTE dummy ;
/* clear flag */
dummy = ITU0.TSR.BIT.IMFA ;
ITU0.TSR.BIT.IMFA = OFF ;
/* judge */
if ( TTRG ) {
/* decrement counter */
wcnt-- ;
if ( wcnt == 0 ) {
TTRG = OFF ;
TFLAG = ON ;
}
}
/* pwm handling */
pwm_cnt++ ;
if ( pwm_cnt == 100 ) { pwm_cnt = 0 ; }
LMOTOR = RMOTOR = OFF ;
if ( pwm_cnt < left_duty ) { LMOTOR = ON ; }
if ( pwm_cnt < right_duty ) { RMOTOR = ON ; }
PB.DR.BIT.B2 = LMOTOR ;
PB.DR.BIT.B0 = RMOTOR ;
}
c328コマンド送信
c328には、6バイトのコマンドを送信します。
コマンドごとに6バイトを、記述するのは面倒なので
必要なパラメータだけを指定する関数を使います。
6バイトのコマンドを送信する関数を定義します。
void send_command(void)
{
/* 0xAA */
rs_put_txd0( 0xAA ) ;
/* command */
rs_put_txd0( cmdp.param[0] );
/* parameters */
rs_put_txd0( cmdp.param[1] );
rs_put_txd0( cmdp.param[2] );
rs_put_txd0( cmdp.param[3] );
rs_put_txd0( cmdp.param[4] );
}
6バイトのコマンドをパラメータ設定するにあたり
最初の1バイトは固定なので、5バイトを0クリアする
関数を定義します。
void clear_command(void)
{
cmdp.param[0] = 0 ;
cmdp.param[1] = 0 ;
cmdp.param[2] = 0 ;
cmdp.param[3] = 0 ;
cmdp.param[4] = 0 ;
}
c328との通信を確立しなければ、コマンドを受け付けません。
SYNCを最大60回送信し、その間にACKを受信したかどうかを
論理値で返す関数を定義します。
UBYTE confirm_sync(void)
{
UBYTE i,tmp,doflag ;
/* default */
doflag = OFF ;
/* looping */
for ( i = 0 ; i < 60 ; i++ ) {
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" SYNC") ; }
/* send command */
send_sync();
/* wait */
delay_ms( 20 ) ;
/* judge */
if ( get_capacity() >= 12 ) {
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" Get Ack and Sync") ; }
doflag = ON ;
}
if ( doflag ) break ;
}
/* judge */
if ( doflag ) {
/* copy */
for ( i = 0 ; i < 12 ; i++ ) {
*(rbuf+i) = tmp = get_ring() ;
if ( DFLAG ) {
rs_put_txd1( get_hex( (tmp >> 4) & MASK0F ) );
rs_put_txd1( get_hex( tmp & MASK0F ) );
rs_put_txd1( ' ' );
}
}
i = 0 ;
if ( judge_response(0) == RES_ACK && *(rbuf+2) == 0x0D ) {
i++ ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" CONFIRM ACK") ; }
}
/* send ACK */
if ( judge_response(6) == RES_SYNC && *(rbuf+8) == 0x00 ) {
i++ ;
send_ack( 0x0D ) ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" SEND ACK") ; }
}
}
return doflag ;
}
パーソナルコンピュータをホストとして、マイクロコンピュータ内部に
c328をどう動かすのかを指定する変数を用意します。この変数へと値を
代入するためのラッパー関数を定義します。
UBYTE set_params(UBYTE x)
{
UBYTE i,doflag ;
/* clear */
clear_command();
/* send initial parameters */
cmdp.param[0] = 0x01 ;
/* color type
0x01 2-bit Gray Scale
0x02 4-bit Gray Scale
0x03 8-bit Gray Scale
0x05 12-bit Color
0x06 16-bit Color
0x07 JPEG
*/
cmdp.param[2] = 0x01 ;
if ( x & 2 ) { cmdp.param[2] = 0x03 ; }
/* preview resolution
0x01 80 x 60
0x03 160 x 120
snap shot resolution
0x01 80 x 64
0x03 160 x 128
0x05 320 x 240
0x07 640 x 480
*/
cmdp.param[3] = 0x01 ;
if ( x & 4 ) { cmdp.param[3] = 0x03 ; }
/* JPEG resolution
0x01 80 x 64
0x03 160 x 128
0x05 320 x 240
0x07 640 x 480
*/
cmdp.param[4] = 0x03 ;
/* send command */
send_command();
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" SET PARAMETERS") ; }
/* wait */
while ( get_capacity() < 6 ) ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" exit PARAMETERS WAIT") ; }
/* copy */
for ( i = 0 ; i < 6 ; i++ ) { *(rbuf+i) = get_ring() ; }
/* judge */
doflag = ON ;
if ( judge_response(0) == RES_ACK && *(rbuf+2) == 1 ) {
doflag = OFF ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" confirm ACK") ; }
}
return doflag ;
}
SnapShotに必要なパラメータで指定する関数を定義します。
UBYTE set_snapshot(void)
{
UBYTE i,doflag ;
/* send command */
send_snapshot( sysparam );
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" SET SNAPSHOT") ; }
/* wait */
while ( get_capacity() < 6 ) ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" exit SNAPSHOT WAIT") ; }
/* copy */
for ( i = 0 ; i < 6 ; i++ ) { *(rbuf+i) = get_ring() ; }
/* judege */
doflag = ON ;
if ( judge_response(0) == RES_ACK && *(rbuf+2) == 5 ) {
doflag = OFF ;
if ( DFLAG ) { rs_puts_txd1((UBYTE *)" confirm ACK") ; }
}
return doflag ;
}
Syncに必要なパラメータを指定する関数を定義します。
void send_sync(void)
{
clear_command();
/* command */
cmdp.param[0] = 0x0D ;
/* send */
send_command() ;
}
Ackに必要なパラメータを指定する関数を定義します。
void send_ack(UBYTE x)
{
clear_command();
/* command */
cmdp.param[0] = 0x0E ; cmdp.param[1] = x ;
/* send */
send_command() ;
}
ShapShotに必要なパラメータを指定する関数を定義します。
void send_snapshot(UBYTE onoff)
{
clear_command();
/* command */
cmdp.param[0] = 0x05 ;
cmdp.param[1] = 0x00 ; /* compressed */
if ( onoff & 1 ) { cmdp.param[1] = 0x01 ; } /* uncompressed */
/* send */
send_command() ;
}
GetPictureに必要なパラメータを指定する関数を定義します。
void send_getpicture(UBYTE onoff)
{
clear_command();
/* command */
cmdp.param[0] = 0x04 ;
cmdp.param[1] = onoff ;
/* send */
send_command() ;
}
c328応答判断
c328はコマンドに応答し、6バイトのコードを返信します。
6バイトの返信コードが、何であるかを判定します。
6バイトの最初は0xAA固定なので、続く16進コードが何かで
応答を判断します。
UBYTE judge_response(UBYTE x)
{
UBYTE result ;
/* set default */
result = RES_NONE ;
/* check command */
if ( *(rbuf+x) == 0xAA ) {
if ( *(rbuf+x+1) == 0x0A ) { result = RES_DATA ; }
if ( *(rbuf+x+1) == 0x0D ) { result = RES_SYNC ; }
if ( *(rbuf+x+1) == 0x0E ) { result = RES_ACK ; }
if ( *(rbuf+x+1) == 0x0F ) { result = RES_NAK ; }
}
return result ;
}
目次
前
次