SIEMENS内蒙古阿拉善盟市 西门子代理商——西门子华北一级总代理
| 更新时间 2024-11-26 07:00:00 价格 请来电询价 西门子总代理 PLC 西门子一级代 驱动 西门子代理商 伺服电机 联系电话 15903418770 联系手机 15915421161 联系人 张经理 立即询价 |
详细介绍
3.2 仅在TI2处计数
void TIM4_ENCODER_Init(void) {GPIO_InitTypeDef GPIO_InitStruct; /*GPIO*/TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; /*时基*/TIM_ICInitTypeDef TIM_ICInitStruct; /*输入通道*/ /*GPIO初始化*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); /*使能GPIO时钟 AHB1*/ GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; /*复用功能*/GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; /*速度100MHz*/GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);
/*时基初始化*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /*使能定时器时钟 APB1*/TIM_DeInit(TIM4); TIM_TimeBaseStructInit(&TIM_TimeBaseStruct); TIM_TimeBaseStruct.TIM_Prescaler = ENCODER_TIM_PSC; /*预分频 */ TIM_TimeBaseStruct.TIM_Period = ENCODER_TIM_PERIOD; /*周期(重装载值)*/TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; /*连续向上计数模式*/ TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);
/*编码器模式配置:同时捕获通道1与通道2(即4倍频),极性均为Rising*/TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStruct); TIM_ICInitStruct.TIM_ICFilter = 0; /*输入通道的滤波参数*/TIM_ICInit(TIM4, &TIM_ICInitStruct); /*输入通道初始化*/TIM_SetCounter(TIM4, CNT_INIT); /*CNT设初值*/TIM_ClearFlag(TIM4,TIM_IT_Update); /*中断标志清0*/TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); /*中断使能*/TIM_Cmd(TIM4,ENABLE); /*使能CR寄存器*/}
tmpsmcr = TIMx->SMCR;/* Get the TIMx SMCR register value */ tmpccmr1 = TIMx->CCMR1; /* Get the TIMx CCMR1 register value */ tmpccer = TIMx->CCER;/* Get the TIMx CCER register value */ tmpsmcr &= (uint16_t)~TIM_SMCR_SMS;/* Set the encoder Mode */ tmpsmcr |= TIM_EncoderMode;
/* Select the Capture Compare 1 and the Capture Compare 2 as input */ tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S); tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
/* Set the TI1 and the TI2 Polarities */ tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P); tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
TIMx->SMCR = tmpsmcr; /* 配置数据写入 SMCR 寄存器 */ TIMx->CCMR1 = tmpccmr1; /* 配置数据写入 CCMR1 寄存器 */ TIMx->CCER = tmpccer; /* 配置数据写入 CCER 寄存器 */}
仅在TI2处计数,就是仅统计编码器的通道B的信号跳变,同样可以分为正转和反转两种情况,具体的对应关系参考上面的”仅在TI1处计数“自行分析,实际上通道A与通道B从自身来说功能是等价的。
3.3 在TI1与TI2处均计数在TI1与TI2处均计数,就是讲编码器的通道A与通道B的信号均统计并进行计数,这样可以提高计数频率,实现倍频。
这里还以电机正转为例*:
观察下图,编码器在开始阶段可依次捕获到:通道A上升沿、通道B上升沿、通道A下降沿、通道B下降沿,所以有:
通道A上升沿,通道B为低电平,向上计数,代表电机正转
通道B上升沿,通道A为高电平,向上计数,代表电机正转
通道A下降沿,通道B为高电平,向上计数,代表电机正转
通道B下降沿,通道A为高电平,向上计数,代表电机正转
4编程实现
这里使用的通用定时器中的 TIM4,配置定时器Zui基础的功能就是要配置时基,使用输入功能还要配置定时器的GPIO和输入通道。
void TIM4_ENCODER_Init(void) {GPIO_InitTypeDef GPIO_InitStruct; /*GPIO*/TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; /*时基*/TIM_ICInitTypeDef TIM_ICInitStruct; /*输入通道*/ /*GPIO初始化*/ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); /*使能GPIO时钟 AHB1*/ GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; /*复用功能*/GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; /*速度100MHz*/GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);
/*时基初始化*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /*使能定时器时钟 APB1*/TIM_DeInit(TIM4); TIM_TimeBaseStructInit(&TIM_TimeBaseStruct); TIM_TimeBaseStruct.TIM_Prescaler = ENCODER_TIM_PSC; /*预分频 */ TIM_TimeBaseStruct.TIM_Period = ENCODER_TIM_PERIOD; /*周期(重装载值)*/TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; /*连续向上计数模式*/ TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);
/*编码器模式配置:同时捕获通道1与通道2(即4倍频),极性均为Rising*/TIM_EncoderInterfaceConfig(TIM4, TIM_EncoderMode_TI12,TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);TIM_ICStructInit(&TIM_ICInitStruct); TIM_ICInitStruct.TIM_ICFilter = 0; /*输入通道的滤波参数*/TIM_ICInit(TIM4, &TIM_ICInitStruct); /*输入通道初始化*/TIM_SetCounter(TIM4, CNT_INIT); /*CNT设初值*/TIM_ClearFlag(TIM4,TIM_IT_Update); /*中断标志清0*/TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); /*中断使能*/TIM_Cmd(TIM4,ENABLE); /*使能CR寄存器*/}
这里将定时器的计数溢出值设为65535,即TIM4的计数Zui大值(TIM4为16位计数器)。目的是避免计数器溢出,简化后续的速度计算方式(计数器器若溢出,在计算转速时,还要将溢出的次数考虑进去)。
编码器模式设置为TIM_EncoderMode_TI12,即两路信号均计数,实现4倍频。
编码器两个输入的极性均设置为TIM_ICPolarity_Rising,即极性不反相。
这里编码器模式的设置,调用了TIM_EncoderInterfaceConfig()函数,其内部即是对相关的寄存器进行配置:
tmpsmcr = TIMx->SMCR;/* Get the TIMx SMCR register value */ tmpccmr1 = TIMx->CCMR1; /* Get the TIMx CCMR1 register value */ tmpccer = TIMx->CCER;/* Get the TIMx CCER register value */ tmpsmcr &= (uint16_t)~TIM_SMCR_SMS;/* Set the encoder Mode */ tmpsmcr |= TIM_EncoderMode;
/* Select the Capture Compare 1 and the Capture Compare 2 as input */ tmpccmr1 &= ((uint16_t)~TIM_CCMR1_CC1S) & ((uint16_t)~TIM_CCMR1_CC2S); tmpccmr1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
/* Set the TI1 and the TI2 Polarities */ tmpccer &= ((uint16_t)~TIM_CCER_CC1P) & ((uint16_t)~TIM_CCER_CC2P); tmpccer |= (uint16_t)(TIM_IC1Polarity | (uint16_t)(TIM_IC2Polarity << (uint16_t)4));
TIMx->SMCR = tmpsmcr; /* 配置数据写入 SMCR 寄存器 */ TIMx->CCMR1 = tmpccmr1; /* 配置数据写入 CCMR1 寄存器 */ TIMx->CCER = tmpccer; /* 配置数据写入 CCER 寄存器 */}
相关产品