2011-12-28 17 views

答えて

4

http://github.com/dwelch67/msp430_samples

サンプルは、タイマーを使用して、時間の計測期間を示し、前と後にタイマーをサンプリングし、その差を引く、それはあなたの実行時間です。

EDIT:

このサンプルではなく、旗の上にロールを監視する、タイマー、除数を使用していますが タイマカウンタレジスタを読んで、あなたが他から1を減算、ダニのタイマー数以上を数えていると仮定します時間を取る。ロールオーバーを避けるために除数を調整し、その後の正確さを試してください。

;This version is written for naken430asm. 
    ;http://www.mikekohn.net/micro/naken430asm_msp430_assembler.php 
    ;naken430asm -o filename.hex filename.s 
    ;mspdebug takes hex files as well as elfs. 

WDTCTL equ 0x0120 


CALBC1_1MHZ equ 0x10FF 
CALDCO_1MHZ equ 0x10FE 

DCOCTL equ 0x56 
BCSCTL1 equ 0x57 
BCSCTL2 equ 0x58 

TACTL equ 0x0160 
TAR  equ 0x0170 
TACCR0 equ 0x0172 
TACCTL0 equ 0x0162 

P1OUT equ 0x0021 
P1DIR equ 0x0022 


    org 0xFC00 

reset: 
    mov #0x0280,r1 

    mov #0x5A80,&WDTCTL ; 0x5A00|WDTHOLD 

    ; use calibrated clock 
    clr.b &DCOCTL 
    mov.b &CALBC1_1MHZ,&BCSCTL1 
    mov.b &CALDCO_1MHZ,&DCOCTL 

    ; make p1.0 and p1.6 outputs 
    bis.b #0x41,&P1DIR 
    bic.b #0x41,&P1OUT 
    bis.b #0x40,&P1OUT 

    ; 1MHz is 1000000 clocks per second 
    ; 1000000 = 0xF4240 
    ; The timers are 16 bit 
    ; Using a divide by 8 in BCSCTL2 gives 
    ; 125000 (0x1E848) clocks in a second 
    ; Using a divide by 8 in the timer gives 
    ; 15625 (0x3D09) timer ticks per second. 

    ; If both divisors are by 8, and we set 
    ; TACCR0 to 0x3D08 and set for count up mode 
    ; then, theory, we can measure seconds. 

    bis.b #0x06,&BCSCTL2 
    mov #0x02C4,&TACTL 
    mov #0x3D08,&TACCR0 
    mov #0x02D0,&TACTL 
    ;mov #0x02D0,&TACTL ; use this instead to blink faster 

loop: 
    xor.b #0x41,&P1OUT 
loop0: 
    bit.w #0x0001,&TACCTL0 
    jz loop0 
    bic.w #0x0001,&TACCTL0 

    jmp loop 


hang: 
    jmp hang 

    org 0xFFE0 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw hang 
    dw reset 

このサンプルでは、​​シリアル(RS232)文字を送信するための時間を計測するタイマーを使用して、前述したようにあなたは、タイマーの複数のサイクルをカウントいけない保証するために、除数を調整(タイマーがロールオーバーすることができ、例えば0xF000から0x3000までは問題ありません。問題にはなりません。可能であれば、あなたが間違いなく転がっていないように分割しすぎると、最高の精度を得るまで、除数を元に戻します。

はい、あなたはロールオーバーを処理するために割り込みを使用できますが、測定しようとしているものが壊れてしまいます。割り込みのオーバーヘッドやタイマのロールオーバーを監視するために使用するメカニズム(あなたはこのために割り込みを必要としません)あなたの測定に許容される)。

#define WDTCTL  (*((volatile unsigned short *)0x0120)) 

#define CALBC1_1MHZ (*((volatile unsigned char *)0x10FF)) 
#define CALDCO_1MHZ (*((volatile unsigned char *)0x10FE)) 
#define CALBC1_8MHZ (*((volatile unsigned char *)0x10FD)) 
#define CALDCO_8MHZ (*((volatile unsigned char *)0x10FC)) 
#define CALBC1_12MHZ (*((volatile unsigned char *)0x10FB)) 
#define CALDCO_12MHZ (*((volatile unsigned char *)0x10FA)) 
#define CALBC1_16MHZ (*((volatile unsigned char *)0x10F9)) 
#define CALDCO_16MHZ (*((volatile unsigned char *)0x10F8)) 

#define DCOCTL (*((volatile unsigned char *)0x56)) 
#define BCSCTL1 (*((volatile unsigned char *)0x57)) 
#define BCSCTL2 (*((volatile unsigned char *)0x58)) 

#define TACTL (*((volatile unsigned short *)0x0160)) 
#define TAR  (*((volatile unsigned short *)0x0170)) 
#define TACCR0 (*((volatile unsigned short *)0x0172)) 
#define TACCTL0 (*((volatile unsigned short *)0x0162)) 


#define P1IN (*((volatile unsigned char *)0x0020)) 
#define P1OUT (*((volatile unsigned char *)0x0021)) 
#define P1DIR (*((volatile unsigned char *)0x0022)) 

// 16MHz clock 
// The timer is 16 bit 
// set to divide by 1 
// 16,000,000/155200 = 138.88889 
#define TACCR0_VALUE 138 

