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

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

QQ登錄

只需一步,快速開始

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

STM32單片機(jī)板球系統(tǒng)設(shè)計(jì)與程序調(diào)試 2017國(guó)賽資料

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
在大一參加了2017年的全國(guó)大學(xué)生電子設(shè)計(jì)大賽,并且拿到了省賽二等獎(jiǎng),雖然效果不是特別的完美,但是實(shí)現(xiàn)了全部的功能。
    因?yàn)槊總(gè)點(diǎn)的位置差異,從點(diǎn)到點(diǎn)函數(shù)并不只有一種的情況啊
    其實(shí)總共只有三種點(diǎn)的存在啊



2017年全國(guó)大學(xué)生電子設(shè)計(jì)大賽:
/*
        1.不同于auto變量,被stati定義的變量的內(nèi)存只分配一次的,因此在下次調(diào)用時(shí)仍然保持上次的值,這是一個(gè)很重要的功能,
          而且也不用每次都開辟內(nèi)存并寫入相應(yīng)的數(shù)據(jù),為CPU減輕負(fù)擔(dān)
        2.此外,sttic關(guān)鍵字限制變量的作用域,只能被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其他函數(shù)訪問(wèn)
        3.自動(dòng)變量使用堆棧機(jī)制使用內(nèi)存,而靜態(tài)變量是分配固定的內(nèi)存
        4.register 請(qǐng)求將數(shù)據(jù)存到內(nèi)部寄存器中,不用通過(guò)內(nèi)存尋址來(lái)訪問(wèn)變量,提高訪問(wèn)效率
        5.volatile 從他的內(nèi)存中讀取數(shù)據(jù),而不使用寄存器緩存的值  即不使用寄存器優(yōu)化
*/

/*typedef unsigned char uchar   對(duì)比著看這個(gè)你就應(yīng)該懂啦吧   多多學(xué)習(xí)這些基礎(chǔ)的東西  以后看別人的代碼就不會(huì)太費(fèi)事啦*/
//       printf("count1=%d\r\n",usart2_dat);
                    

      u8   item3_flag=0;
      u16  time_tingliu;
      char cha_x,cha_y;
      static uint32_t MoveTimeCnt = 0;
      MoveTimeCnt += 5;                                  //每5ms運(yùn)算1次
        
    if(item3_flag==0)   
    {   
        
      if( (target_BUF[6]<Position_BUF[6])  &&  (target_BUF[7]<Position_BUF[7]) )
        {   
                target_BUF[6]=Position_BUF[0]+MoveTimeCnt*0.2;        //這相當(dāng)于是一個(gè)隨動(dòng)系統(tǒng),但不知道那個(gè)效果好啊
                target_BUF[7]=Position_BUF[1]+MoveTimeCnt*0.2;        //到了調(diào)試時(shí)按照具體的現(xiàn)象定方案吧
        }                                                                    
   
        PID_M1_SetPoint(target_BUF[6]);      //X方向PID定位目標(biāo)值0
        PID_M1_SetKp(85);         
        PID_M1_SetKi(0);     
        PID_M1_SetKd(2000);

        PID_M2_SetPoint(target_BUF[7]);      //Y方向PID定位目標(biāo)值0
        PID_M2_SetKp(85);         
        PID_M2_SetKi(0);   
        PID_M2_SetKd(2000);
            
        M1.PWM = PID_M1_PosLocCalc(Ball_x);    //   電機(jī)一PWM計(jì)算
        M2.PWM = PID_M2_PosLocCalc(Ball_y);  //   電機(jī)二PWM計(jì)算        //但是暫時(shí)并沒有使用積分分離,只有積分限幅最后加
        
        if(M1.PWM > POWER1_MAX)  M1.PWM =  POWER1_MAX;
        if(M1.PWM < POWER1_MIN)  M1.PWM =  POWER1_MIN;   
        
        if(M2.PWM > POWER2_MAX)  M2.PWM = POWER2_MAX;
        if(M2.PWM < POWER2_MIN)  M2.PWM = POWER2_MIN;        
   
   
       MotorMove(M1.PWM,M2.PWM);
         
         //這里計(jì)算的就是絕對(duì)的誤差大小啦
         cha_x=Position_BUF[6]-Ball_x;
         cha_y=Position_BUF[7]-Ball_y;
         if(  (abs(cha_x)<4)  &&  (abs(cha_y)<4)    )
         {
              time_tingliu+=5;
             if(time_tingliu==420)
             {
                  item3_flag=1;
             }
         }
         
     }
     
     else      //但是要求在P5停留至少兩秒的程序并沒有寫,覺著并不需要    但是時(shí)間確實(shí)是需要特別注意的一個(gè)地方
     {
            if( (target_BUF[8]<Position_BUF[8])  &&  (target_BUF[9]<Position_BUF[9]) )
            {   
                    target_BUF[8]=Position_BUF[6]+MoveTimeCnt*0.2;        //這相當(dāng)于是一個(gè)隨動(dòng)系統(tǒng),但不知道那個(gè)效果好啊
                    target_BUF[9]=Position_BUF[7]+MoveTimeCnt*0.2;        //到了調(diào)試時(shí)按照具體的現(xiàn)象定方案吧
            }                                                                    
        
            PID_M1_SetPoint(target_BUF[8]);      //X方向PID定位目標(biāo)值0
            PID_M1_SetKp(85);         
            PID_M1_SetKi(0);     
            PID_M1_SetKd(2000);

            PID_M2_SetPoint(target_BUF[9]);      //Y方向PID定位目標(biāo)值0
            PID_M2_SetKp(85);         
            PID_M2_SetKi(0);   
            PID_M2_SetKd(2000);
               
            M1.PWM = PID_M1_PosLocCalc(Ball_x);    //   電機(jī)一PWM計(jì)算
            M2.PWM = PID_M2_PosLocCalc(Ball_y);  //   電機(jī)二PWM計(jì)算        //但是暫時(shí)并沒有使用積分分離,只有積分限幅最后加
            
        if(M1.PWM > POWER1_MAX)  M1.PWM =  POWER1_MAX;
        if(M1.PWM < POWER1_MIN)  M1.PWM =  POWER1_MIN;   
        
        if(M2.PWM > POWER2_MAX)  M2.PWM = POWER2_MAX;
        if(M2.PWM < POWER2_MIN)  M2.PWM = POWER2_MIN;            
        
        
             MotorMove(M1.PWM,M2.PWM);
               
     }

}






