(続)マイコンカーラリーで1ms毎の高速データログを目指す

試作マイコンカーラリーモータドライブ基板

下のデータを記録する例で実行時間を調べてみました。
このデータは62文字でJMCR事務局が提供しているプログラムライブラリを使ったMicroSD書き込みだと10mSで記録出来る限界のサイズです。

       /* microSD記録処理 */
        if( msdFlag == 1 ) {
            msdPrintf( "%4d,%3d,=\"%4b\",%c,%5d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\r\n",
				line_no,			// 行番号
                pattern,            // パターン番号
                sensor_inp(),       // デジタルセンサ(4bit)
                center_inp() + '0', // デジタルセンサ(中心)
                getAnalogSensor(),  // アナログセンサ
                getServoAngle(),    // ボリューム(ステアリング角度)
				ServoPwm_Buff,		// サーボPWM
                iEncoder,           // ロータリエンコーダ
                motorLF,            // 左前モータ
                motorRF,            // 右前モータ
                motorLR,            // 左後モータ
                motorRR,            // 右後モータ
				ad4			// 坂センサー
            );
            if( ++line_no >= 10000 ) line_no = 0;
        }

まずprintf()を使った書き方、msdPrintfをprintfに置き換えただけです。

      printf( "%4d,%3d,=\"%4b\",%c,%5d,%4d,%4d,%4d,%4d,%4d,%4d,%4d\r\n",
				line_no,			// 行番号
                pattern,            // パターン番号
                sensor_inp(),       // デジタルセンサ(4bit)
                center_inp() + '0', // デジタルセンサ(中心)
                getAnalogSensor(),  // アナログセンサ
                getServoAngle(),    // ボリューム(ステアリング角度)
				ServoPwm_Buff,		// サーボPWM
                iEncoder,           // ロータリエンコーダ
                motorLF,            // 左前モータ
                motorRF,            // 右前モータ
                motorLR,            // 左後モータ
                motorRR,            // 右後モータ
				ad4			// 坂センサー
        );

);

(実測結果)
実行時間 2mS、文字化けでデータが表示されませんでした。
メモリに余裕が無いためかも知れません。

次の例は、データごとに数値→文字列変換関数を使った書き方です
書き方は面倒ですが時間は節約できます。

	uart0_putint(line_no);			uart0_putch(',');		// 行番号
        uart0_putint(pattern);          uart0_putch(',');  // パターン番号
        uart0_puthxb(sensor_inp());     uart0_putch(',');  // デジタルセンサ(4bit)
        uart0_putch(center_inp() + (int)'0'); uart0_putch(','); // デジタルセンサ(中心)
        uart0_putint(getAnalogSensor()); uart0_putch(','); // アナログセンサ
        uart0_putint(getServoAngle());  uart0_putch(',');    // ボリューム(ステアリング角度)
	uart0_putint(ServoPwm_Buff); 	uart0_putch(',');	// サーボPWM
        uart0_putint(iEncoder); 		uart0_putch(',');       // ロータリエンコーダ
        uart0_putint(motorLF);          uart0_putch(',');   // 左前モータ
        uart0_putint(motorRF);          uart0_putch(',');   // 右前モータ
        uart0_putint(motorLR);          uart0_putch(',');   // 左後モータ
        uart0_putint(motorRR);          uart0_putch(',');   // 右後モータ
	uart0_putint(ad4);	// 坂センサー	
	uart0_putcrlf(); 	

(実測結果)
約0.4mSでした、メインループの中で1mS毎のデータを出力するのにも使えそうです。

 

次が出力に使ったプログラムです。

/*======================================*/
/* インクルード                         */
/*======================================*/
#include    
#include    "sfr_r838a.h"               /* R8C/38A SFRの定義ファイル    */
#include    "uart0.h"              /* printf関連処理               */


/*======================================*/
/* シンボル定義                         */
/*======================================*/
#define         TX_BUF_SIZE  128 //64      /* 送信バッファサイズ           */
#define    USE_PRINTF

