답변
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은 매우 간단하고 좋은 아키텍처입니다.
일반적인 방법은 없지만 사용 가능한 하드웨어 타이머 리소스를 사용하여 다음과 같이 구성 할 수 있습니다. 적절한 시간대를 제공하십시오. 타이밍 코드 실행을 위해 밀리 초 타이머가 다소 코스가 될 수 있다고 제안합니다. 마이크로 초가 더 적절할 수 있습니다.
오버 헤드 나 추가 코드 (또는 하드웨어)가없고, 정확도가 더 높은 간단한 방법은 시뮬레이터에서 코드를 실행하고 프로파일 링하는 것입니다. 필자는 Code Composer Studio에 프로파일 링 및 시뮬레이션 도구가 포함되어 있다고 생각합니다. 다른 툴 체인도 이들을 포함하기 쉽습니다. 테스트중인 코드에 하드웨어 타이밍/대기 시간 종속성이있는 경우이 방법이 적합하지 않을 수 있습니다.
또 다른 간단한 방법은 실행 전후에 사용 가능한 GPIO를 전환하고 오실로스코프 또는 외부 타이머/카운터로 핀을 모니터링하는 것입니다. 이 접근법에는 하드웨어 대기 시간/지터 및 테스트중인 코드의 실행 중에 발생할 수있는 인터럽트와 관련된 모든 오버 헤드가 포함됩니다. 또한 사용 가능한 하드웨어 타이머 리소스가 없을 때 구현할 수도 있습니다.
일부 MSP430 장치에는 디버거를 사용할 때 사용할 수있는 온보드 순환 카운터가 있습니다. 나는 이것이 코드 시퀀스를 비교할 때 매우 정확하다는 것을 발견했다.
기기에 기기가 있는지 알 수 없습니다. 실제로 MSP430f16이라는 이름을 찾지 못했습니다. 일반적으로 "f"다음에 3 자리 또는 4 자리 숫자가 있습니다.
기존 소프트웨어를 변경하지 않고 빠른 것을 찾고 있지만 매우 정확하지 않은 제품을 찾고 계시다면. 프로파일 링하려는 코드 앞뒤에 로깅 중단 점을 사용할 수 있습니다.
IAR을 사용하는 경우이 옵션이 약간 숨겨집니다. 중단 점을 추가하려는 줄을 마우스 오른쪽 단추로 클릭하고 로깅 중단 점을 선택해야합니다.
물론, 로그를 트리거하려면 약간의 지연이 있습니다.이 지연은 일정해야합니다.
표준 StackOverflow 정책에 따라 답변에 대한 포인터 (앞으로 이동하거나 멀리 갈 수도 있음)가 아닌 실제 답변을 제공하는 것이 좋습니다. –
동시에 스택 오버플로가 발생하면 링크의 기능이 향상되지 않습니다. 포인트는 취했지만 샘플 코드는 답안에 추가되었습니다. –
사실, 나는 링크를 추가하는 것도 유용하다는 것에 동의 할 것이다. 어쨌든, 코드로 추가 한 설명은 링크에서 찾을 수있는 것보다 훨씬 낫습니다! 기꺼이 upvoted. –