|
150黑幣
定時器2初始化,做編碼器讀速度用
- void AX_ENCODER_AB_Init(uint16_t cycle)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_ICInitTypeDef TIM_ICInitStructure;
- //GPIO功能時鐘使能
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
- GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
- //配置IO口為復用功能-定時器通道
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //復用功能
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度100MHz
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- //TIM時鐘使能
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
- //Timer configuration in Encoder mode
- TIM_DeInit(TIM2);
- TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
- TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling
- TIM_TimeBaseStructure.TIM_Period = cycle;
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
- TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
- TIM_ICStructInit(&TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_ICFilter = 0;
- TIM_ICInit(TIM2, &TIM_ICInitStructure);
- //Reset counter
- TIM2->CNT = 0;
- TIM_Cmd(TIM2, ENABLE);
- }
- /**
- * @簡 述 編碼器AB獲取計數器數值
- * @參 數 無
- * @返回值 計數器當前值
- */
- uint16_t AX_ENCODER_AB_GetCounter(void)
- {
- int16_t temp;
- temp=TIM_GetCounter(TIM2);
- printf("CNT的值為%d\r\n",temp);
- <font color="#00ffff" style="background-color: red;"> return (TIM_GetCounter(TIM2)); </font>
- }
- /**
- * @簡 述 編碼器AB設置計數器數值
- * @參 數 count 計數器數值
- * @返回值 無
- */
- void AX_ENCODER_AB_SetCounter(uint16_t count)
- {
- TIM2->CNT = count;
- }
復制代碼
PID讀取部分,使用了操作系統的高優先級任務
- void PID_task(void*pvParameters)
- {
- printf("進行PID計算\r\n");
- while(1)
- {
- printf("開始進行PID計算\r\n");
- //計算編碼器變化值,即獲取小車實際速度
- ax_encoder_delta[0] = <font color="#00ffff">(<span style="background-color: red;">AX_ENCODER_AB_GetCounter()</span>-</font>ENCODER_MID_VALUE);
- ax_encoder_delta[1] = (AX_ENCODER_CD_GetCounter()-ENCODER_MID_VALUE);
- ax_encoder_delta[2] = (AX_ENCODER_EF_GetCounter()-ENCODER_MID_VALUE);
- ax_encoder_delta[3] = -(AX_ENCODER_GH_GetCounter()-ENCODER_MID_VALUE);
- //設置編碼器初始中間值
- AX_ENCODER_AB_SetCounter(ENCODER_MID_VALUE);
- AX_ENCODER_CD_SetCounter(ENCODER_MID_VALUE);
- AX_ENCODER_EF_SetCounter(ENCODER_MID_VALUE);
- AX_ENCODER_GH_SetCounter(ENCODER_MID_VALUE);
- //運動解析,獲取目標轉速
- printf("A電機轉速 %d \r\n",ax_encoder_delta[0]);
- printf("B電機轉速 %d \r\n",ax_encoder_delta[1]);
- printf("C電機轉速 %d \r\n",ax_encoder_delta[2]);
- printf("D電機轉速 %d \r\n",ax_encoder_delta[3]);
- AX_MOVE_Kinematics(ax_vx,ax_vy,ax_vz);
- printf("A目標轉速 %d \r\n",ax_encoder_delta_target[0]);
- printf("B目標轉速 %d \r\n",ax_encoder_delta_target[1]);
- printf("C目標轉速 %d \r\n",ax_encoder_delta_target[2]);
- printf("D目標轉速 %d \r\n",ax_encoder_delta_target[3]);
- //PID控制
- ax_motor_pwm[0] = AX_MID_MotorVelocityPidCtl_A(ax_encoder_delta_target[0], ax_encoder_delta[0]);
- ax_motor_pwm[1] = AX_MID_MotorVelocityPidCtl_B(ax_encoder_delta_target[1], ax_encoder_delta[1]);
- ax_motor_pwm[2] = AX_MID_MotorVelocityPidCtl_C(ax_encoder_delta_target[2], ax_encoder_delta[2]);
- ax_motor_pwm[3] = AX_MID_MotorVelocityPidCtl_D(ax_encoder_delta_target[3], ax_encoder_delta[3]);
- printf("A電機輸出 %d \r\n",ax_motor_pwm[0]);
- printf("B電機輸出 %d \r\n",ax_motor_pwm[1]);
- printf("C電機輸出 %d \r\n",ax_motor_pwm[2]);
- printf("D電機輸出 %d \r\n",ax_motor_pwm[3]);
- printf("PID計算完畢\r\n");
- AX_MOTOR_A_SetSpeed(ax_motor_pwm[0]);
- AX_MOTOR_B_SetSpeed(ax_motor_pwm[1]);
- AX_MOTOR_C_SetSpeed(ax_motor_pwm[2]);
- AX_MOTOR_D_SetSpeed(ax_motor_pwm[3]);
- vTaskDelay(300);
-
- }
- }
復制代碼
A電機得到的速度反饋只能是1,0,-1,然后又去看TIM2,CNT的值,發現是30000,30000是賦的初值。
BC電機被我屏蔽了
通過示波器,觀察D,和A,的編碼器AB相,轉動輪子,波形一致。也換過電機編碼器測試,
綜上,問題直指TIM2CNT 的讀取部分,
附上全部代碼,只求解決問題。
|
|