/*------------------------------------------
函數(shù)功能:第4問(wèn)PID計(jì)算
函數(shù)說(shuō)明:電機(jī)M1控制X方向,電機(jī)M2控制Y軸方向
------------------------------------------*/
void item4()
{            
      u8   item4_flag=0;
      u16  time_tingliu;
      char cha_x,cha_y;
      static uint32_t MoveTimeCnt = 0;
      MoveTimeCnt += 5;                                  //每5ms運(yùn)算1次
        
    if(item4_flag==0)   
    {   
        
      if( (target_BUF[8]<Position_BUF[8])  &&  (target_BUF[9]<Position_BUF[9]) )
        {   
                target_BUF[8]=Position_BUF[0]+MoveTimeCnt*0.2;        //這相當(dāng)于是一個(gè)隨動(dòng)系統(tǒng),但不知道那個(gè)效果好啊
                target_BUF[9]=Position_BUF[1]+MoveTimeCnt*0.2;        //到了調(diào)試時(shí)按照具體的現(xiàn)象定方案吧
        }                                                                    
   
        PID_M1_SetPoint(target_BUF[8]);      //X方向PID定位目標(biāo)值0
        PID_M1_SetKp(85);         
        PID_M1_SetKi(0);     
        PID_M1_SetKd(2000);

        PID_M2_SetPoint(target_BUF[9]);      //Y方向PID定位目標(biāo)值0
        PID_M2_SetKp(85);         
        PID_M2_SetKi(0);   
        PID_M2_SetKd(2000);
            
        M1.PWM = PID_M1_PosLocCalc(Ball_x);    //   電機(jī)一PWM計(jì)算
        M2.PWM = PID_M2_PosLocCalc(Ball_y);  //   電機(jī)二PWM計(jì)算        //但是暫時(shí)并沒有使用積分分離,只有積分限幅最后加
        
        if(M1.PWM > POWER1_MAX)  M1.PWM =  POWER1_MAX;
        if(M1.PWM < POWER1_MIN)  M1.PWM =  POWER1_MIN;   
        
        if(M2.PWM > POWER2_MAX)  M2.PWM = POWER2_MAX;
        if(M2.PWM < POWER2_MIN)  M2.PWM = POWER2_MIN;            
   
   
       MotorMove(M1.PWM,M2.PWM);
         
         //這里計(jì)算的就是絕對(duì)的誤差大小啦
         //先確定我可以很好的到達(dá)區(qū)域5,然后再?gòu)膮^(qū)域5跑到區(qū)域9     在區(qū)域1到區(qū)域9的途徑很多  我可以隨意選擇的啊
         cha_x=Position_BUF[8]-Ball_x;
         cha_y=Position_BUF[9]-Ball_y;
         if(  (abs(cha_x)<4)  &&  (abs(cha_y)<4)    )
         {
              time_tingliu+=5;
             if(time_tingliu==100)
             {
                  item4_flag=1;
             }
         }         
     }
     
     else
     {
            if( (target_BUF[16]<Position_BUF[16])  &&  (target_BUF[17]<Position_BUF[17]) )
            {   
                    target_BUF[16]=Position_BUF[8]+MoveTimeCnt*0.2;        //這相當(dāng)于是一個(gè)隨動(dòng)系統(tǒng),但不知道那個(gè)效果好啊
                    target_BUF[17]=Position_BUF[9]+MoveTimeCnt*0.2;        //到了調(diào)試時(shí)按照具體的現(xiàn)象定方案吧
            }                                                                    
        
            PID_M1_SetPoint(target_BUF[16]);      //X方向PID定位目標(biāo)值0
            PID_M1_SetKp(85);         
            PID_M1_SetKi(0);     
            PID_M1_SetKd(2000);

            PID_M2_SetPoint(target_BUF[17]);      //Y方向PID定位目標(biāo)值0
            PID_M2_SetKp(85);         
            PID_M2_SetKi(0);   
            PID_M2_SetKd(2000);
               
            M1.PWM = PID_M1_PosLocCalc(Ball_x);    //   電機(jī)一PWM計(jì)算
            M2.PWM = PID_M2_PosLocCalc(Ball_y);  //   電機(jī)二PWM計(jì)算        //但是暫時(shí)并沒有使用積分分離,只有積分限幅最后加
            
        if(M1.PWM > POWER1_MAX)  M1.PWM =  POWER1_MAX;
        if(M1.PWM < POWER1_MIN)  M1.PWM =  POWER1_MIN;   
        
        if(M2.PWM > POWER2_MAX)  M2.PWM = POWER2_MAX;
        if(M2.PWM < POWER2_MIN)  M2.PWM = POWER2_MIN;        
        
        
             MotorMove(M1.PWM,M2.PWM);
               
     }



5 上下限 0.8-1.2
1題        
        PID_M1_SetKp(0.07);   
        PID_M1_SetKi(0);     
        PID_M1_SetKd(0.8);
        PID_M2_SetKp(0.07);   
        PID_M2_SetKi(0);        
        PID_M2_SetKd(0.8);      




        PID_M1_SetPoint(Position_BUF[8]);            //X方向PID定位目標(biāo)值0
        PID_M1_SetKp(0.111);   
        PID_M1_SetKi(0.005);     
        PID_M1_SetKd(2);
        
        PID_M2_SetPoint(Position_BUF[9]);       //Y方向PID跟蹤目標(biāo)值sin
        PID_M2_SetKp(0.111);   
        PID_M2_SetKi(0.005);        
        PID_M2_SetKd(2);      
2題     PID_M1_SetPoint(Position_BUF[8]);            //X方向PID定位目標(biāo)值0
        PID_M1_SetKp(0.22);   
        PID_M1_SetKi(0.02);     
        PID_M1_SetKd(1.8);
        
        PID_M2_SetPoint(Position_BUF[9]);       //Y方向PID跟蹤目標(biāo)值sin
        PID_M2_SetKp(0.22);   
        PID_M2_SetKi(0.02);        
        PID_M2_SetKd(1.8);           






void item7()
{            
    static u8 i;
   
    const float priod =4000;                 //單擺周期(毫秒)     1851
    static uint32_t MoveTimeCnt = 0;
   
    float set_x = 0.0;
    float set_y = 0.0;

    float Normalization = 0.0;
    float Omega = 0.0;
   
    MoveTimeCnt += 100;                                   //每100ms運(yùn)算1次,來(lái)源于100ms的定時(shí)器函數(shù)  
    Normalization = (float)MoveTimeCnt / priod;     //對(duì)單擺周期歸一化
    Omega = 2.0*3.1415926*Normalization;                 //對(duì)2π進(jìn)行歸一化處理               
        
   
   
    set_x = R*sin(Omega);                 //計(jì)算出X方向當(dāng)前擺角
    set_y = R*sin(Omega+((3.0*3.141592)/2.0));      //計(jì)算出Y方向當(dāng)前擺角     3*PI/2   是順時(shí)針轉(zhuǎn)圈    用正弦余弦就不用這個(gè)關(guān)系啦
     
    set_x=set_x*4+117;
    set_y=set_y*4+116;
   
    PID_M1_SetPoint(set_x);    //X方向PID跟蹤目標(biāo)值sin
    PID_M1_SetKp(0.21);   
    PID_M1_SetKi(0.02);     
    PID_M1_SetKd(2.01);

    PID_M2_SetPoint(set_y);    //Y方向PID跟蹤目標(biāo)值cos
    PID_M2_SetKp(0.21);   
    PID_M2_SetKi(0.02);        
    PID_M2_SetKd(2.01);         
   
            M1.PWM = PID_M1_PosLocCalc(Ball_x);     //   電機(jī)一PWM計(jì)算
            M2.PWM = PID_M2_PosLocCalc(Ball_y);  //   電機(jī)二PWM計(jì)算        //但是暫時(shí)并沒有使用積分分離,只有積分限幅最后加
   
        if(M1.PWM > POWER1_MAX)  M1.PWM =  POWER1_MAX;
        if(M1.PWM < POWER1_MIN)  M1.PWM =  POWER1_MIN;   
        
        if(M2.PWM > POWER2_MAX)  M2.PWM =  POWER2_MAX;
        if(M2.PWM < POWER2_MIN)  M2.PWM =  POWER2_MIN;              //83   95   107   

          MotorMove(M1.PWM,M2.PWM);
   
   
     //作為一個(gè)標(biāo)志,指示系統(tǒng)的運(yùn)行   
    i++;
    if(i==10)
    {
//              printf("All is well!\r\n");
//        printf("count1=%d\r\n",M1.PWM);
//        printf("count2=%d\r\n",M2.PWM);
            i=0;
    }
       send_data(&set_x,&set_y);     //  一三目標(biāo)   二四實(shí)
}

下面是主程序:
  1. /**
  2. **          2017全國(guó)大學(xué)生電子設(shè)計(jì)大賽
  3. **/

  4. //記得檢查優(yōu)先級(jí)啊,刪減變量   到時(shí)候估計(jì)PID的選擇也是一個(gè)問(wèn)題啊
  5. /*
  6.                 比賽記錄:
  7.                 整個(gè)題目全是在要求在X秒之內(nèi)完成,要停留多少多少秒,可見時(shí)間到時(shí)候會(huì)成為一個(gè)很重要的判斷標(biāo)準(zhǔn)
  8.                 而且可以看出     對(duì)小球的快速性要求非常高     誰(shuí)快誰(shuí)就是王
  9. */

  10. #include "sys.h"

  11. int main(void)
  12. {

  13.        
  14.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //設(shè)置系統(tǒng)中斷優(yōu)先級(jí)分組2       
  15.         NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(5, 0, 0));
  16.   All_init();

  17.                 while(1)
  18.                 {               
  19.                        
  20.                 }

  21. }
