代码之家  ›  专栏  ›  技术社区  ›  zud

了解代码的一部分

  •  1
  • zud  · 技术社区  · 11 年前

    这是微控制器代码的一部分,我无法理解。

    #define GPIO_PORTF_DIR_R        (*((volatile unsigned long *)0x40025400))
    
    int main (void){
         GPIO_PORTF_DIR_R = 0x0E;
    ...}
    

    正如我所理解的,GPIO_PORTF_DIR_R不是一个有效的,(*((volatile unsigned long*)0x40025400))是所指向的地址的内容。 那么如何使用GPIO_PORTF_DIR_R作为变量。这里发生了什么。

    3 回复  |  直到 11 年前
        1
  •  4
  •   Sergey L.    11 年前

    #define 声明预处理器宏。这意味着在编译之前 GPIO_PORTF_DIR_R 将用宏的内容替换代码中的任何位置。因此,实际编译的代码将是

    (*((volatile unsigned long *)0x40025400)) = 0x0E;
    

    这几乎意味着写 0x0E 到那个地址。

    如果希望通过名称引用某些(复杂)数值,则通常使用预处理器宏。这允许您在必要时集中更改该值,但在代码中有一个有意义的名称,而不必为其设置变量。

        2
  •  3
  •   TypeIA    11 年前

    常量值0x40025400用作 存储器地址 。似乎在您的平台(微控制器)上,该地址是 memory-mapped general-purpose I/O port .

    如果代码使其可读性更强,则代码与此等效:

    // pointer to memory address 0x40025400
    volatile unsigned long *p = 0x40025400;
    
    // set that value in memory
    *p = 0x0E;
    
        3
  •  3
  •   Noah Watkins    11 年前

    tl;赋值不是给变量,而是给内存中的特定位置。

    这里的宏可以被认为只是被替换来使用。

    #define GPIO_PORTF_DIR_R (*((volatile unsigned long *)0x40025400))
    int main (void) {
      GPIO_PORTF_DIR_R = 0x0E;
    ...
    

    可以重写为

    int main (void) {
      (*((volatile unsigned long *)0x40025400)) = 0x0E;
    ...
    

    这只是解引用内存地址 0x40025400 并为其赋值0x0E。