STM32配置外设时,外设结构体寄存器缺省带来的后果。

今天在调试定时器,PWM输入捕获的功能时,奇怪的发现,在某一处多添加一句语句导致改变了定时器模式的配置。

正常情况下,我们配置外设的时候,都会采用这样的方式:

static void TIM_PWM_Input_Config(void)
{
	// bug 这里定义局部变量,会导致初始化的时候结构体数组不为0,使得寄存器初始化出错。
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	
    // 开启TIMx_CLK,x[1,8] 
    RCC_APB2PeriphClockCmd(ADVANCE_TIM_CLK, ENABLE);
    
	//不加这句,局部变量结构体缺省值不确定。
	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
	
	//重装载值 
    TIM_TimeBaseStructure.TIM_Period = ADVANCE_TIM_PERIOD; 
    
	// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
    TIM_TimeBaseStructure.TIM_Prescaler = ADVANCE_TIM_PSC;
    // 计数方式
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;	
    // 初始化定时器TIMx, x[1,8]
	TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);

    /* IC1捕获:上升沿触发 TI1FP1 */
    TIM_ICInitStructure.TIM_Channel = ADVANCE_IC1PWM_CHANNEL;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);


    /* IC2捕获:下降沿触发 TI1FP2 */	
    TIM_ICInitStructure.TIM_Channel = ADVANCE_IC2PWM_CHANNEL;
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);

    /* 选择定时器输入触发: TI1FP1 */
    TIM_SelectInputTrigger(ADVANCE_TIM, TIM_TS_TI1FP1);

    /* 选择从模式: 复位模式 */
	// PWM 输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器CNT 会被复位
    TIM_SelectSlaveMode(ADVANCE_TIM, TIM_SlaveMode_Reset);
    TIM_SelectMasterSlaveMode(ADVANCE_TIM,TIM_MasterSlaveMode_Enable);

    /* 使能高级控制定时器 */
    TIM_Cmd(ADVANCE_TIM, ENABLE);

    /* 使能捕获/比较2中断请求 */
    TIM_ITConfig(ADVANCE_TIM, TIM_IT_CC1, ENABLE);
}

我们可以看到,在配置定时器的时候,其中有一个值是缺省的,查看 TIM_TimeBaseInitTypeDef 结构体可知:

/** 
  * @brief  TIM Time Base Init structure definition  
  * @note   This structure is used with all TIMx except for TIM6 and TIM7.  
  */

typedef struct
{
  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                       This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.
                                       This parameter can be a value of @ref TIM_Counter_Mode */

  uint32_t TIM_Period;            /*!< Specifies the period value to be loaded into the active
                                       Auto-Reload Register at the next update event.
                                       This parameter must be a number between 0x0000 and 0xFFFF.  */ 

  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */

  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                       reaches zero, an update event is generated and counting restarts
                                       from the RCR value (N).
                                       This means in PWM mode that (N+1) corresponds to:
                                          - the number of PWM periods in edge-aligned mode
                                          - the number of half PWM period in center-aligned mode
                                       This parameter must be a number between 0x00 and 0xFF. 
                                       @note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef; 

其中,我们有几个结构体变量,并没有配置它,然而,我们定义结构体的时候,定义的是局部变量,并且,没有初始化局部变量,导致他的值是随机的。
如图:
在这里插入图片描述
可以看到,我们刚进入结构体的时候,变量不是为不确定的值,(这个值和代码有关系,多在某一处定义一条语句,可能就会导致该值是另外一个值。)。
在我们初始化的时候,又缺省了某些值,导致配置出错。
在这里插入图片描述
由图上面可知,实际配置却将定时器模式配置为了中心对齐模式2:
在这里插入图片描述
这样就导致了定时器中的计数器不工作。

因此,我们在配置外设结构体的时候,如果定义了局部变量的结构体,那么最好是所有外设的成员都初始化配置一下,或者调用库中的外设结构体初始化

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

这样就可以避免值不确定的问题。

或者简单一点,直接定义为全部变量。因为定义全部变量的时候,编译器默认初始化为0。

发布了61 篇原创文章 · 获赞 89 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/qq_33559992/article/details/103983955