//------------------------------------------------------------------- 
void uart_putc (unsigned short c) 
{ 
    unsigned short sa; 
    unsigned short sb; 
    unsigned short then,now; 

    sa=c<<1; 
    sa|=1<<9; 
    sb=10; 
    then=TAR; 
    while(sb--) 
    { 
     if(sa&1) P1OUT|=1; else P1OUT&=(~1); 
     sa>>=1; 
     while(1) 
     { 
      now=TAR-then; 
      if(now>TACCR0_VALUE) break; 
     } 
     then+=TACCR0_VALUE; 
    } 
} 
//------------------------------------------------------------------- 
void hexstring (unsigned short d, unsigned short cr) 
{ 
    //unsigned short ra; 
    unsigned short rb; 
    unsigned short rc; 

    rb=16; 
    while(1) 
    { 
     rb-=4; 
     rc=(d>>rb)&0xF; 
     if(rc>9) rc+=0x37; else rc+=0x30; 
     uart_putc(rc); 
     if(rb==0) break; 
    } 
    if(cr) 
    { 
     uart_putc(0x0D); 
     uart_putc(0x0A); 
    } 
    else 
    { 
     uart_putc(0x20); 
    } 
} 
//------------------------------------------------------------------- 
void notmain (void) 
{ 
    unsigned short /*sa,*/sb; 
    //unsigned short start; 
    unsigned short then; //,now; 
    unsigned short bitin; 
    //unsigned short log[32]; 

    WDTCTL = 0x5A80; 

    // use calibrated clock 
    DCOCTL = 0x00; 
    BCSCTL1 = CALBC1_16MHZ; 
    DCOCTL = CALDCO_16MHZ; 

    // make p1.0 an output 
    P1DIR |= 0x01; 
    P1OUT |= 0x01; 

    P1DIR &= ~0x02; 


    BCSCTL2&=~0x06; 
    TACTL = 0x0204; 
    TACTL = 0x0220; 

    hexstring(0x1234,1); 
    hexstring(0x5678,1); 

    while(1) 
    { 
     //sa=0; 
     bitin=0; 
     while(1) if((P1IN&2)==0) break; 
     then=TAR; 
     while(1) 
     { 
      if((TAR-then)>=(TACCR0_VALUE>>1)) break; 
     } 
     if(P1IN&2) 
     { 
      bitin>>=1; 
      bitin|=1<<9; 
     } 
     else 
     { 
      bitin>>=1; 
     } 
     then+=(TACCR0_VALUE>>1); 
      for(sb=0;sb<9;sb++) 
     { 
      while(1) 
      { 
       if((TAR-then)>=TACCR0_VALUE) break; 
      } 
      if(P1IN&2) 
      { 
       bitin>>=1; 
       bitin|=1<<9; 
      } 
      else 
      { 
       bitin>>=1; 
      } 
      then+=TACCR0_VALUE; 
     } 
     hexstring(bitin,0); hexstring(bitin>>1,1); 
    } 
} 
//------------------------------------------------------------------- 
//------------------------------------------------------------------- 

LLVMのMSP430のバックエンドが本当に実験的なもので、読み:壊れて、それを再生するには、単により多くのそれに頼っていけない、GCCコンパイラは些細なもののいずれかを構築するために過度に苦痛ではないではありません。 naken430asmアセンブラは非常に使いやすく、このプロセッサのasmは非常にシンプルで良いアーキテクチャです。

+0

標準のStackOverflowポリシーでは、回答へのポインタ(将来的には移動したり離れる可能性があります)だけでなく、実際の回答を提供することをお勧めします。 –

+0

同時にスタックオーバーフローはリンクで行われた改良を失います。ポイントは取られましたが、答えにサンプルコードが追加されました。 –

+0

真実ですが、リンクを追加すると便利です。いずれにしても、コードで追加した説明は、リンクで見つけたものよりはるかに優れています。喜んでupvoted。 –

1

これを行う一般的な方法はありません。使用可能なハードウェアタイマリソースを使用し、適切なタイムベースを提供する。私はタイミングコードの実行のために、ミリ秒タイマーはいくらかコースになるかもしれないことを示唆しています。マイクロ秒がより適切かもしれません。

オーバヘッドや追加コード(またはハードウェア)がなく、おそらく精度が高い簡単な方法は、シミュレータでコードを実行しプロファイルすることです。私はCode Composer Studioにプロファイリングツールとシミュレーションツールが含まれていると思います。他のツールチェーンもそれらを含めることができます。テストされるコードにハードウェアのタイミング/レイテンシの依存性がある場合、この方法は適切ではない可能性があります。

もう1つの簡単な方法は、実行前と実行後に使用可能なGPIOをトグルし、オシロスコープまたは外部タイマー/カウンタでピンをモニタすることです。このアプローチには、ハードウェアレイテンシ/ジッタと、テスト中のコードの実行中に発生する割り込みに関連するオーバーヘッドも含まれます。利用可能なハードウェアタイマーリソースがない場合にも実装できます。

+0

"ミリ秒単位で"私はGPIO +スコープのタイミングがかなり良いと期待しています。 – XTL

+0

@XTL:具体的な質問があれば、間違いありませんが、多くの「ハード」リアルタイムアプリケーションでは、オーバーヘッドが重大な問題になる可能性があります。 – Clifford

1

一部のMSP430デバイスにはオンボードのサイクルカウンタがあり、デバッガを使用するときに使用できます。コードシーケンスを比較すると、これが非常に正確であることがわかりました。

私はあなたのデバイスが1つ持っているかどうかわかりません。実際、私はMSP430f16という名前のものは見つけられませんでしたが、通常は "f"の後に3桁または4桁の数字があります。

0

既存のソフトウェアを変更せずにすばらしいものを探していて、超正確ではないものをお探しの場合は、プロファイリングするコードの前後にロギングブレークポイントを使用できます。

IARを使用している場合、このオプションは少し隠されています。ブレークポイントを追加する行を右クリックし、ログブレークポイントを選択する必要があります。

もちろん、ログをトリガーするには若干の遅延がありますが、この遅延は一定である必要があります。

関連する問題