Beancurd2333 发表于 2022-9-4 16:35

N32G430 编码器模式如何配置【问题已解决】

本帖最后由 Beancurd2333 于 2022-9-5 23:23 编辑


[*]目的:通过编码器模式,硬件获取电机编码值,从而计算速度和获取转向。


[*]我看过手册也是有这个功能的,但是给的例程没有编码器模式,我也试过自己配置,仿真寄存器值没错(和手册对应),GPIO,定时器也配置过,但就是弄不出来,在这里想问问有没有成功过的大佬,麻烦指教下!感谢!




[*]我的代码:

void Encoder_TIM2_Init(void)
{
      GPIO_InitType GPIO_InitStructure;
      TIM_TimeBaseInitType TIM_TimeBaseStructure;
      TIM_ICInitType TIM_ICInitStructure;
      
      RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
      RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);                //开启复用时钟
      RCC_Pclk1_Config(RCC_HCLK_DIV4);                                                      //配置低速APB时钟(PCLK1)
      RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_TIM2);                //开启定时器2时钟

      GPIO_InitStructure.Pin            = EN_TIM2_GPIO_PIN;
      GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_INPUT;
      GPIO_Peripheral_Initialize(EN_TIM2_GPIO_PORT, &GPIO_InitStructure);
      
      TIM_Base_Struct_Initialize(&TIM_TimeBaseStructure);                //填入缺省值
    TIM_TimeBaseStructure.Period    = 65535;
    TIM_TimeBaseStructure.Prescaler = 0;
    TIM_TimeBaseStructure.ClkDiv    = TIM_CLK_DIV1;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;
    TIM_Base_Initialize(TIM2, &TIM_TimeBaseStructure);
      
      TIM_Encoder_Interface_Set(TIM2, TIM_ENCODE_MODE_TI12, TIM_IC_POLARITY_RISING, TIM_IC_POLARITY_RISING);

      TIM_Input_Struct_Initialize(&TIM_ICInitStructure);
      TIM_ICInitStructure.IcFilter = 10;
      TIM_Input_Channel_Initialize(TIM2, &TIM_ICInitStructure);
      
      TIM_Interrupt_Status_Clear(TIM2, TIM_INT_UPDATE);      //配置溢出更新中断标志位
      
      TIM_Base_Count_Set(TIM2, 0);      //清零定时器计数值
      
      TIM_On(TIM2);
}

void Encoder_TIM3_Init(void)
{
      
}

int Read_Speed(int TIMx)
{
      int value_1;
      switch(TIMx)      //【*】为什么要强制转换short
      {
                case 2:value_1=(short)TIM_Base_Count_Get(TIM2); TIM_Base_Count_Set(TIM2,0); break;//IF是定时器2,1.采集编码器的计数值并保存。2.将定时器的计数值清零。
                //case 3:value_1=(short)TIM_Base_Count_Get(TIM3); TIM_Base_Count_Set(TIM3,0); break;
                default:value_1=0;
      }
      return value_1;
}





[*]仿真寄存器值:











问题已经解决了——GPIO的复用没打开,这个在STM32上面是不用的,总是有不一样的地方,能找到问题就好
下面是我的代码:
void Encoder_TIM3_Init(void)
{
        GPIO_InitType GPIO_InitStructure;
        TIM_TimeBaseInitType TIM_TimeBaseStructure;
        TIM_ICInitType TIM_ICInitStructure;
       
        GPTIMClockFrequency = Common_GPTIM_RCC_Initialize(TIM3, RCC_HCLK_DIV4);                //配置相关时钟

        GPIO_InitStructure.Pin            = EN_TIM3_GPIO_PIN;        //IO口
        GPIO_InitStructure.GPIO_Mode      = GPIO_MODE_INPUT;        //输入模式
        GPIO_InitStructure.GPIO_Alternate = GPIO_AF3_TIM3;                //TIM3复用PA6 PA7【就是这里了,具体要看看手册,搜“AF3”就会有很多相关的】
        GPIO_Peripheral_Initialize(EN_TIM3_GPIO_PORT, &GPIO_InitStructure);        //配置GPIO
       
        //Common_TIM_NVIC_Initialize(TIM3_IRQn, ENABLE);        //需要中断再配置
       
        TIM_Base_Struct_Initialize(&TIM_TimeBaseStructure);                //填入缺省值
    TIM_TimeBaseStructure.Period    = 65535;                        //重装载值
    TIM_TimeBaseStructure.Prescaler = 0;                                //不分频
    TIM_TimeBaseStructure.ClkDiv    = TIM_CLK_DIV1;                //CK_INT(定时器时钟)和 DTS(用于死区时间发生器和数字滤波器(ETR、TIx)的时钟)之间的分频比       
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;        //向上计数
    TIM_Base_Initialize(TIM3, &TIM_TimeBaseStructure);       
       
        TIM_Encoder_Interface_Set(TIM3, TIM_ENCODE_MODE_TI12, TIM_IC_POLARITY_RISING, TIM_IC_POLARITY_RISING);        //编码器模式

        TIM_Input_Struct_Initialize(&TIM_ICInitStructure);                        //输入捕获配置
    TIM_ICInitStructure.Channel   = TIM_CH_1;
    TIM_ICInitStructure.IcPolarity= TIM_IC_POLARITY_RISING;
    TIM_ICInitStructure.IcSelection = TIM_IC_SELECTION_DIRECTTI;
    TIM_ICInitStructure.IcPrescaler = TIM_IC_PSC_DIV1;
    TIM_ICInitStructure.IcFilter    = 0;
    TIM_Input_Channel_Initialize(TIM3, &TIM_ICInitStructure);
       
        TIM_Interrupt_Status_Clear(TIM3, TIM_INT_UPDATE);                //配置溢出中断标志位
        TIM_Interrupt_Enable(TIM3, TIM_INT_UPDATE);                                //使能定时器2中断       
       
        TIM_Base_Count_Set(TIM3, 0);        //清零定时器计数值
       
        TIM_On(TIM3);        //开始定时器2       
}

int Read_Speed(int TIMx)
{
        int value_1;
        switch(TIMx)        //【*】为什么要强制转换short
        {
                case 2:value_1=(short)TIM_Base_Count_Get(TIM2); TIM_Base_Count_Set(TIM2,0); break;//IF是定时器2,1.采集编码器的计数值并保存。2.将定时器的计数值清零。
                case 3:value_1=(short)TIM_Base_Count_Get(TIM3); TIM_Base_Count_Set(TIM3,0); break;
                default:value_1=0;
        }
        return value_1;
}

sy12138 发表于 2022-9-5 18:52

可以参考一下这个代码

chenHaoYan 发表于 2023-1-24 11:11

sy12138 发表于 2022-9-5 18:52
可以参考一下这个代码

感谢大佬,刚好需要,参考参考{:lol:}

便携手到老 发表于 2023-1-28 10:17

感谢楼主分享经验,不错的。

数据采集存储 发表于 2023-1-28 10:31

恭喜楼主。
页: [1]
查看完整版本: N32G430 编码器模式如何配置【问题已解决】