復(fù)制代碼

全部資料51hei下載地址:
2017國(guó)賽----最后.7z (617.67 KB, 下載次數(shù): 69)

評(píng)分

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

查看全部評(píng)分

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

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日批免费观看 | 亚洲色图综合网 | 久久久久久国模大尺度人体 | 日韩精品999 | 中文字幕视频在线观看 | 九久久| 欧美一级免费 | 一道本不卡视频 | 日日夜精品视频 | 亚洲一区二区三区四区五区午夜 | 国产美女免费视频 | 看羞羞视频免费 | 国产日韩视频在线 | 国产成人一区二区三区久久久 | 亚洲一区在线免费观看 | 国产成人99久久亚洲综合精品 | 欧美日韩视频在线播放 | 奇米影视在线 | www.久久久.com | 日韩精品一区二区三区中文在线 | 在线播放中文字幕 | 色播久久久 | 亚洲视频免费在线观看 | 国产精品18久久久久久白浆动漫 | 日韩欧美中文字幕在线观看 | 综合激情网 | wwwxxx国产| 五月婷婷视频 | 美日韩免费视频 | 99精品网 | 亚洲高清成人在线 | 久久精品综合网 | 中文字幕伊人 | 特一级黄色毛片 | 中文字幕成人在线 | 日韩成人中文字幕 | 中文字幕一区二区视频 | 欧美日韩一区二区在线 | 久久亚洲国产精品日日av夜夜 | 91精品国产91久久久久久最新 | 91在线视频播放 |