我希望C代码的执行时间以毫秒为单位,我使用msp430f16
。
任何帮助将不胜感激。
谢谢。
答案 0 :(得分: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非常简单,很好的架构......
答案 1 :(得分:1)
没有通用的方法,您可以使用可用的硬件计时器资源并对其进行配置以提供适当的时基。我建议对于定时代码执行,毫秒定时器可能会有些过程;微秒可能更合适。
一个没有开销或额外代码(甚至硬件)的简单方法,可能更高的准确性,是在模拟器中执行和分析代码。我相信Code Composer Studio包括分析和模拟工具。其他工具链也可能包含它们。如果被测试的代码具有硬件定时/延迟依赖性,则此方法可能不合适。
另一种简单的方法是在执行前后切换可用的GPIO,并使用示波器或外部定时器/计数器监视引脚。此方法将包括硬件延迟/抖动以及与在测试代码执行期间可能发生的中断相关的任何开销。它也可以在没有可用的硬件计时器资源时实现。
答案 2 :(得分:1)
某些MSP430器件具有板载周期计数器,使用调试器时可以使用。我发现在比较代码序列时这是非常准确的。
我不知道你的设备是否有一个。事实上,我没有找到一个名为MSP430f16,它们通常在“f”之后有三到四个数字。
答案 3 :(得分:0)
如果您在不更改现有软件的情况下快速寻找某些内容,但不是非常准确。您可以在要分析的代码之前和之后使用日志记录断点。
如果您正在使用IAR,则此选项有点隐藏。您必须右键单击要添加断点的行并选择记录断点。
当然,触发日志会有一些延迟,这种延迟应该是不变的。