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

標題: 求助!關于控制電機螺旋槳帶動平衡桿繞軸轉動的編程問題 [打印本頁]

作者: 123go    時間: 2016-3-31 17:35
標題: 求助!關于控制電機螺旋槳帶動平衡桿繞軸轉動的編程問題
    要求平衡桿能在正負30°的范圍內平衡。現在我只能讓其在水平位置以下平衡,到了水平位置以上就不能平衡,會飛到上面去了。     求大神指導,不勝感激!
附上程序:
#include <reg52.h>
#include <intrins.h>
#include <math.h>
#define _Nop() _nop_()
#define nop() _nop_()
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
#define LCD_data P0
sbit LCD_RS=P2^3;
sbit LCD_RW=P2^4;
sbit LCD_EN=P2^5;
sbit LCD_PSB=P3^3;
unsigned int c,d,e,f,m,n,p;
uchar code dis1[]={"單軸螺旋槳懸浮系"};
uchar code dis2[]={"角度:"};
uchar code dis3[]={"調整時間:"};
uchar code dis4[]={"°"};
uchar code dis5[]={"秒"};

sbit lowspeed=P3^6;           //K3
sbit autospeed=P3^4;   //K1  !!!之前的K4與LCD12864端口沖突了!!!
sbit pmw=P3^5;
sbit ADC0832_CLK = P1^4;
sbit ADC0832_DIO = P1^5;
sbit ADC0832_CS = P2^0;
unsigned int chuzhi0=0xb9b0,chuzhi1=0xf830,time,time1;
unsigned char ADC_flag,balance=0x9f;
unsigned char kaiguan=1;
unsigned char jiaodu[20];
unsigned char jiaodu1,jiaodu2,jiaodu3;
unsigned int angle; /*實測角度值*/
float setjiaodu=0;
float Pro=0.01,
          I=0.0001,
          De=0,
          lasterror=0,
          pre_error=0,
          sumerror=0;


unsigned char ADC0832_Read(unsigned char ch){
        unsigned char i,ADC_buff=0,temp=0;
        ADC0832_CS = 1;
        ADC0832_DIO = 1;   
        ADC0832_CLK = 0;
        ADC0832_CS = 0;
        nop();
        ADC0832_CLK = 1;
        nop();
        ADC0832_CLK = 0;
        ADC0832_DIO = 1;  
        nop();
        ADC0832_CLK = 1;
        nop();
        ADC0832_CLK = 0;
        if(ch==0)
                ADC0832_DIO = 0;
        else
                ADC0832_DIO = 1;
        ADC0832_CLK = 1;
        nop();
        ADC0832_CLK = 0;
        nop();  
        ADC0832_DIO = 1;
        nop();
        ADC0832_CLK = 1;
        nop();
        for(i=0;i<8;i++){                 
                nop();
                ADC0832_CLK = 0;
                nop();
                nop();
                ADC_buff=ADC_buff<<1;
                if(ADC0832_DIO==1)
                        ADC_buff=ADC_buff+1;  
                ADC0832_CLK = 1;                        
                }
        for(i=0;i<8;i++){
                temp = temp>>1;
                if(ADC0832_DIO==1)
                        temp = temp | 0x80;
                ADC0832_CLK = 1;
                nop();
                ADC0832_CLK = 0;
                nop();
                }
        ADC0832_CS = 1;
        ADC0832_CLK = 1;
        if(temp == ADC_buff)
                ADC_flag = 1;
        else
                ADC_flag = 0;
        return ADC_buff;         
}
//1MS為單位的延時程序
void xianshi2();
unsigned int set_to_dat(float a)
{
    float b;
    if(a>0)
      {b=256/5*(2*sqrt(1-((3.1415*a/180)*(3.1415*a/180)))+2.5);}
    else
      {b=256/5*(2.5-2*sqrt(1-((3.1415*a/180)*(3.1415*a/180))));}
    return b;
}
unsigned int ADC0832da_to_Angle(unsigned char da)
{
        /*將輸入的數據轉換成角度值*/
        float Volage;
        float Angle;
        int zhuan;
        Volage =da*5.0/256;
        if(0.5*Volage-1.25>=0){
                Angle = (float)(asin(0.5*Volage-1.25))*180/3.1415;
            zhuan=(float)((asin(0.5*Volage-0.25*5)*180/3.1415)*100);
        }
        else{
                Angle = (float)(asin(1.25-0.5*Volage))*180/3.1415;
            zhuan=(float)((asin(1.25-0.5*Volage)*180/3.1415)*100);
                }
        return zhuan;        
}
void delay_1ms(uchar x)
{
    uchar j;
    while(x--){
        for(j=0;j<125;j++)
            {;}
        }   
}

void delay(unsigned int a);
///////////////////以下是LCD12864驅動程序//////////////////////////////

bit lcd_busy()                   //檢查LCD忙狀態
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P0&0x80);
    LCD_EN = 0;
    return(result);
}
void lcd_wcmd(uchar cmd)//寫指令數據到LCD
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P0 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}
void lcd_wdat(uchar dat) //寫顯示數據到LCD
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P0 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
}

