/

/*======================================*/
/* インクルード */
/*======================================*/
#include
#include "sfr_r838a.h" /* R8C/38A SFRの定義ファイル */
#include "printf_lib.h" /* printf使用ライブラリ */

/*======================================*/
/* シンボル定義 */
/*======================================*/

/* 定数設定 */
#define PWM_CYCLE 39999 /* モータPWMの周期 */
#define SERVO_CENTER 3800 /* サーボのセンタ値 */
#define HANDLE_STEP 25 /* 1゜分の値 */

/* マスク値設定 ×:マスクあり(無効) ○:マスク無し(有効) */
#define MASK2_2 0x66 /* ×○○××○○× */
#define MASK2_0 0x60 /* ×○○××××× */
#define MASK0_2 0x06 /* ×××××○○× */
#define MASK3_3 0xe7 /* ○○○××○○○ */
#define MASK0_3 0x07 /* ×××××○○○ */
#define MASK3_0 0xe0 /* ○○○××××× */
#define MASK4_0 0xf0 /* ○○○○×××× */
#define MASK0_4 0x0f /* ××××○○○○ */
#define MASK4_4 0xff /* ○○○○○○○○ */

/*======================================*/
/* プロトタイプ宣言 */
/*======================================*/
void init( void );
void timer( unsigned long timer_set );
int check_crossline( void );
int check_rightline( void );
int check_leftline( void );
unsigned char sensor_inp( unsigned char mask );
unsigned char dipsw_get( void );
unsigned char pushsw_get( void );
unsigned char startbar_get( void );
void led_out( unsigned char led );
void motor( int accele_l, int accele_r );
void handle( int angle );
int get_ad7( void );

/*======================================*/
/* グローバル変数の宣言 */
/*======================================*/
unsigned long cnt0; /* timer関数用 */
unsigned long cnt1; /* main内で使用 */
int pattern; /* パターン番号 */

/************************************************************************/
/* メインプログラム */
/************************************************************************/
void main( void )
{
int i;
char c;
/* マイコン機能の初期化 */
init(); /* 初期化 */
init_uart0_printf( SPEED_9600 ); /* UART0とprintf関連の初期化 */

asm(" fset I "); /* 全体の割り込み許可 */

pattern = 0;

/* マイコンカーの状態初期化 */
handle( 0 );
motor( 0, 0 );

while( 1 ) {

//if(get_ad7()>512){led_out(0x3);}else{led_out(0x0);}
//printf( "%d\n", get_ad7() );

switch( pattern ) {

/*****************************************************************
パターンについて
0:スイッチ入力 か start信号 待ち
1:スタートバーを開き、計測スタート
2:2秒待ち
3:ゲートセンサ および スイッチ OR stop信号 により計測終了
4:計測タイムの転送
*****************************************************************/

case 0://スタート信号待ち
//プッシュスイッチによる計測開始
if( pushsw_get() && cnt0 > 500 ) {
printf( "GO\n" ); handle(90); cnt0=0; pattern=10; break; }

i = get_uart0( &c );
//スタートボタンによる計測開始
if( i==1 && c=='g' ) {
printf( "START\n" ); handle(90); cnt0=0; pattern=15; break; }
//RESETボタンによる初期位置復帰 
if( i==1 && c=='r' ) {
printf("RESET\n000.000\n"); pattern=0; break; }
//ゲートクローズ
handle( 0 );
break;

case 10://プッシュスイッチ戻り待ち
if( !pushsw_get() ) { pattern = 15; break; }
//STOPボタンによる計測停止
i = get_uart0( &c );
if( i==1 && c=='s' ) { handle(90);
printf( "STOP\n%ld\n", cnt0 ); pattern=30; break; }
//RESETボタンによる初期位置復帰
i = get_uart0( &c );
if( i==1 && c=='r' ) {
printf("RESET\n000.000\n"); pattern=0; break; }
break;

case 15:
//計測時間表示
if(cnt0%100==0){ printf( "%ld\n", cnt0 ); }
//発車時のアナログセンサー反応待ち
if( get_ad7()<64 ) { pattern=20; cnt1=0; break; }
//STOPボタンによる計測停止
i = get_uart0( &c );
if( i==1 && c=='s' ) { handle(90);
printf( "STOP\n%ld\n", cnt0 ); pattern=30; break; }
//RESETボタンによる初期位置復帰
i = get_uart0( &c );
if( i==1 && c=='r' ) {
printf("RESET\n000.000\n"); pattern=0; break; }
break;

case 20:
//計測時間表示
if(cnt0%100==0){ printf( "%ld\n", cnt0 ); }
//STOPボタンによる計測停止
i = get_uart0( &c );
if( i==1 && c=='s' ) { handle(90);
printf( "STOP\n%ld\n", cnt0 ); pattern=30; break; }
//センサーによる計測停止 スタート反応後2秒待つ
if( get_ad7()<64 && cnt1 > 2000 ) {
printf( "%ld\nGOAL\n", cnt0 ); pattern=30; break; }
//プッシュスイッチとRESETボタンによる初期位置復帰
if( pushsw_get() || i==1 && c=='r' ) {
printf("RESET\n000.000\n"); pattern=0; break; }
break;

case 30://計測終了後の待機状態
i = get_uart0( &c );
//プッシュスイッチとRESETボタンによる初期位置復帰
if( pushsw_get() || i==1 && c=='r' ) {
printf("RESET\n000.000\n"); pattern=0; break; }
break;

}
}
}

