使用24位差分的SysTick代码意味着什么?

使用24位差分的SysTick代码意味着什么?,c,microcontroller,clock,cortex-m,C,Microcontroller,Clock,Cortex M,我对ARM Cortex M MCU编程是新手。在使用SysTick功能时,我遇到了这个函数来检查计时。但是我没有得到第五行的代码。一个大约24位的差异。他们为什么在那一行上做位运算符?它应该做什么 unsigned long Last; // 24-bit time at previous call (12.5ns) unsigned long Elapsed; // 24-bit time between calls (12.5ns) void Action(void){

我对ARM Cortex M MCU编程是新手。在使用SysTick功能时,我遇到了这个函数来检查计时。但是我没有得到第五行的代码。一个大约24位的差异。他们为什么在那一行上做位运算符?它应该做什么

 unsigned long Last;     // 24-bit time at previous call (12.5ns)
 unsigned long Elapsed;  // 24-bit time between calls (12.5ns)
void Action(void){      // function under test
  Now = NVIC_ST_CURRENT_R;         // what time is it now?
  Elapsed = (Last-Now)&0x00FFFFFF; // 24-bit difference
  Last = Now;                      // set up for next...
}

因为Last&appeated有24位(3字节)有意义的数据,但它们是32位(4字节),所以需要将最高有效的8位归零

…&0x00ffffff
执行此操作

你也可以

typedef struct 
{
    uint32_t cnt:24;
}SYSTICK_cnt_t;


uint32_t GetElapsed(uint32_t Now, uint32_t Start)
{
    SYSTICK_cnt_t t = {Now - Start};

    return t.cnt;
}

计数器是24位的,但是当你读取它时,你会得到32位,因为C没有24位变量(至少这个编译器没有)

他们正在做一个24位的减法,通过做一个32位的减法,然后将额外的8位设置为0


将额外位设置为0很重要,因为在16777215(所有位设置为1)之后,计数器将重置为0(所有位设置为0)。如果你只是减去它们,你会看到1-16777215是-16777214(有符号)或4278190082(无符号),但正确的答案是2个记号出现在记号16777215和记号1之间。

&0xffffff
是否有,打字错误?(应该是
0x00ffffff
)@Ryker请告诉我
0x0000000000000ffffff
0x00ffffff
0xffffff
之间的区别。它们有不同的值吗?您引用了OP代码片段,说“the…
&0xffffff
做到了。”。如果你要更改文章中使用的表达式,即使它是等效的,特别是当你引用它时,请提供一个解释,说明为什么要更改它,并且它们是等效的。删除前导零在任何情况下都是混淆。清晰是王道;保留零并保存您和您的同事的理智。这是一个24位计数器,寄存器大小无关紧要计时器是24位的,因此差分的数学运算必须剪裁为24位。以一个3位计数器为例,2-5=-3,0xFFFFFFFD,但5,6,7,0,1,2是5个计数。(2-5)&7=5,这是3位计数器的差值。24位计数器相同。为什么是十进制数字,为什么是有符号的?这里没有带符号的算术。
C没有24位变量(至少这个编译器没有)。
有。它们被称为位域。@P_uj_uu你不能有位域变量。@user253751我明白你的意思。另一件我想澄清的事情是,如果重新加载寄存器的值是n,时钟周期是12.5ns,那么它的限制是它只能精确到(12.5*n)纳秒。如果是这样的话,为什么人们还把它用作时钟?它对我的作用似乎有限。@Shane这意味着它大约每0.2秒重复一次。但也许他们不需要比这更好的时机?只要您至少每0.2秒检查一次,您就可以通过计算返回0的次数,在软件中添加您自己的额外位。甚至可能有一个中断,您可以使用它来检测何时返回到0。