如何访问另一个结构中的struct字段指针并正确写入?

时间:2017-04-25 10:10:20

标签: c pointers struct embedded

我有以下结构(来自我正在使用的库)和一些字段,我想用OR操作分配一个新值。但是我正在调试,我无法看到stm32l4xx_hal_tim.c文件中有什么东西在写:

 typedef struct
 {
   TIM_TypeDef              *Instance;     /*!< Register base address  */
   TIM_Base_InitTypeDef     Init;          /*!< TIM Time Base required parameters */
   HAL_TIM_ActiveChannel    Channel;       /*!< Active channel                    */
   DMA_HandleTypeDef        *hdma[7];      /*!< DMA Handlers array This array is accessed by a @ref DMA_Handle_index */
   HAL_LockTypeDef          Lock;          /*!< Locking object                    */
   __IO HAL_TIM_StateTypeDef   State;         /*!< TIM operation state               */
 }TIM_HandleTypeDef;


typedef struct
{
  __IO uint32_t CR1;         /*!< TIM control register 1,                   Address offset: 0x00 */
  __IO uint32_t CR2;         /*!< TIM control register 2,                   Address offset: 0x04 */
  __IO uint32_t SMCR;        /*!< TIM slave mode control register,          Address offset: 0x08 */
  __IO uint32_t DIER;        /*!< TIM DMA/interrupt enable register,        Address offset: 0x0C */
  __IO uint32_t SR;          /*!< TIM status register,                      Address offset: 0x10 */
  __IO uint32_t EGR;         /*!< TIM event generation register,            Address offset: 0x14 */
  __IO uint32_t CCMR1;       /*!< TIM capture/compare mode register 1,      Address offset: 0x18 */
  __IO uint32_t CCMR2;       /*!< TIM capture/compare mode register 2,      Address offset: 0x1C */
  __IO uint32_t CCER;        /*!< TIM capture/compare enable register,      Address offset: 0x20 */
  __IO uint32_t CNT;         /*!< TIM counter register,                     
 } TIM_TypeDef;

我有一部分我定义的代码:TIM_HandleTypeDef TIMER_Struct;

我想访问TIM_TypeDef结构的字段“CR1”,它是TIM_HandleTypeDef的“* Instance”字段。所以我通过这种方式在函数DRV_TIMER_init()中完成了它:

  #include "main.h"
  #include "stm32l4xx_hal_tim.h"

  uint32_t uwPrescalerValue = 0;
  TIM_HandleTypeDef TIMER_Struct;
  void DRV_TIMER_init(void);

 int main(void)
 {  

   DRV_TIMER_init();
   while(1)
   {

   }

 }

 //where uint32_t SystemCoreClock = 4000000; in other system source file.
 void DRV_TIMER_init(void)
 {
  uwPrescalerValue = (uint32_t)(SystemCoreClock / 1000000) - 1;
  TIMER_Struct.Init.Period            = 100 - 1;
  TIMER_Struct.Init.Prescaler         = uwPrescalerValue;
  TIMER_Struct.Init.ClockDivision     = 0; // these accesses work

  TIMER_Struct.Instance -> CR1 |= 0x01 << 3; // this no works

 }

即使我直接写作:

 TIMER_Struct.Instance -> CR1 = 0xFFFFFFFF; 

它仍然没有效果。

我认为这可能是一个事实,我没有适当地控制指针访问或类似。但我不知道如何访问和修改注释字段的内容。因为我可以看到(调试模式)如何正确写入其余结构字段更新。

此处有任何更正建议吗?

TIMER_Struct.Instance -> CR1 = 0xFFFFFFFF; 

我尝试了不同的方法来取得成功。我需要新的想法。

3 个答案:

答案 0 :(得分:0)

我想你忘了定义TIMER_Struct.Instance

TIM_HandleTypeDef TIMER_Struct;
TIMER_Struct.Instance = TIM1;
//Now you can access TIMER_Struct.Instance
TIMER_Struct.Instance->CR1 = (uint32_t)0xFFFFFFFF;

但我更喜欢使用CMSIS写入寄存器。不需要HAL。使用CMSIS写入寄存器可能如下所示:

TIM1->CR1=(uint32_t)0xFFFFFFFF

答案 1 :(得分:0)

TIM_TypeDef              *Instance;

只是一个指向任何地方的指针,所以你不能取消引用它

你已经在lib中的某个地方定义了这样一个宏:

#define TIM    (TIM_TypeDef*)0xDEADBEEF;

这是将寄存器映射到内存的方式

尝试修改你的代码:

TIMER_Struct.Instance = (TIM_Typedef*)0xDEADBEEF;

或只是

TIMER_Struct.Instance = TIM;

 TIMER_Struct.Instance -> CR1 |= 0x01 << 3;

应该有效

答案 2 :(得分:0)

我找到了解决方案。首先,您必须启用外设时钟。如果不是,则不会对定时器寄存器产生任何影响,因为指针结构字段直接指向硬件寄存器分配。这是我在调试时观察struct var时看不到任何更新的原因。

我在写入分配后启用了clk(使用hal_xxx_init())。那是我的错。

这部分代码中有更正:

//where uint32_t SystemCoreClock = 4000000; in other system source file.
void DRV_TIMER_init(void)
{
  uwPrescalerValue = (uint32_t)(SystemCoreClock / 1000000) - 1;
  TIMER_Struct.Init.Period            = 100 - 1;
  TIMER_Struct.Init.Prescaler         = uwPrescalerValue;
  TIMER_Struct.Init.ClockDivision     = 0; // these accesses work

  if (HAL_TIM_Base_Init(&TIMER_Struct) != HAL_OK)
  {
     /* Initialization Error */
     TIM_Error_Handler();
  }

  TIMER_Struct.Instance -> CR1 |= 0x01 << 3; // this works now

}

如果您尝试将最后一句放在:

之前
HAL_TIM_Base_Init(&TIMER_Struct); 

没有

TIMER_Struct.Instance -> CR1 = xxx; //write mode register acces

会生效。