/************************************************************************/
/* R8C/38A スペシャルファンクションレジスタ(SFR)の初期化 */
/************************************************************************/
void init( void )
{
int i;

/* クロックをXINクロック(20MHz)に変更 */
prc0 = 1; /* プロテクト解除 */
cm13 = 1; /* P4_6,P4_7をXIN-XOUT端子にする*/
cm05 = 0; /* XINクロック発振 */
for(i=0; i<50; i++ ); /* 安定するまで少し待つ(約10ms) */
ocd2 = 0; /* システムクロックをXINにする */
prc0 = 0; /* プロテクトON */

/* ポートの入出力設定 */
prc2 = 1; /* PD0のプロテクト解除 */
pd0 = 0x00; /* 7-0:センサ基板Ver.5 */
pd1 = 0xd0; /* 5:RXD0 4:TXD0 3-0:DIP SW */
p2 = 0xc0;
pd2 = 0xfe; /* 7-0:モータドライブ基板Ver.5 */
pd3 = 0xff; /* */
p4 = 0x20; /* P4_5のLED:初期は点灯 */
pd4 = 0xb8; /* 7:XOUT 6:XIN 5:LED 2:VREF */
pd5 = 0xff; /* */
pd6 = 0xff; /* */
pd7 = 0xff; /* */
pd8 = 0xff; /* */
pd9 = 0x3f; /* */
pur0 = 0x04; /* P1_3〜P1_0のプルアップON */

/* タイマRBの設定 */
/* 割り込み周期 = 1 / 20[MHz] * (TRBPRE+1) * (TRBPR+1)
= 1 / (20*10^6) * 200 * 100
= 0.001[s] = 1[ms]
*/
trbmr = 0x00; /* 動作モード、分周比設定 */
trbpre = 200-1; /* プリスケーラレジスタ */
trbpr = 100-1; /* プライマリレジスタ */
trbic = 0x07; /* 割り込み優先レベル設定 */
trbcr = 0x01; /* カウント開始 */

/* タイマRD リセット同期PWMモードの設定*/
/* PWM周期 = 1 / 20[MHz] * カウントソース * (TRDGRA0+1)
= 1 / (20*10^6) * 8 * 40000
= 0.016[s] = 16[ms]
*/
trdpsr0 = 0x08; /* TRDIOB0,C0,D0端子設定 */
trdpsr1 = 0x05; /* TRDIOA1,B1,C1,D1端子設定 */
trdmr = 0xf0; /* バッファレジスタ設定 */
trdfcr = 0x01; /* リセット同期PWMモードに設定 */
trdcr0 = 0x23; /* ソースカウントの選択:f8 */
trdgra0 = trdgrc0 = PWM_CYCLE; /* 周期 */
trdgrb0 = trdgrd0 = 0; /* P2_2端子のON幅設定 */
trdgra1 = trdgrc1 = 0; /* P2_4端子のON幅設定 */
trdgrb1 = trdgrd1 = SERVO_CENTER; /* P2_5端子のON幅設定 */
trdoer1 = 0xcd; /* 出力端子の選択 */
trdstr = 0x0d; /* TRD0カウント開始 */
}

/************************************************************************/
/* タイマRB 割り込み処理 */
/************************************************************************/
#pragma interrupt intTRB(vect=24)
void intTRB( void )
{
cnt0++;
cnt1++;
}

/************************************************************************/
/* タイマ本体 */
/* 引数  タイマ値 1=1ms */
/************************************************************************/
void timer( unsigned long timer_set )
{
cnt0 = 0;
while( cnt0 < timer_set );
}

/************************************************************************/
/* センサ状態検出 */
/* 引数  マスク値 */
/* 戻り値 センサ値 */
/************************************************************************/
unsigned char sensor_inp( unsigned char mask )
{
unsigned char sensor;

sensor = ~p0;

sensor &= mask;

return sensor;
}

