欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

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

QQ登錄

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

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

PID自動(dòng)控速

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:235301 發(fā)表于 2017-9-24 16:41 | 只看該作者 回帖獎(jiǎng)勵(lì) |正序?yàn)g覽 |閱讀模式
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define THC0 0xf8
#define TLC0 0xcc   //2ms
unsigned char code Duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共陰極數(shù)碼管,0-9段碼表
unsigned char Data_Buffer[8]={0,0,0,0,0,0,0,0};
unsigned char Data[4]={0,0,0,0};
unsigned char Arry[4]={0,0,0,0};
bit flag1=0;
bit flag0=0;
uchar i=0;
sbit AddSpeed=P1^1;
sbit SubSpeed=P1^2;
sbit PWM_FC=P1^0;
int e=0,e1=0,e2=0;                        //pid 偏差
float uk=0,uk1=0.0,duk=0.0;        //pid輸出值
float Kp=5,Ki=1.5,Kd=0.9;        //pid控制系數(shù)       
//float Kp=10;
int out=0;
uint SpeedSet=1000;
uint cnt=0;
uint Inpluse=0,num=0;                //脈沖計(jì)數(shù)
uint PWMTime=0;                                //脈沖寬度
unsigned char arry[];
void SendString(uint ch);
void PIDControl();
void SystemInit();
void delay(uchar x);
void PWMOUT();
void SetSpeed();
void SegRefre();
/**************主函數(shù)************/
void main()
{
        SystemInit();//系統(tǒng)初始化
        while(1)
        {
                SetSpeed();//設(shè)置速度
                SegRefre();//更新數(shù)碼管顯示
                PWMOUT();  //PWM輸出
                if(flag0==1)
                {
                        flag0=0;
                        ES=0;//關(guān)串口中斷,避免TI引起串口中斷
                        TI=1;//printf前TI置1
                        printf("%f",(float)(num>>8));//脈沖計(jì)數(shù)
                        printf("%f",(float)num);         //脈沖計(jì)數(shù)
                        while(!TI);
                        TI=0;           //TI軟件清除
                        ES=1;           //允許串口中斷
                }
        }
}

//PID偏差控制計(jì)算
void PIDControl()        //pid偏差計(jì)算
{
        e=SpeedSet-num;//設(shè)置速度-實(shí)際速度,兩者的差值
        //對(duì)應(yīng)于增量式PID的公式Δuk=uk-u(k-1)
//        duk=(Kp*(e-e1))/100;//只調(diào)節(jié)P
        duk=(Kp*(e-e1)+Ki*e)/100;//只調(diào)節(jié)PI
//        duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2))/100;//調(diào)節(jié)PID
        uk=uk1+duk;//uk=u(k-1)+Δuk
        out=(int)uk;//取整后輸出
        if(out>250)        //設(shè)置最大限制
                out=250;
        else if(out<0)//設(shè)置最小限制
                out=0;
        uk1=uk;                  //為下一次增量做準(zhǔn)備
        e2=e1;
        e1=e;
        PWMTime=out;  //out對(duì)應(yīng)于PWM高電平的時(shí)間
}

//較短的延時(shí)。注意delay的值不要超過(guò)255
void delay(uchar x)
{
        uchar i,j;
        for(i=x;i>0;i--)
                for(j=50;j>0;j--);//接近500us
}

//PWM輸出
void PWMOUT()
{
        if(cnt<PWMTime)//若小于PWM的設(shè)定時(shí)間,則輸出高電平
                PWM_FC=1;
        else                   //否則輸出低電平
                PWM_FC=0;
        if(cnt>250)    //超過(guò)限制清零
                cnt=0;
}

//系統(tǒng)初始化
void SystemInit()
{
        TMOD=0X21;    //T1用于串口的波特率發(fā)生器 T0用于定時(shí)
        TH0=THC0;          //2ms定時(shí),晶振頻率是11.0592MHz,事先算好裝入THC0中
        TL0=TLC0;          //2ms定時(shí),晶振頻率是11.0592MHz,實(shí)現(xiàn)算好裝入TLCO中
        ET0=1;                  //允許定時(shí)器0中斷
        TR0=1;                  //啟動(dòng)定時(shí)器0
        EX0=1;                  //允許外部中斷
        IT0=1;                  //中斷方式設(shè)置為下降沿
        //用于串口調(diào)試時(shí)用
        PCON=0x00;         //SMOD不加倍
        SCON=0x50;         //串口工作方式1,允許接收
        TH1=0xfd;         //波特率9600
        TL1=0xfd;         //波特率9600
        TR1=1;                 //啟動(dòng)定時(shí)器1
        ES=1;                 //開(kāi)串口中斷
        EA=1;                 //開(kāi)總中斷
        e =0;                 //PID的差值初值均為0
        e1=0;                 
        e2=0;
}

//設(shè)置轉(zhuǎn)速
void SetSpeed()
{
        if(AddSpeed==0)//按鍵
        {
                delay(200);//消抖
                if(AddSpeed==0)//再次判斷按鍵
                {
                        SpeedSet+=100;//速度增加
                        if(SpeedSet>9999)//超限
                                SpeedSet=9999;//設(shè)置為最大9999
                }
        }
        if(SubSpeed==0)//按鍵
        {
                delay(200);//消抖
                if(SubSpeed==0)//按鍵
                {
                        SpeedSet-=100;//速度減
                        if(SpeedSet<0)//低于速度的最小值
                                SpeedSet=0;//速度置零
                }
        }
}

