直流電機控制
1. 編碼器
1.1 簡介
- 用來測量機械旋轉或位移的傳感器,能夠測量機械部位在旋轉或直線運動時的位移位置或速度等資訊,并将其轉換成一系列電信号
- 根據檢測原理分為光電編碼器(最廣泛)、磁編碼器(霍爾元件,精度較低)和感應式編碼器(可靠性高,高端領域)
- 根據運動方式分為線性編碼器和旋轉編碼器
- 根據編碼類型分為增量式、絕對式、混合式
1.2 原理
- 分辨率:編碼器能夠分辨的最小機關
- 精度:編碼器每個讀數與轉軸實際位置間的最大誤差,通常用角度、角分或角秒來表示
- 最大響應頻率:編碼器每秒輸出的脈沖數,機關是Hz
- 信号輸出形式:直接輸出/輸入協定
1.3 定時器的編碼器模式
1.3.1 程式邏輯
- 初始化定時器為編碼器模式
/**************************************************************************
函數功能:把TIM3初始化為編碼器接口模式
入口參數:無
傳回 值:無
**************************************************************************/
void Encoder_Init_TIM3(void)
{
__HAL_RCC_TIM3_CLK_ENABLE(); //使能定時器3
GPIOA_TIM3_Init(); //使能IO口
/* 把定時器初始化為編碼器模式 */
TIM3->PSC = 0x0; //預分頻器
TIM3->ARR = ENCODER_TIM_PERIOD-1; //設定計數器自動重裝值
TIM3->CCMR1 |= 1<<0; //輸入模式,IC1FP1映射到TI1上
TIM3->CCMR1 |= 1<<8; //輸入模式,IC2FP2映射到TI2上
TIM3->CCER |= 0<<1; //IC1不反向
TIM3->CCER |= 0<<5; //IC2不反向
TIM3->SMCR |= 3<<0; //SMS='011' 所有的輸入均在上升沿和下降沿有效
TIM3->CR1 |= 0x01; //CEN=1,使能定時器
}
//編碼器TIM2 IO初始化
void GPIOA_TIM2_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOA_CLK_ENABLE(); //開啟GPIOA時鐘
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1; //PA0、PA1
GPIO_Initure.Mode=GPIO_MODE_INPUT; //浮空輸入
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
- 讀取定時器中的脈沖數,通過讀取CNT的值
/**************************************************************************
函數功能:機關時間讀取編碼器計數
入口參數:定時器
傳回 值:速度值
**************************************************************************/
int Read_Encoder(u8 TIMX)
{
int Encoder_TIM;
switch(TIMX)
{
case 2: Encoder_TIM= (short)TIM2 -> CNT; TIM2 -> CNT=0;break;
case 3: Encoder_TIM= (short)TIM3 -> CNT; TIM3 -> CNT=0;break;
case 4: Encoder_TIM= (short)TIM4 -> CNT; TIM4 -> CNT=0;break;
default: Encoder_TIM=0;
}
return Encoder_TIM;
}
2. PID
2.1 簡介
P(比例)I(積分)D(微分)
通過編碼器的速度回報,可以實時知道小車的速度是否慢了,然後利用目标速度與實際速度的誤差代入算法,既可獲得目前占空比,達到控制速度的效果
PID控制其實對偏差的控制過程
- PID算法連續公式
- 離散的PID公式
- 位置式PID:每次輸出均與過去的狀态有關,直接控制執行機構
- 增量式PID:實時性,無擾動切換,有穩态誤差,溢出的影響大
2.2 原理
- 參數
- 比例項:增大比例系數可以加快系統的響應、增大比例系數有助于減小靜差
- 積分項:增大積分時間有利于減小超調,使系統穩定性增加,但是會增長消除靜差的時間
- 微分項:具有超前調節的作用,抑制振蕩
- 整定方法
- 試湊法:先比例,再積分,最後微分
- 臨界比例法:從大到小逐漸改變調節器的比例度,并且得到等幅度的震蕩過程就叫做臨界比例度
- 一般調節法:
- 輸出不振蕩 - 增大比例增益P
- 輸出不振蕩 - 減小積分時間常數Ti
- 輸出不振蕩 - 增大微分時間常數Td
- 采樣周期
- 采樣周期越短控制的效果越接近于連續,對于大多數算法縮短采樣周期可使控制回路性能改善
- 但采樣周期縮短時,頻繁的采樣必然會占用較多的計算工作時間,同時也會增加計算的負擔
- 而對有些變化緩慢的受控對象無需很高的采樣頻率既可滿意地進行跟蹤,過多的采樣反而沒有多少實際意義
2.3 程式邏輯
一般把PID放在一個周期執行,比如定時器或定時的中斷中,這裡以定時器為例
- 在定時器中斷中:讀取編碼器的值-PID計算-指派PWM輸出
//回調函數,定時器中斷服務函數調用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&TIM3_Handler))
{
Encoder=Read_Encoder(2); //===讀取編碼器的值,M法測速,輸出為每10ms的脈沖數
Moto1=Incremental_PI(Encoder,Target_velocity); //===速度PI控制器
Xianfu_Pwm(&Moto1); //===PWM限幅
Set_Pwm(Moto1); //===指派給PWM寄存器
printf("AIN1=%d\tAIN2=%d\tMoto1=%d\tEncoder=%d\r\n",AIN1,AIN2,Moto1,Encoder);
}
}
- 增量式PI控制器
/**************************************************************************
函數功能:增量PI控制器
入口參數:編碼器測量值,目标速度
傳回 值:電機PWM
根據增量式離散PID公式
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)+Kd[e(k)-2e(k-1)+e(k-2)]
e(k)代表本次偏差
e(k-1)代表上一次的偏差 以此類推
pwm代表增量輸出
在我們的速度控制閉環系統裡面,隻使用PI控制
pwm+=Kp[e(k)-e(k-1)]+Ki*e(k)
**************************************************************************/
int Incremental_PI(int Encoder,int Target)
{
float Kp=20,Ki=30; //原例程中Kp=20,Ki=30
static int Bias,Pwm,Last_bias;
//Bias=Encoder-Target; //計算偏差
Bias=Target-Encoder; //計算偏差
Pwm+=Kp*(Bias-Last_bias)+Ki*Bias; //增量式PI控制器
Last_bias=Bias; //儲存上一次偏差
return Pwm; //增量輸出
}
2.4 剖析PI控制器
- 中斷函數中
- 讀取編碼器的值:Encoder(由于定時器每10ms中斷一次,是以得到的值為每10ms的脈沖數)
- 調用速度PI控制器獲得電機PWM變量:Motol
- 進行PWM限幅
- 指派給PWM寄存器
- 讀取編碼器的值
- 初始化TIM為編碼器模式(需要兩個IO口)
- 讀取TIM->CNT的值
- 增量PI控制器
- 該函數中的Kp和Ki需要直接在函數中修改
- 該函數的形參為編碼器測量值:Encoder和目标速度:Target_velocity(目标速度的表示為每10msX個脈沖)
- 該函數的傳回值是一個int的資料
- 補充知識點:static(靜态局部變量的效果類似于局部變量)
- PWM限幅
- 由于PWM的滿幅是7200,不可以超過這個值
- 若Motol的絕對值超過7100,則将其修改為設定的最大值:7100