2011-12-28 72 views

回答

4

http://github.com/dwelch67/msp430_samples

樣品示出了使用的計時器的時間測量週期,採樣定時器之前和之後和減去差,即你的執行時間。

編輯:

此示例使用定時器和除數,而不是監測翻轉標誌讀取 計數寄存器和假設你計數比蜱的計時器數量多,減去一個從另得到時間。調整除數以避免翻滾,並嘗試以後的精確度。

;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例如,沒有問題,0xF000,一旦到0xF100就是一個問題)。如果可能嚴重超過分數,以至於你肯定沒有翻身,那麼縮小分母直到你得到最好的準確度。

是的,你可以使用中斷來處理翻滾,但是這會弄亂你正在測試的東西,你不想這樣做(除非中斷的開銷或用來監視定時器翻轉的任何機制(你不需要中斷)可以接受你的測量)。

#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策略,最好提供一個實際答案,而不僅僅是指向答案的指針(將來可能會移動或消失)。 – 2011-12-29 21:36:32

+0

同時堆棧溢出失去了鏈接上的改進。儘管採取了點,在答案中添加了示例代碼。 – 2011-12-29 23:11:30

+0

沒錯,我同意添加鏈接也很有用。在任何情況下,您使用代碼添加的解釋都比我在鏈接中找到的要好得多!高興地upvoted。 – 2011-12-31 01:05:30

1

沒有通用的方法來執行此操作,您可以使用可用的硬件計時器資源並將其配置爲提供合適的時間基準。我建議對於定時代碼執行,一個毫秒計時器可能有點過程;微秒可能更合適。

一個簡單的方法沒有開銷或額外的代碼(甚至硬件),並且可能更高的準確性將是在模擬器中執行和剖析代碼。我相信Code Composer Studio包含分析和仿真工具。其他工具鏈也可能包括它們。如果正在測試的代碼具有硬件時序/延遲依賴性,則此方法可能不合適。

另一種簡單的方法是在執行前後切換可用的GPIO,並用示波器或外部定時器/計數器監視引腳。這種方法將包括硬件延遲/抖動以及在執行被測代碼期間可能發生的與中斷相關的任何開銷。當沒有可用的硬件定時器資源時也可以實現它。

+0

對於「毫秒」,我期望GPIO +示波器時序非常好。 – XTL 2012-02-29 07:48:40

+0

@XTL:給出具體問題的公平點,但對於許多「硬」實時應用程序而言,開銷可能至關重要。 – Clifford 2012-02-29 12:01:42

1

某些MSP430器件具有片上循環計數器,使用調試器時可以使用該計數器。我發現在比較代碼序列時這是非常準確的。

我不知道你的設備是否有一個。事實上,我還沒有找到一個名爲MSP430f16,它們通常在「f」後面有三個或四個數字。

0

如果您正在尋找快速而不改變現有軟件的東西,但不是超級準確。您可以在要配置的代碼之前和之後使用日誌記錄斷點。

如果您使用的是IAR,則此選項有點隱藏。您必須右鍵單擊要添加斷點的線並選擇記錄斷點。

當然,會有一些延遲觸發日誌,這個延遲應該是不變的。

相關問題