2011-12-28 37 views

Trả lời

4

http://github.com/dwelch67/msp430_samples

các mẫu hiển thị thời gian đo thời gian bằng cách sử dụng bộ đếm thời gian, mẫu bộ đếm thời gian trước và sau và trừ sự khác biệt, đó là thời gian thực hiện của bạn.

EDIT:

mẫu này sử dụng tính giờ và ước, thay vì theo dõi cuộn trên lá cờ đọc quầy đăng ký hẹn giờ và giả sử bạn đang đếm nhiều hơn số timer tick, trừ một từ khác để có được thời gian. Điều chỉnh các ước muốn để tránh việc cuộn và cũng cố gắng kiểm tra độ chính xác mà bạn đang theo dõi.

;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 

Mẫu này sử dụng bộ đếm thời gian để đo lường một khoảng thời gian để truyền ký tự nối tiếp (RS232), như đã đề cập ở trên điều chỉnh các ước để đảm bảo bạn không đếm nhiều hơn một chu kỳ của timer (bộ đếm thời gian có thể cuộn qua, đó là tốt 0xF000 đến 0x3000 ví dụ, không phải là một vấn đề, 0xF000, khoảng một lần đến 0xF100 đó là một vấn đề). Nếu có thể gộp lại quá mức để bạn chắc chắn không lăn qua, quy mô trở lại số chia cho đến khi bạn có được độ chính xác cao nhất. Có, bạn có thể sử dụng một ngắt để đối phó với cuộn trên nhưng điều đó messes lên điều bạn đang cố gắng để đo lường, bạn không muốn làm điều đó (trừ khi chi phí của các ngắt hoặc bất cứ cơ chế bạn sử dụng để giám sát rollover hẹn giờ (bạn không cần một ngắt cho điều này) là chấp nhận được để đo lường của bạn).

#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 của MSP430 backend là thực sự thử nghiệm, đọc: phá vỡ, đừng dựa vào nó nhiều hơn là chỉ để chơi với nó, trình biên dịch gcc là không nhỏ nhưng không quá đau đớn để xây dựng một trong hai. Bộ kết hợp naken430asm rất dễ sử dụng và asm cho bộ vi xử lý này khá đơn giản, cấu trúc tốt ...

+0

Theo chính sách StackOverflow chuẩn, bạn nên cung cấp câu trả lời thực tế, không chỉ là một con trỏ đến câu trả lời (có thể di chuyển hoặc biến mất trong tương lai). –

+0

tại cùng một thời gian tràn ngăn mất những thay đổi được thực hiện tại liên kết. Điểm lấy, mặc dù mã mẫu được thêm vào trong câu trả lời. –

+0

Đúng, và tôi đồng ý rằng việc thêm liên kết cũng hữu ích. Trong mọi trường hợp, lời giải thích mà bạn đã thêm bằng mã sẽ tốt hơn nhiều so với những gì tôi có thể tìm thấy ở liên kết! Gladly upvoted. –

1

Không có cách chung để thực hiện việc này, bạn có thể sử dụng tài nguyên hẹn giờ phần cứng sẵn có và cấu hình nó cung cấp một timebase thích hợp. Tôi sẽ đề nghị rằng để thực thi mã thời gian, một bộ đếm thời gian mili giây có thể là một phần nào đó; micro giây có thể phù hợp hơn.

Một phương pháp đơn giản hơn không có mã chi phí hoặc mã bổ sung (hoặc thậm chí phần cứng) và có lẽ chính xác hơn, sẽ là thực thi và cấu hình mã trong trình mô phỏng. Tôi tin rằng Code Composer Studio bao gồm các công cụ mô phỏng và lược tả. Các chuỗi công cụ khác cũng tương tự như vậy. Nếu mã được kiểm tra có phụ thuộc thời gian/độ trễ phần cứng, phương pháp này có thể không phù hợp.

Một phương pháp đơn giản khác là chuyển đổi GPIO sẵn có trước và sau khi thực hiện và giám sát pin bằng dao động hoặc bộ đếm thời gian/bộ đếm bên ngoài. Cách tiếp cận này sẽ bao gồm độ trễ phần cứng/jitter và cũng có bất kỳ chi phí nào liên quan đến các ngắt có thể xảy ra trong quá trình thực thi mã đang được thử nghiệm. Nó cũng có thể được thực hiện khi không có tài nguyên hẹn giờ phần cứng có sẵn.

+0

Đối với "Trong mili giây", tôi mong đợi thời gian phạm vi GPIO + là khá tốt. – XTL

+0

@XTL: Điểm công bằng được đưa ra cho câu hỏi cụ thể, nhưng đối với nhiều ứng dụng thời gian thực "khó", chi phí có thể rất quan trọng. – Clifford

1

Một số thiết bị MSP430 có bộ đếm chu trình tích hợp, có sẵn khi sử dụng trình gỡ lỗi. Tôi đã thấy rằng điều này là cực kỳ chính xác khi so sánh các chuỗi mã.

Tôi không biết liệu thiết bị của bạn có mặc dù không. Trong thực tế, tôi đã không tìm thấy một trong những tên MSP430f16, họ thường có ba hoặc bốn chữ số sau khi "f".

0

Nếu bạn đang tìm kiếm thứ gì đó nhanh chóng mà không thay đổi phần mềm hiện có, nhưng không phải siêu chính xác. Bạn có thể sử dụng các điểm ngắt đăng nhập trước và sau mã bạn muốn cấu hình.

Nếu bạn đang sử dụng IAR, tùy chọn này bị ẩn một chút. Bạn phải nhấp chuột phải vào dòng bạn muốn thêm điểm ngắt và chọn điểm ngắt đăng nhập.

Ofcourse, sẽ có một số chậm trễ để kích hoạt nhật ký, sự chậm trễ này phải không đổi.

Các vấn đề liên quan