久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 11046|回復(fù): 12
打印 上一主題 下一主題
收起左側(cè)

使用增量式PID對(duì)直流電機(jī)進(jìn)行簡(jiǎn)單的控制

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本帖最后由 kaixuan520 于 2019-7-12 10:04 編輯

位置式PID控制
位置式PID控制是指在積分環(huán)節(jié),對(duì)從0時(shí)刻到當(dāng)前時(shí)刻的所有偏差進(jìn)行積分,是非遞推式的全局積分。
增量式PID控制
和位置式PID控制不同,增量式PID控制將當(dāng)前時(shí)刻的控制量和上一時(shí)刻的控制量做差,以差值為新的控制量,是一種遞推式的算法。
增量式PID控制的主要優(yōu)點(diǎn)為:
①算式中不需要累加。控制增量Δu(k)的確定僅與最近3次的采樣值有關(guān),容易通過(guò)加權(quán)處理獲得比較好的控制效果;
②計(jì)算機(jī)每次只輸出控制增量,即對(duì)應(yīng)執(zhí)行機(jī)構(gòu)位置的變化量,故機(jī)器發(fā)生故障時(shí)影響范圍小、不會(huì)嚴(yán)重影響生產(chǎn)過(guò)程;
③手動(dòng)—自動(dòng)切換時(shí)沖擊小。當(dāng)控制從手動(dòng)向自動(dòng)切換時(shí),可以作到無(wú)擾動(dòng)切換[2]  。
由于增量式需要對(duì)控制量進(jìn)行記憶,所以對(duì)于不帶記憶裝置的系統(tǒng),只能使用位置式PID控制方式進(jìn)行控制。


公式:




上代碼:
使用定時(shí)器3作為PWM輸出,頻率為20KHz,調(diào)節(jié)占空比0-100%來(lái)改變電機(jī)速度
    //TIM3初始化和輸出GPIO初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
    GPIO_InitTypeDef GPIO_InitTypeStruct;
    GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitTypeStruct);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruct;
    TIM_TimeBaseInitTypeStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitTypeStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitTypeStruct.TIM_Period = 99;
    TIM_TimeBaseInitTypeStruct.TIM_Prescaler = 35;                //20KHz
    TIM_TimeBaseInitTypeStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeStruct);

    TIM_OCInitTypeDef TIM_OCInitTypeStruct;
    TIM_OCInitTypeStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitTypeStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitTypeStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitTypeStruct.TIM_Pulse = DutyCycle;                                                                //占空比
    TIM_OC1Init(TIM3,&TIM_OCInitTypeStruct);

    TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);

    TIM_Cmd(TIM3,ENABLE);





   //使用定時(shí)器1作輸入捕獲,PWM輸入模式,
   //GPIO和定時(shí)器1初始化
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    GPIO_InitTypeDef GPIO_InitTypeStruct;
    GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_8;
    GPIO_Init(GPIOA,&GPIO_InitTypeStruct);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruct;
    TIM_TimeBaseInitTypeStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitTypeStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitTypeStruct.TIM_Period = TIM1_ARR;
    TIM_TimeBaseInitTypeStruct.TIM_Prescaler = TIM1_PSC;
    TIM_TimeBaseInitTypeStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitTypeStruct);

    TIM_ICInitTypeDef TIM_ICInitTypeStruct;
    TIM_ICInitTypeStruct.TIM_Channel = TIM_Channel_1;
    TIM_ICInitTypeStruct.TIM_ICFilter = 0x0f;//對(duì)輸入的脈沖進(jìn)行濾波
    TIM_ICInitTypeStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitTypeStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitTypeStruct.TIM_ICSelection =  TIM_ICSelection_DirectTI;
    TIM_PWMIConfig(TIM1,&TIM_ICInitTypeStruct);

    TIM_SelectInputTrigger(TIM1,TIM_TS_TI1FP1);                //選擇輸入觸發(fā)方式
    TIM_SelectSlaveMode(TIM1,TIM_SlaveMode_Reset);        //設(shè)置從機(jī)模式
    TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);//

    NVIC_InitTypeDef NVIC_InitTypeStruct;
    NVIC_InitTypeStruct.NVIC_IRQChannel = TIM1_CC_IRQn;//輸入捕獲中斷線
    NVIC_InitTypeStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitTypeStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitTypeStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitTypeStruct);

    TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);//使能通道1捕獲中斷

    TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);

    TIM_Cmd(TIM1,ENABLE);

