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
Run Code Online (Sandbox Code Playgroud)
此示例使用计时器来测量传输串行 (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);
}
}
//-------------------------------------------------------------------
//-------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
llvm 的 msp430 后端确实是实验性的,请阅读:损坏,不要依赖它而不仅仅是玩它,gcc 编译器并不简单,但构建起来也不会太痛苦。naken430asm 汇编器非常易于使用,该处理器的 asm 也非常简单,良好的架构......