#ifdef USE_PRINTF
/* printf,scanf関係 */
volatile FILE           _iob[4];  // ダミー変数
#endif

/*======================================*/
/* グローバル変数の宣言                 */
/*======================================*/
/* 送信バッファ */
static volatile char    uart0_tx_buf[TX_BUF_SIZE];
static volatile char    *tx_wp = uart0_tx_buf;
static volatile int     tx_ct = 0;

/**********************************************************************************/
/*		RAM
/**********************************************************************************/

#pragma ADDRESS	dtc_fact_s0t	02C0BH			/* DTC vector address of UART0 transfer interruption */
#pragma ADDRESS	dtc_fact_s0r	02C0AH			/* DTC vector address of UART0 receive interruption */

#pragma ADDRESS	dtccr_dtcd0		02C40H			/* Address of DTC control register in dtcd0 */
#pragma ADDRESS	dtbls_dtcd0		02C41H			/* Address of DTC block size register in dtcd0 */
#pragma ADDRESS	dtcct_dtcd0		02C42H			/* Address of DTC transfer count register in dtcd0 */
#pragma ADDRESS	dtrld_dtcd0		02C43H			/* Address of DTC transfer count reload register in dtcd0 */
#pragma ADDRESS	dtsar_dtcd0		02C44H			/* Address of DTC source address register in dtcd0 */
#pragma ADDRESS	dtdar_dtcd0		02C46H			/* Address of DTC destination address register in dtcd0 */

#pragma ADDRESS	dtccr_dtcd1		02C48H			/* Address of DTC control register in dtcd1 */
#pragma ADDRESS	dtbls_dtcd1		02C49H			/* Address of DTC block size register in dtcd1 */
#pragma ADDRESS	dtcct_dtcd1		02C4AH			/* Address of DTC transfer count register in dtcd1 */
#pragma ADDRESS	dtrld_dtcd1		02C4BH			/* Address of DTC transfer count reload register in dtcd1 */
#pragma ADDRESS	dtsar_dtcd1		02C4CH			/* Address of DTC source address register in dtcd1 */
#pragma ADDRESS	dtdar_dtcd1		02C4EH			/* Address of DTC destination address register in dtcd1 */

unsigned char dtc_fact_s0t;						/* Control Data No. of UART0 transmit interruption */
unsigned char dtc_fact_s0r;						/* Control Data No. of UART0 receive interruption */

unsigned char dtccr_dtcd0;						/* DTC control register in dtcd0 */
unsigned char dtbls_dtcd0;						/* DTC block size register in dtcd0 */
unsigned char dtcct_dtcd0;						/* DTC transfer count register in dtcd0 */
unsigned char dtrld_dtcd0;						/* DTC transfer count reload register in dtcd0 */
unsigned short dtsar_dtcd0;						/* DTC source address register in dtcd0 */
unsigned short dtdar_dtcd0;						/* DTC destination address register in dtcd0 */

unsigned char dtccr_dtcd1;						/* DTC control register in dtcd1 */
unsigned char dtbls_dtcd1;						/* DTC block size register in dtcd1 */
unsigned char dtcct_dtcd1;						/* DTC transfer count register in dtcd1 */
unsigned char dtrld_dtcd1;						/* DTC transfer count reload register in dtcd1 */
unsigned short dtsar_dtcd1;						/* DTC source address register in dtcd1 */
unsigned short dtdar_dtcd1;						/* DTC destination address register in dtcd1 */

#ifdef USE_PRINTF
/************************************************************************/
/* fgetc(ストリームから1文字入力する)から呼ばれるダミー関数        */
/************************************************************************/
int _sget( void ) {    return 0; }

/************************************************************************/
/* fgetc(ストリームから1文字入力する)から呼ばれるダミー関数       */
/************************************************************************/
int _sput( int put_data ) {   return put_data; }

/************************************************************************/
/* fgetc(ストリームから1文字入力する)から呼ばれる1文字出力関数         */
/* 引数  出力文字                                                      */
/* 戻り値 正常:1 以上:EOF                                               */
/************************************************************************/
int _pput( int put_data ) {  return put_data;  }
#endif