//通過(guò)輸入捕獲中斷函數(shù)來(lái)取得電機(jī)編碼器的頻率,占空比,周期,從而計(jì)算出速度
uint16_t IC1V;
uint16_t IC2V;
void TIM1_CC_IRQHandler(void)
{
    TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);

    IC1V = TIM_GetCapture1(TIM1);//周期us
    IC2V = TIM_GetCapture2(TIM1);//占空比
    if(IC1V!=0)
    {
        IC1V+=1;
        IC2V+=1;
        float d1 = ((float)IC1V/1000);
        float d2 = ((float)IC2V/1000);
        float f = (float)IC1V/1000000;
        DutyCycle = 100*d2/d1;//占空比
        Frequency = 1/f;        //計(jì)算出編碼器的頻率
        Period = (float)IC1V/1000;//周期ms
    } else {
        Frequency = 0;
        DutyCycle = 0;
    }
}


//再使用一個(gè)100ms的定時(shí)器來(lái)每秒10次的數(shù)據(jù)采集和控制,定時(shí)器初始化就不貼了,具體看附件

float M_PWM = 0;
float M_Speed = 0;
uint8_t xi=0;
void TIM2_IRQHandler(void)//100ms定時(shí)器中斷
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
    {
        //if(Frequency!=0) {
        GPIOB->ODR ^= GPIO_Pin_5;
        M_Speed = Frequency;
        M_Speed /= 20;
                Frequency = 0;

        int value = Compute_PID((uint16_t)(M_Speed*100));//進(jìn)行PID計(jì)算,返回PWM占空比
                int y = value;
        float n = value/100;
        M_PWM += n;

        if(xi==0) {//沒(méi)500ms向串口發(fā)送一次數(shù)據(jù)
                        printf("當(dāng)前轉(zhuǎn)速:%0.2f\r\n",M_Speed);
                        printf("目標(biāo)轉(zhuǎn)速:%d\r\n",(uint16_t)PID_Struct->SetPoint/100);
            printf("P:%0.4f,I:%0.4f,D:%0.4f,LE:%d,PE:%d,VO:%d,MO:%d\r\n",//PID相關(guān)參數(shù)信息,
                        PID_Struct->Proportion,PID_Struct->Integral,PID_Struct->Derivaltive,
                        PID_Struct->LastError,PID_Struct->PreError,y,(int)M_PWM);  
            printf("Period:%0.4fms, Frequency:%0.4fHz, DutyCycle:%0.4f%%\r\n",Period,Frequency,DutyCycle);//PWM輸出的周期,頻率,占空比
            printf("\r\n\r\n");
        }
        xi++;
        xi%= 5;
        if(M_PWM>100)M_PWM = 100;                //防止越過(guò)最大和最小控制量
        if(M_PWM<0)M_PWM = 0;
        TIM_SetCompare1(TIM3,(uint16_t)M_PWM);
        //}
        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }
}


PID算法結(jié)構(gòu)體
typedef struct {
    int SetPoint;                        //設(shè)定值
    long SumError;                        //累計(jì)誤差

    double Proportion;                //比例
    double Integral;                //積分
    double Derivaltive;                //微分

    int LastError;                        //上次誤差
    int PreError;                        //上上次誤差
} PID_S;

static PID_S PID_Struct_;
static PID_S *PID_Struct = &PID_Struct_;


//main:
/PID參數(shù)整定方法請(qǐng)轉(zhuǎn)各大論壇查找教程,這里不詳細(xì)介紹
PID_Struct->Proportion = 1.92;
    PID_Struct->Integral = 1.65;
    PID_Struct->Derivaltive = 0.116;
    PID_Struct->SetPoint = 80*100;


//PID計(jì)算
int Compute_PID(uint16_t nowValue)
{
    register int iError,Ouk;
    iError = PID_Struct->SetPoint - nowValue;//當(dāng)前誤差
//    PID_Struct ->SumError += iError;

    Ouk = (PID_Struct->Proportion * iError)
          - (PID_Struct->Integral * PID_Struct->LastError)
          + (PID_Struct->Derivaltive *PID_Struct->PreError);

    PID_Struct->PreError = PID_Struct->LastError;

    PID_Struct->LastError = iError;
    return Ouk;
}


電路方面制作
電機(jī)使用12V掃地機(jī)器人的電機(jī),編碼器使用每圈20次脈沖的光電編碼器
使用LM393電壓比較器對(duì)光電編碼器輸出進(jìn)行穩(wěn)定和優(yōu)化
電路圖:







編碼器輸出波形圖:


波形還是比較完美的

電機(jī)驅(qū)動(dòng)使用L298N,連接圖:


串口打印數(shù)據(jù):

視頻演示PWM輸出效果:https://share.weiyun.com/5idpKLF