/************************************************************************/
/* クロスライン検出処理 */
/* 戻り値 0:クロスラインなし 1:あり */
/************************************************************************/
int check_crossline( void )
{
unsigned char b;
int ret;

ret = 0;
b = sensor_inp(MASK3_3);
if( b==0xe7 ) {
ret = 1;
}
return ret;
}

/************************************************************************/
/* 右ハーフライン検出処理 */
/* 戻り値 0:なし 1:あり */
/************************************************************************/
int check_rightline( void )
{
unsigned char b;
int ret;

ret = 0;
b = sensor_inp(MASK4_4);
if( b==0x1f ) {
ret = 1;
}
return ret;
}

/************************************************************************/
/* 左ハーフライン検出処理 */
/* 戻り値 0:なし 1:あり */
/************************************************************************/
int check_leftline( void )
{
unsigned char b;
int ret;

ret = 0;
b = sensor_inp(MASK4_4);
if( b==0xf8 ) {
ret = 1;
}
return ret;
}

/************************************************************************/
/* ディップスイッチ値読み込み */
/* 戻り値 スイッチ値 0〜15 */
/************************************************************************/
unsigned char dipsw_get( void )
{
unsigned char sw;

sw = p1 & 0x0f; /* P1_3〜P1_0読み込み */

return sw;
}

/************************************************************************/
/* プッシュスイッチ値読み込み */
/* 戻り値 スイッチ値 ON:1 OFF:0 */
/************************************************************************/
unsigned char pushsw_get( void )
{
unsigned char sw;

sw = ~p2; /* スイッチのあるポート読み込み */
sw &= 0x01;

return sw;
}

/************************************************************************/
/* スタートバー検出センサ読み込み */
/* 戻り値 センサ値 ON(バーあり):1 OFF(なし):0 */
/************************************************************************/
unsigned char startbar_get( void )
{
unsigned char b;

b = ~p0; /* スタートバー信号読み込み */
b &= 0x01;

return b;
}

/************************************************************************/
/* LED制御 */
/* 引数 スイッチ値 LED2:bit1 LED3:bit0 "0":消灯 "1":点灯 */
/* 例)0x3→LED2:ON LED3:ON 0x2→LED2:ON LED3:OFF */
/************************************************************************/
void led_out( unsigned char led )
{
unsigned char data;

led = ~led;
led <<= 6;
data = p2 & 0x3f;
p2 = data | led;
}

/************************************************************************/
/* モータ速度制御 */
/* 引数  左モータ:-100〜100、右モータ:-100〜100 */
/* 0で停止、100で正転100%、-100で逆転100% */
/* 戻り値 なし */
/************************************************************************/
void motor( int accele_l, int accele_r )
{
int sw_data;

sw_data = dipsw_get() + 5;
accele_l = accele_l * sw_data / 20;
accele_r = accele_r * sw_data / 20;

/* 左モータ制御 */
if( accele_l >= 0 ) {
p2 &= 0xfd;
trdgrd0 = (long)( PWM_CYCLE - 1 ) * accele_l / 100;
} else {
p2 |= 0x02;
trdgrd0 = (long)( PWM_CYCLE - 1 ) * ( -accele_l ) / 100;
}

/* 右モータ制御 */
if( accele_r >= 0 ) {
p2 &= 0xf7;
trdgrc1 = (long)( PWM_CYCLE - 1 ) * accele_r / 100;
} else {
p2 |= 0x08;
trdgrc1 = (long)( PWM_CYCLE - 1 ) * ( -accele_r ) / 100;
}
}

/************************************************************************/
/* サーボハンドル操作 */
/* 引数  サーボ操作角度:-90〜90 */
/* -90で左へ90度、0でまっすぐ、90で右へ90度回転 */
/************************************************************************/
void handle( int angle )
{
/* サーボが左右逆に動く場合は、「-」を「+」に替えてください */
trdgrd1 = SERVO_CENTER - angle * HANDLE_STEP;
}
/************************************************************************/
/* A/D値読み込み(AN7) */
/* 引数  なし */
/* 戻り値 A/D値 0〜1023 */
/************************************************************************/
int get_ad7( void )
{
int i;

/* A/Dコンバータの設定 */
admod = 0x03; /* 単発モードに設定 */
adinsel = 0x07; /* 入力端子AN7(P0_0)を選択 */
adcon1 = 0x30; /* A/D動作可能 */
asm(" nop "); /* φADの1サイクルウエイト入れる*/
adcon0 = 0x01; /* A/D変換スタート */

while( adcon0 & 0x01 ); /* A/D変換終了待ち */

i = ad7;

return i;
}
/************************************************************************/
/* end of file */
/************************************************************************/