//數(shù)碼管顯示更新
void SegRefre()                  //顯示刷新
{
        Data_Buffer[0]=SpeedSet/1000;
        Data_Buffer[1]=SpeedSet%1000/100;
        Data_Buffer[2]=SpeedSet%100/10;
        Data_Buffer[3]=SpeedSet%10;
        Data_Buffer[4]=num/1000;
        Data_Buffer[5]=num%1000/100;
        Data_Buffer[6]=num%100/10;
        Data_Buffer[7]=num%10;
}

//外部中斷,統(tǒng)計(jì)脈沖數(shù)目,實(shí)際上是統(tǒng)計(jì)電機(jī)的轉(zhuǎn)速
//在實(shí)際中,電機(jī)沒(méi)有一根線引出來(lái)可以表示他的轉(zhuǎn)速,只能通過(guò)傳感器如霍爾傳感器的方式測(cè)量轉(zhuǎn)速
//脈沖一次下降沿對(duì)應(yīng)于一次自增
void int0() interrupt 0
{
        Inpluse++;
}

//定時(shí)器T0操作
void t0() interrupt 1
{
        static unsigned char Bit=0;//靜態(tài)變量,退出程序值保留
        static unsigned int time=0;
        static unsigned int aa=0;
        TH0=THC0;//重新賦初值
        TL0=TLC0;
        aa++;
        if(aa==50)//每100ms
        {
                aa=0;
                flag0=1;
        }
        cnt++;        //pid 周期
        Bit++;
        time++;  //轉(zhuǎn)速測(cè)量周期
        if(Bit>8) Bit=0;//數(shù)碼管總共只有8位,超過(guò)8位則在程序上進(jìn)行清零
        //數(shù)碼管顯示部分
        P0=0xff;
        P2=Duan[Data_Buffer[Bit]];
        switch(Bit)
        {
                case 0:P0=0X7F;break;
                case 1:P0=0XBF;break;
                case 2:P0=0XDF;break;
                case 3:P0=0XEF;break;
                case 4:P0=0XF7;break;
                case 5:P0=0XFB;break;
                case 6:P0=0XFD;break;
                case 7:P0=0XFE;break;
        }
        //數(shù)碼管顯示部分
        if(time>500)//每1s處理一次脈沖
        {
                time=0;
                num=Inpluse*15;//實(shí)際轉(zhuǎn)速,*15是由電機(jī)決定的,電機(jī)的一個(gè)脈沖對(duì)應(yīng)著電機(jī)轉(zhuǎn)過(guò)了15轉(zhuǎn)
                Inpluse=0;           //清零,為下一次計(jì)數(shù)做準(zhǔn)備
                PIDControl();  //調(diào)用PID控制程序
        }
}

//串口中斷,用于對(duì)串口的數(shù)據(jù)進(jìn)行處理
void u_int(void) interrupt 4
{
        ES=0;//關(guān)串口中斷,避免在數(shù)據(jù)處理的過(guò)程中造成影響
        if(RI)//若有RI==1,由RI產(chǎn)生中斷
        {
                RI=0;//RI標(biāo)志位必須通過(guò)軟件進(jìn)行清零
                arry[i]=SBUF;//將字符賦到arry中
                i++;                 //下一個(gè)數(shù)
                if(i>3)                 //接收完了指令,進(jìn)行數(shù)據(jù)處理,一共有arry[0],arry[1],arry[2],arry[3]四個(gè)數(shù)據(jù)
                {
                        flag1=1;//將標(biāo)志置1
                        i=0;        //i清零,重新計(jì)數(shù)
                }
                if(flag1)        //若flag1==1
                {
                        flag1=0;//flag1清零
                        SpeedSet=(arry[0]-'0')+(arry[1]-'0')*10+(arry[2]-'0')*100+(arry[3]-'0')*1000;//獲得的速度值
                        //由于串口發(fā)送的是字符,所以要減去'0'
                }
        }
        else//對(duì)應(yīng)的由TI產(chǎn)生中斷
                TI=0;//TI由軟件進(jìn)行清零       
        ES=1;//處理完后再開(kāi)中斷
}


PID自動(dòng)控速.zip

53.95 KB, 下載次數(shù): 76, 下載積分: 黑幣 -5

PID自動(dòng)控速

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

使用道具 舉報(bào)

6#
無(wú)效樓層,該帖已經(jīng)被刪除
5#
ID:1014193 發(fā)表于 2022-8-4 16:24 | 只看該作者
請(qǐng)問(wèn)這里1000的轉(zhuǎn)速是每秒還是每分?
回復(fù)

使用道具 舉報(bào)

地板
ID:505055 發(fā)表于 2019-7-30 10:52 | 只看該作者
這是穩(wěn)定占空比吧???考慮外界阻力的時(shí)候不能穩(wěn)定速度
回復(fù)

使用道具 舉報(bào)

板凳
ID:237723 發(fā)表于 2017-10-7 22:47 | 只看該作者
學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:89286 發(fā)表于 2017-9-25 09:03 | 只看該作者
thanks for sharing
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表