增大阻力和調(diào)節(jié)速度都能快速回到設(shè)定值以下為附件信息
STM32源碼: PID_直流調(diào)速.rar (349.35 KB, 下載次數(shù): 157)

PID學(xué)習(xí)資料: PID算法.zip (1.81 MB, 下載次數(shù): 113)






評(píng)分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏8 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:492516 發(fā)表于 2019-7-14 20:52 | 只看該作者
VO:%d,MO:%d這兩個(gè)參數(shù)表示pid的啥
回復(fù)

使用道具 舉報(bào)

板凳
ID:492516 發(fā)表于 2019-7-14 20:52 | 只看該作者
求大佬解釋
回復(fù)

使用道具 舉報(bào)

地板
ID:300212 發(fā)表于 2019-7-15 15:05 | 只看該作者
小林大哥哥 發(fā)表于 2019-7-14 20:52
VO:%d,MO:%d這兩個(gè)參數(shù)表示pid的啥

VO是PID計(jì)算出的結(jié)果,MO是當(dāng)前輸出PWM的占空比
回復(fù)

使用道具 舉報(bào)

5#
ID:380985 發(fā)表于 2019-7-16 17:17 來(lái)自手機(jī) | 只看該作者
很好的學(xué)習(xí)資料,在學(xué)習(xí)平衡小車(chē),研究下
回復(fù)

使用道具 舉報(bào)

6#
ID:380985 發(fā)表于 2019-7-17 17:43 來(lái)自手機(jī) | 只看該作者
電路圖提供一下唄
回復(fù)

使用道具 舉報(bào)

7#
ID:300212 發(fā)表于 2019-7-20 19:41 | 只看該作者

沒(méi)有電路圖,電路自己設(shè)計(jì)的只有編碼器那塊的,電路圖在貼子中,別的連接都是杜邦線直接連的
回復(fù)

使用道具 舉報(bào)

8#
ID:573864 發(fā)表于 2019-8-1 10:03 | 只看該作者
沒(méi)有PID.c文件
回復(fù)

使用道具 舉報(bào)

9#
ID:300212 發(fā)表于 2019-9-20 13:24 來(lái)自手機(jī) | 只看該作者
13958988573 發(fā)表于 2019-8-1 10:03
沒(méi)有PID.c文件

沒(méi)用到,代碼都在main.c里
回復(fù)

使用道具 舉報(bào)

10#
ID:553615 發(fā)表于 2020-3-8 17:40 | 只看該作者
請(qǐng)問(wèn)大佬,程序里用于捕獲的定時(shí)器只使能了通道1,為什么還能用通道2采集占空比呢?
回復(fù)

使用道具 舉報(bào)

11#
ID:693716 發(fā)表于 2020-3-16 11:24 | 只看該作者
學(xué)習(xí)了,謝謝大佬分享
回復(fù)

使用道具 舉報(bào)

12#
ID:717071 發(fā)表于 2020-5-4 14:36 | 只看該作者
資源不錯(cuò)
回復(fù)

使用道具 舉報(bào)

13#
ID:717071 發(fā)表于 2020-5-4 19:36 | 只看該作者
樓主,輸入捕獲中斷函數(shù)里面的ICV1和ICV2為什么分別是周期和占空比啊
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一级二级三级 | 日韩二区| 久久蜜桃资源一区二区老牛 | 中文字幕在线一区二区三区 | 一区欧美 | 一区二区三区视频在线观看 | 国产一级免费视频 | 欧美成人精品一区二区男人看 | 欧美在线成人影院 | 国产伦精品一区二区三区照片91 | 亚洲成人精品 | 国产精品美女久久久久久免费 | 久久久久久九九九九 | 久综合 | 99久久久国产精品 | 免费看国产片在线观看 | 玖玖视频国产 | 欧美一级在线视频 | 天天综合网天天综合 | 久久亚洲一区 | 亚洲精品久久久久久久久久久久久 | 欧美日韩视频在线播放 | 欧美一区二区三区四区五区无卡码 | 亚洲h视频 | 国产一级片免费看 | 精品久久香蕉国产线看观看亚洲 | 欧美一区二区三区免费在线观看 | 久久精品在线播放 | 国产精品九九九 | 特级a欧美做爰片毛片 | 成年人在线视频 | 日韩中文字幕久久 | 午夜电影网址 | 成人精品一区二区三区中文字幕 | 中文字幕精品一区 | 国产成人99久久亚洲综合精品 | 国产成人精品视频 | www久久国产| 亚洲在线高清 | 日本在线播放一区二区 | 四虎最新地址 |