1. 程式人生 > 實用技巧 >結構體指標中的一點困惑

結構體指標中的一點困惑

在學習32中的滴答定時器的時候,我進入底層去分析程式碼,然後就遇到了攔路虎。我遇到了這樣的程式碼

 1 //core_cms.h中的巨集定義
 2 #define SCS_BASE            (0xE000E000) 
 3 #define SysTick_BASE        (SCS_BASE +  0x0010)  
 4 #define SysTick             ((SysTick_Type *)       SysTick_BASE) 
 5 //滴答定時器結構體
 6 typedef struct
 7 {
 8   __IO uint32_t CTRL;                         /*
!< Offset: 0x00 SysTick Control and Status Register */ 9 __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */ 10 __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */ 11 __I uint32_t CALIB; /*
!< Offset: 0x0C SysTick Calibration Register */ 12 } SysTick_Type; 13 //配置滴答定時器 14 static __INLINE uint32_t SysTick_Config(uint32_t ticks) 15 { 16 if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ 17 18
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ 19 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ 20 SysTick->VAL = 0; /* Load the SysTick Counter Value */ 21 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 22 SysTick_CTRL_TICKINT_Msk | 23 SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ 24 return (0); /* Function successful */ 25 }

在第4行我就不理解結構體指標到底指向的是什麼位置,在我一開始的想法中,我覺得應該指向的是結構體變數的地址。按照這個思路的話,在巨集定義中就沒必要有第2行和第3行的程式碼。

然後我就對程式碼進行除錯,找到了VAL暫存器,以及記憶體。除錯介面如下:

發現指標指向的地址就是SysTick_BASE 的值,我想了一下指標的定義,*A就是代表去訪問A中所存放的地址的內容。這樣我就理解了

後來我對比滴答定時器四個暫存器的地址也均正確,然後也就明白了第2行和第3行程式碼那樣設計的含義——在為多個暫存器提供地址的時候,寫成基準地址+偏移地址這樣的寫法更容易後期來維護程式碼。