void lcd_init()                         //LCD初始化設定
{
        delay(15);
    LCD_PSB = 1;         //并口方式
    delay(5);
    lcd_wcmd(0x34);      //擴充指令操作
    delay(5);
    lcd_wcmd(0x30);      //基本指令操作
    delay(5);
    lcd_wcmd(0x0C);      //顯示開,關光標
    delay(5);
    lcd_wcmd(0x01);      //清除LCD的顯示內容
    delay(5);
}

////////////////以上是LCD12864驅動程序////////////////////////////
void xianshi()
{        

  if(jiaodu2<128){
        lcd_wcmd(0X93);
    delay_1ms(15);
    lcd_wcmd(0X93);
    delay_1ms(15);
    lcd_wcmd(0X93);
        delay_1ms(15);
        lcd_wdat(0x2B);
        delay_1ms(5);                    
        }else{
        lcd_wcmd(0X93);
        delay_1ms(5);
        lcd_wdat(0x2D);
        delay_1ms(5);}  
    lcd_wcmd(0x94);
        lcd_wdat(c+0x30);
        delay_1ms(20);
    lcd_wdat(d+0x30);
        delay_1ms(20);
        lcd_wdat(0x2E);
        delay_1ms(5);
    lcd_wdat(e+0x30);
        delay_1ms(20);
        lcd_wdat(f+0x30);
        delay_1ms(20);                     
}
void xianshi2()
{
        lcd_wcmd(0X8D);
        lcd_wdat(m+0x30);
        delay_1ms(5);
    lcd_wdat(n+0x30);
        delay_1ms(5);
        lcd_wdat(0x2E);
        delay_1ms(5);
    lcd_wdat(p+0x30);
        delay_1ms(5);
}
void pid();
void main(){
    uchar i;
        lcd_init();                   /*LCD初始化*/
        lcd_wcmd(0X80);                                                 //設置顯示位置為第一行的第1個字符
           for(i=0;i<16;i++){lcd_wdat(dis1);}         //顯示字符
    lcd_wcmd(0X90);                          //設置顯示位置為第二行的第2個字符
    for(i=0;i<6;i++){lcd_wdat(dis2);}
        lcd_wcmd(0X88);                          //設置顯示位置為第三行的第3個字符
    for(i=0;i<10;i++){lcd_wdat(dis3);}
        lcd_wcmd(0X97);                          //設置顯示位置為第四行的第3個字符
    for(i=0;i<2;i++){lcd_wdat(dis4);}
        lcd_wcmd(0X8F);                          //設置顯示位置為第五行的第3個字符
    for(i=0;i<2;i++){lcd_wdat(dis5);}
        IT0=0;
        EX0=1;
        IT1=0;
        EX1=1;
        TMOD=0x11;
        TH0=chuzhi1>>8;
        TL0=chuzhi1;
        ET0=1;
        EA=1;
        TR0=1;
        while(1){
                if(lowspeed==0){                                   //初始化
                        delay(20);
                        if(lowspeed==0){
                                chuzhi0=0xb5c8;
                                chuzhi1=0xfc18;
                        }
                }
                if(autospeed==0){
                        delay(20);
                        if(autospeed==0){
                                kaiguan=1;
                                balance=0x90;
                                //balance=(char)set_to_dat(setjiaodu);
                                pid();
                        }
                }               
        }
}
void shezhi() interrupt 1{                           //調節占空比
        if(pmw==1){
                TH0=chuzhi0>>8;
                TL0=chuzhi0;
                pmw=0;
        }
        else{
                TH0=chuzhi1>>8;
                TL0=chuzhi1;
                pmw=1;
        }
        TF0=0;        
}
void shezhi1() interrupt 0{
        chuzhi0=0xb5c8;
        chuzhi1=0xfc18;
        kaiguan=0;
}
void shezhi2() interrupt 3{
        time++;
        TH1=0X3C;
        TL1=0XB0;
        TF1=0;
}
/*void shezhi3() interrupt 2{
        //balance=0x9c;
}        */
void delay(unsigned int a){
        unsigned b=50,c=130;
        for(;a>0;a--){
                for(;b>0;b--)
                        for(;c>0;c--);
        }
}
void pid2();
void pid(){
        unsigned char chazhi,chazhi1,chazhi2,button,change,j=3,i;
        while(kaiguan==1){
                for(i=0;i<20;i++){
                        jiaodu=ADC0832_Read(0);
                        delay(200);
                }
                jiaodu3=jiaodu[0];
                jiaodu1=(jiaodu[0]+jiaodu[1]+jiaodu[2]+jiaodu[3]+jiaodu[4]+jiaodu[5]+jiaodu[6]+jiaodu[7]+jiaodu[8]+jiaodu[9])/10;
                jiaodu2=(jiaodu[10]+jiaodu[11]+jiaodu[12]+jiaodu[13]+jiaodu[14]+jiaodu[15]+jiaodu[16]+jiaodu[17]+jiaodu[18]+jiaodu[19])/10;
               
        angle=ADC0832da_to_Angle(jiaodu2); //將采集值轉換為角度值
                chazhi=abs(jiaodu2-balance);
                chazhi1=abs(jiaodu1-balance);
                chazhi2=abs(jiaodu3-balance);
                change=chazhi/8+1;
                if((chazhi>=20)&&(button==0)){
                        button=1;
                        TH1=0x3c;
                        TL1=0xb0;
                        ET1=1;
                        TR1=1;
                }
                if((chazhi<=3)&&(button==1)&&(chazhi1<=3)&&(chazhi2<=3)){
                        button=0;
                        ET1=0;
                        TR1=0;
                        time1=(time*10)/20;
                  /*此處添加顯示平衡時間的子函數,平衡時間為已經設好的變量“time”*/
                        m=time1/100;
                     n=time1%100/10;
                      p=time1%10;
                        xianshi2();  
                //        time=0;           
                        pid2();
        
                }
                c=angle/1000;
                d=angle%1000/100;
                e=angle%1000%100/10;
                f=angle%10;
                j--;
                if(j==0){
                    xianshi();
                        j=3;
                }  /*此處添加顯示當前角度的子程序,角度值為已經設好的變量“jiaodu2”*/
        
                if(jiaodu2=jiaodu1){
                        if((jiaodu2>balance)&&(chuzhi0<0xb9b0)&&(chazhi>=2)){
                                chuzhi0=chuzhi0+change;                                                                         //改變占空比
                                chuzhi1=chuzhi1-change;
                        }
                        if((jiaodu2<balance)&&(chuzhi0>0xb5c8)&&(chazhi>=2)){
                                chuzhi0=chuzhi0-change;
                                chuzhi1=chuzhi1+change;        
                        }
                }
                if(jiaodu2>jiaodu1){
                        if((jiaodu2>=balance)&&(chuzhi0<0xb9b0)&&(chazhi>=2)){
                                chuzhi0=chuzhi0+change;
                                chuzhi1=chuzhi1-change;
                        }
                }
                if(jiaodu2<jiaodu1){
                        if((jiaodu2<=balance)&&(chuzhi0>0xb5c8)&&(chazhi>=2)){
                                chuzhi0=chuzhi0-change;
                                chuzhi1=chuzhi1+change;
                        }
                }        
        }
        return;
}