/************************************************************************/
/* UART0の初期化、及びprintf関係をUART0に割り当て                       */
/* 引数  通信速度                                                      */
/************************************************************************/
void init_uart0( long bps )
{
 	int brg;

#ifdef USE_PRINTF
    stdin->_cnt = stdout->_cnt = stdaux->_cnt = stdprn->_cnt = 0;
    stdin->_flag = _IOREAD;
    stdout->_flag = _IOWRT;
    stdaux->_flag = _IORW;
    stdprn->_flag = _IOWRT;

    stdin->_mod = _TEXT;
    stdout->_mod = _TEXT;
    stdaux->_mod = _BIN;
    stdprn->_mod = _TEXT;

    stdin->_func_in = NULL;
    stdout->_func_in = NULL;
    stdaux->_func_in = NULL;
    stdprn->_func_in = NULL;

    stdin->_func_out = NULL;
    stdout->_func_out = write;
    stdaux->_func_out = write;
    stdprn->_func_out = NULL;
#endif

    brg = (1250000L*10 / bps+5)/10  - 1; /* 四捨五入処理をしている */	
    /* UART0の設定 */
    u0sr = 0x05;                    /* P14=TXD0,P15=RXD0に設定      */
    u0c0 = 0x00;                    /* カウントソース=20MHz         */
    u0c1 = 0x05;                    /* 送信、受信許可                */
    u0brg = brg;                    /* 通信速度 = brg               */
    u0mr = 0x05;                    /* UART0 データ長8bit 1ストップビット  */
	s0tic = 0x00;					/* UART0 transmit interrupt disabled */

    /* Setting DTCD0 registers */
	dtc_fact_s0t = 0;							/* Setting Control Data No. of UART0 transfer interruption to "No. 0" */
	dtccr_dtcd0 = 0x04;							/* Setting DTC control register in DTCD0 at UART0 transfer interruption */
												/* Normal mode is selected */
												/* Source address is incremented */
												/* Destination address is fixed */
												/* Chain transfers is disabled */
	dtbls_dtcd0 = 1;							/* Setting DTC block size register in DTCD0 */
												/* One-byte is set */
	dtcct_dtcd0 = TX_BUF_SIZE-1;			    /* Setting DTC transfer count register in DTCD0 */
												/* Transmit or receive data size minus one is set to transfer */
	dtrld_dtcd0 = 0;							/* Setting DTC transfer count reload register in DTCD0 */
												/* Not used in normal mode */
	dtsar_dtcd0 = (unsigned short )&uart0_tx_buf[1];
												/* Setting DTC source address register in DTCD0 */
												/* DTC source address is set to the address of "uart0_tx_data[1]"*/
	dtdar_dtcd0 = (unsigned short)&u0tbl;		/* Setting DTC destination register in DTCD0 */
												/* DTC destination address is set to the address of "u0tbl" register */

 	/* Setting DTC activation enable registers */
	dtcen0 = 0x00;								/* Activation disabled */
	dtcen1 = 0x00;								/* Activation disabled */
	dtcen2 = 0x00;								/* Activation disabled */
	dtcen3 = 0x00;								/* Activation disabled */
	dtcen4 = 0x00;								/* Activation disabled */
	dtcen5 = 0x00;								/* Activation disabled */
	dtcen6 = 0x00;								/* Activation disabled */
	dtctl = 0x00;								/* Setting DTC activation control register */
												/* Non-maskable interrupts not generated is selected */
}

/************************************************************************/
/* 1文字ダイレクト出力                                                           */
/* writeとの干渉に注意                                                  */
/************************************************************************/
void uart0_conout( char c )
{
    while( ti_u0c1 == 0 ) ;
    u0tbl = c;
}


