/* * @Author: mikey.zhaopeng * @Date: 2018-12-20 19:51:02 * @Last Modified by: mikey.zhaopeng * @Last Modified time: 2018-12-20 19:51:02 */ #include "global.h" #include "Encode.h" #define ENCODEPERIOD 65536 typedef struct { unsigned short encode1_use; unsigned short encode2_use; float BMGearRatio_ch1; float BMGearRatio_ch2; long cRealPosi_ch1; long cRealPosi_ch2; } cEncodeAxis_t; static cEncodeAxis_t cEncodeAxis; void EncoderInit(void) { if (cEncodeAxis.encode1_use)//编码器1 { RCC->APB2ENR |= 0x10 ; GPIO_Set(GPIOA, PIN15, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE); GPIO_Set(GPIOB, PIN13, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE); // AFIO->MAPR |=3<<8;//用TIME2 完全映射 RCC->APB1ENR |=1<<0;//开启TIME3定时器时钟 Sys_NVIC_Init(1, 1, TIM2_IRQn, 1); TIM2->CR1 = 0; TIM2->CR1 |= (0 << 8) | (0 << 7) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 2) | (0 << 1); // 禁止自动重载 TIM2->CR2 = 0; TIM2->PSC = 0; //72 TIM2->ARR = ENCODEPERIOD - 1; TIM2->CCER = 0; TIM2->CCMR1 = 0; TIM2->SMCR = 0; TIM2->DIER = 0; TIM2->DIER |= 1; // 允许更新中断 TIM2->CNT = 0; TIM2->SMCR |=(3 << 0); // 编码器模弿1 TIM2->CCMR1 |= (3 << 12) | (0 << 10) | (1 << 8); TIM2->CCMR1 |= (3 << 4) | (0 << 2) | (1 << 0); //CH1 CH2 输入配置 ,一分频,滤波设罿 TIM2->CCER |= (0 << 5) | (0 << 1); //CH1 CH2 输入捕获 上升沿有敿 TIM2->CCER |= (1 << 4) | (1 << 0); // 弿启输入捕莿 TIM2->CR1 |= 1 << 0; TIM2->SR = 0; } if (cEncodeAxis.encode2_use)//编码器2 { RCC->APB2ENR |= 0x10 ; GPIO_Set(GPIOC, PIN6, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE); GPIO_Set(GPIOC, PIN7, GPIO_MODE_IN_FLOATING, GPIO_SPEED_50M, GPIO_PUPD_NONE); // AFIO->MAPR |=3<<10;//用TIME3 完全映射 RCC->APB1ENR |=1<<1;//开启TIME3定时器时钟 Sys_NVIC_Init(1, 1, TIM3_IRQn, 1); TIM3->CR1 = 0; TIM3->CR1 |= (0 << 8) | (0 << 7) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 2) | (0 << 1); // 禁止自动重载 TIM3->CR2 = 0; TIM3->PSC = 0; //72 TIM3->ARR = ENCODEPERIOD - 1; TIM3->CCER = 0; TIM3->CCMR1 = 0; TIM3->SMCR = 0; TIM3->DIER = 0; TIM3->DIER |= 1; // 允许更新中断 TIM3->CNT = 0; TIM3->SMCR |=(3 << 0); // 编码器模弿1 TIM3->CCMR1 |= (3 << 12) | (0 << 10) | (1 << 8); TIM3->CCMR1 |= (3 << 4) | (0 << 2) | (1 << 0); //CH1 CH2 输入配置 ,一分频,滤波设罿 TIM3->CCER |= (0 << 5) | (0 << 1); //CH1 CH2 输入捕获 上升沿有敿 TIM3->CCER |= (1 << 4) | (1 << 0); // 弿启输入捕莿 TIM3->CR1 |= 1 << 0; TIM3->SR = 0; } } //定时器检测高速输入接口信号 void TIM2_IRQHandler(void) { if (TIM2->SR & TIM_SR_UIF) { if ((TIM2->CR1 & TIM_CR1_DIR)) { cEncodeAxis.cRealPosi_ch1--; } else if ((TIM2->CR1 & TIM_CR1_DIR)==0) { cEncodeAxis.cRealPosi_ch1++; } TIM2->SR &= ~TIM_SR_UIF; } } //定时器检测高速输入接口信号 void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { if ((TIM3->CR1 & TIM_CR1_DIR)) { cEncodeAxis.cRealPosi_ch2--; } else if ((TIM3->CR1 & TIM_CR1_DIR)==0) { cEncodeAxis.cRealPosi_ch2++; } TIM3->SR &= ~TIM_SR_UIF; } } long GetEncodeNum(int ch) { long encode_num; switch(ch) { case ENCODE_X20X21: encode_num = (int)TIM2->CNT; encode_num += ENCODEPERIOD * cEncodeAxis.cRealPosi_ch1; return encode_num; break; case ENCODE_X22X23: encode_num = (int)TIM3->CNT; encode_num += ENCODEPERIOD * cEncodeAxis.cRealPosi_ch1; return encode_num; break; } return 0; } long GetEncodePos(int ch) { float pulse_buff; switch(ch) { case ENCODE_X20X21: if(cEncodeAxis.BMGearRatio_ch1==0)cEncodeAxis.BMGearRatio_ch1=1; pulse_buff=(float)GetEncodeNum(ENCODE_X20X21); return (long)(pulse_buff/cEncodeAxis.BMGearRatio_ch1); break; case ENCODE_X22X23: if(cEncodeAxis.BMGearRatio_ch2==0)cEncodeAxis.BMGearRatio_ch2=1; pulse_buff=(float)GetEncodeNum(ENCODE_X22X23); return (long)(pulse_buff/cEncodeAxis.BMGearRatio_ch2); break; } return (0); } void SetEncodePos(int ch,long pos) { switch(ch) { case ENCODE_X20X21: cEncodeAxis.cRealPosi_ch1=(long)((pos*cEncodeAxis.BMGearRatio_ch1)/ENCODEPERIOD); TIM2->CNT=(int)(pos*cEncodeAxis.BMGearRatio_ch1)%ENCODEPERIOD; break; case ENCODE_X22X23: cEncodeAxis.cRealPosi_ch2=(long)((pos*cEncodeAxis.BMGearRatio_ch2)/ENCODEPERIOD); TIM3->CNT=(int)(pos*cEncodeAxis.BMGearRatio_ch2)%ENCODEPERIOD; break; } } //设置编码器的比例 void SetEncodeGearRatio(int ch,float gearRatio) { switch(ch) { case ENCODE_X20X21: if(gearRatio==0)gearRatio=1; cEncodeAxis.BMGearRatio_ch1=gearRatio; break; case ENCODE_X22X23: if(gearRatio==0)gearRatio=1; cEncodeAxis.BMGearRatio_ch2=gearRatio; break; } } //编码器应用设置 void SetEncode_enable(int ch) { switch(ch) { case ENCODE_X20X21: cEncodeAxis.encode1_use=1; break; case ENCODE_X22X23: cEncodeAxis.encode2_use=1; break; } }