void pid2(){

        float derror,error,change;
        unsigned char jiaodu0,button,j;
                while(1)
                {
              jiaodu0=ADC0832_Read(0);
                c=angle/1000;
                d=angle%1000/100;
                e=angle%1000%100/10;
                f=angle%10;
                j--;
        
                    xianshi();
               
                error=(float)abs(balance-jiaodu0);
                sumerror+=error;
                derror=lasterror-pre_error;
                pre_error=lasterror;
                lasterror=error;
                change=Pro*error+I*sumerror+De*derror;
          // change=error/10+1;
                if(change>500)
                   {
                      change=500;
                    }
                if((error>=20)&&(button==0)){
                        button=1;
                        TH1=0x3c;
                        TL1=0xb0;
                        ET1=1;
                        TR1=1;
                }
                if((jiaodu>balance)&&(chuzhi0<0xb9b0)&&(error>=2)){
                                chuzhi0=chuzhi0-(int)change;
                                chuzhi1=chuzhi1+(int)change;
                                        }
                if((jiaodu<balance)&&(chuzhi0>0xb5c8)&&(error>=2)){
                                chuzhi0=chuzhi0+(int)change;
                                  chuzhi1=chuzhi1-(int)change;        
                        }
                        if(error<2){
                        button=0;
                        ET1=0;
                        TR1=0;
                        time1=(time*10)/20;
                  /*此處添加顯示平衡時間的子函數,平衡時間為已經設好的變量“time”*/
                        m=time1/100;
                     n=time1%100/10;
                    p=time1%10;
                        xianshi2();
                        time=0;
                }

          }
                return;
}                                






歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 伊人久久在线 | 成人av在线网站 | 欧美中文字幕一区二区三区亚洲 | 免费在线一区二区三区 | 欧美日韩美女 | 国产精品有限公司 | 精品免费国产一区二区三区四区 | 日韩在线免费 | 成人午夜 | 狠狠色综合久久丁香婷婷 | 日韩久久久久久 | 国产精品三级久久久久久电影 | 国产精品久久久久久久久久久免费看 | 中文字幕在线观看第一页 | 四季久久免费一区二区三区四区 | 精品福利在线 | 久热久热 | 99精品在线观看 | 久久精品综合 | 高清黄色网址 | 日本三级网址 | 九九九久久国产免费 | 三级黄色片在线播放 | 超碰人人人 | 精品日本中文字幕 | 色综网| 成人av片在线观看 | 成人精品一区二区三区 | 久草热8精品视频在线观看 午夜伦4480yy私人影院 | 在线成人 | 日本成人在线免费视频 | 不卡一二三区 | 91精品国产综合久久久久久 | 久久久国产亚洲精品 | 99精品视频一区二区三区 | 日本在线中文 | 中文字幕视频在线观看免费 | 新91| 中文字幕在线中文 | 午夜理伦三级理论三级在线观看 | 91在线看片 |