/**********************************************************************
* DTCでuart0送信 printfで呼び出される関数名を使用                                             *
************************************************************************/
int write( int c )
{
//	uart0_putch((char)c);
//    return 1;
// p4_5 = 1;
    if( ((char)c == '\n')||( TX_BUF_SIZE-1 <= tx_ct ) ){
		*tx_wp++ = '\n';
		tx_ct++;
    	if(dtcen14 == 1){	/* An activation disabled in UART0 transmission interrupt ? */
    	    tx_wp = &uart0_tx_buf[0];
    	    tx_ct = 0;
		    return 0;
	    }
 	    dtcct_dtcd0 = tx_ct-1;	            /* Setting DTC transfer count register in DTCD0 */
											/* Transmit or receive data size minus one is set to transfer */
	    dtsar_dtcd0 = (unsigned short)&uart0_tx_buf[1];
											/* Setting DTC source address register in DTCD0 */
											/* DTC source address is set */
	    dtcen14 = 1;						/* Activation enabled in UART0 transmission interrupt */
	    te_u0c1 = 1;						/* Transmission enabled in UART0 */
	    while(ti_u0c1 == 0);				/* Wating for no data in U0TB register */
	    u0tbl = uart0_tx_buf[0];			/* Set transmission first data */
        tx_ct = 0;
        tx_wp = uart0_tx_buf;
    }else{
        *tx_wp++ = (char)c;
        tx_ct++;
    }
//p4_5 = 0;
    return 1;   // TRUE
}

/**********************************************************************
*  uart0 CRLF出力                                            *
************************************************************************/
void uart0_putcrlf(void)
{
  write('\r');
  write('\n'); 
}

/**********************************************************************
*  uart0 文字列出力                                            *
************************************************************************/
void uart0_puts(char * s)
{
  int i;
  
  for(i=0; i<256; i++){
    //write((int)*s++);
	uart0_putch(*s++);
    if( !*s )break;
  }
}

/**********************************************************************
*  uart0 2桁16進出力                                         *
************************************************************************/
void uart0_puthex(unsigned char n)
{
    write((int)(n < 10 ? n + '0' : n + 'A' - 10)); } void uart0_puthxb(unsigned char n) { uart0_puthex(n >> 4);
    uart0_puthex(n & 0x0f);
}

/**********************************************************************
*  uart0 4桁16進出力                                         *
************************************************************************/
void uart0_puthxw(unsigned short n)
{
    uart0_puthxb((unsigned char)(n >> 8));
    uart0_puthxb((unsigned char)(n & 0xff));
}

/**********************************************************************
*  uart0 8桁16進出力                                         *
************************************************************************/
void uart0_puthxl(unsigned long n)
{
    uart0_puthxw((unsigned short)(n >> 16));
    uart0_puthxw((unsigned short)(n & 0xffff));
}

/**********************************************************************
*  uart0 10進出力                                         *
************************************************************************/
void uart0_putint(int n)
{
    int n0;
    int i,j;

	if( n < 0 ){
	    write((int)'-');
	    n = -n;
	}
    n0 = 10;
    for(i=0;i < 8 ; i++){
        if(n < n0)break;
        n0 *= 10;
    }
    for(j=0; j <= i; j++){
        n0 /= 10;
        write((int)((n / n0) + '0'));
        n %= n0;
    }
}

void mon_putlong(long n)
{
    long n0;
    int i,j;

	if( n < 0 ){
	    write((int)'-');
	    n = -n;
	}
    n0 = 10;
    for(i=0;i < 8 ; i++){
        if(n < n0)break;
        n0 *= 10;
    }
    for(j=0; j <= i; j++){
        n0 /= 10;
        write((int)((n / n0) + '0'));
        n %= n0;
    }
}


/**********************************************************************
*  数値を文字列に変換して uart0から出力
*  u : 出力する数値
*  len : 文字列の長さ
*  radix : 基数 2,10,16等                                        *
************************************************************************/
const char XStr[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

void uart0_ltoa(unsigned long u, int len, int radix)
{
  int i;

  if(16<radix) radix = 16;
  for(i=0; i < len; i++){
	write((int)XStr[u % radix]);
	u /= radix;
  }
}

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)