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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3625|回復: 1
打印 上一主題 下一主題
收起左側

基于MSP430G2553的直流電機調速測速裝置源程序

[復制鏈接]
跳轉到指定樓層
樓主
本設計基于MSP430G2553單片機,主要用了PWM輸出和捕獲功能,控制算法是PID.
設置二級菜單,功能一:調速功能;通過按鍵加減占空比調速,通過返回按鍵退出此功能。
                       功能二:定速功能:通過按鍵設置目標轉速,確認按鍵按下后,啟動電機,自動調整到目標轉速,通過返回按鍵退出此功能。
(附件限制了大小,能上傳的也就只有程序了,有相關視頻去B站搜索:飛檐走壁王不羈,即可觀看相關視頻)


單片機源程序如下:
  1. #include <msp430G2553.h>
  2. #include "Lcd1602.h"

  3. unsigned int DUTY=1000;   //PWM占空比           (DUTY/10000)%

  4. #define uchar unsigned char
  5. #define uint  unsigned int

  6. uchar flag=0,disp_table[6],cap_table[10],n=0;
  7. volatile uint fre_num=0;
  8. long sum=0;
  9. uint  Redge,frequence,key=4,count=0,speed=0,yes=0,fanhui=0;
  10. uint Period[10];
  11. volatile long AvgPeriod;
  12. unsigned char distr[3];

  13. //uint Real,Target;
  14. /*------------------PID參數初始化----------------------*/
  15. float kp=0.0457,ki=0.005,kd=0.1;  //PI控制參數設置
  16. float error=0,Last_error=0,Prev_error=0;
  17. float IncremDuty;

  18. /****************************增量式PI控制函數******************************/
  19. float Incremental_PID(float Real,float Target)
  20. {
  21.     error = Target - Real;
  22.     IncremDuty = kp*(2.45*error - 3.5*Last_error + 1.25*Prev_error) ;
  23.     Prev_error = Last_error;
  24.     Last_error = error;

  25.     return IncremDuty;
  26. }

  27. /****************************************字符類型轉換函數***********************************************/
  28. char int_to_char(char x)
  29. {
  30.     distr[0] = (x/10) + 0x30;
  31.     distr[1] = x%10 + 0x30;
  32.     distr[2] = '\0';
  33. }

  34. /*---------------------數字轉換成字符------------------------------------------------*/
  35. void num_to_char(uint k)
  36. {
  37.     uchar i=0;

  38. //    disp_table[0] = k/10000 + 0x30;      //'0'的ASCII碼0x30
  39.     disp_table[0] = k%10000/1000 + 0x30;
  40.     disp_table[1] = k%1000/100 + 0x30;
  41.     disp_table[2] = k%100/10 + 0x30;
  42.     disp_table[3] = k%10 + 0x30;
  43.     disp_table[4] = 0x20;
  44.     disp_table[5] = '\0';

  45.     for(i=0;i<4;i++)  //去掉無效的前導'0'字符
  46.     {
  47.         if(disp_table[i]==0x30)
  48.             disp_table[i] = 0x20; //0x20是空格的ASCII碼
  49.         else
  50.             break;
  51.     }
  52. }

  53. void long_to_char(long k)
  54. {
  55.     uchar j=0;

  56.     cap_table[0] = k/100000000 + 0x30;      //'0'的ASCII碼0x30
  57.     cap_table[1] = k%100000000/10000000 + 0x30;
  58.     cap_table[2] = k%10000000/1000000 + 0x30;
  59.     cap_table[3] = k%1000000/100000 + 0x30;
  60.     cap_table[4] = k%100000/10000 + 0x30;
  61.     cap_table[5] = k%10000/1000 + 0x30;
  62.     cap_table[6] = k%1000/100 + 0x30;
  63.     cap_table[7] = k%100/10 + 0x30;
  64.     cap_table[8] = k%10 + 0x30;
  65.     cap_table[9] = '\0';

  66.     for(j=0;j<8;j++)  //去掉無效的前導'0'字符
  67.     {
  68.         if(cap_table[j]==0x30)
  69.             cap_table[j] = 0x20; //0x20是空格的ASCII碼
  70.         else
  71.             break;
  72.     }
  73. }

  74. /*****************************************系統時鐘源設置******************************************************/

  75. void OSC_CLK_Init(void)
  76. {
  77.    if (CALBC1_8MHZ == 0xFF || CALDCO_8MHZ == 0xFF)
  78.    {while(1);}                      // If calibration constants erased, trap CPU!!
  79.     BCSCTL1 = CALBC1_8MHZ;          // Set range
  80.     DCOCTL = CALDCO_8MHZ;           // Set DCO step + modulation

  81.     IFG1 &= ~OFIFG;                 // Clear OSCFault flag
  82.     BCSCTL2 |= SELM_1 + DIVS_3 ;    // Set MCLK=8MHz, SMCLK/
  83. }

  84. /****************************************PWM設置函數(比較模塊)**************************************************/

  85. void PWM()
  86. {
  87.     TA1CTL=TASSEL_2+MC_1+TACLR;     //(定時器A1控制寄存器 )SMCLK 1MHZ+不分頻+增計數+清零
  88.     TA1CCTL2=OUTMOD_7;              //(定時器A1捕獲控制寄存器2)高電平 PWM
  89.     TA1CCR0=10000-1;                //周期10000us==10ms    100HZ
  90.     TA1CCR2=DUTY;                   //高電平時間
  91. }

  92. /********************************************捕獲模塊寄存器設置*******************************************************/
  93. //P1.2端口設置為捕獲功能,用于測量信號頻率 ,當捕獲頻率f=1MHz時
  94. //能捕獲到最大信號周期為65.536ms,頻率為15.26Hz(最低信號頻率)
  95. void Timer_A0_1_CAP()
  96. {
  97.      TACTL   = TASSEL_2 + MC_2 + ID_3 + TACLR;  //SMCLK=1MHz/8=0.125MHz,連續計數模式,清TAR
  98.      TACCTL1 = CAP + CCIS_0 + SCS + CM_1 + CCIE;//CCISxA,開捕獲,上升沿捕獲,使能,同步捕獲
  99. }

  100. /*******************************************GPIO設置*****************************************************/

  101. void IO_RE()
  102. {
  103.     P2DIR |=BIT4;    //pwm輸出   P2.4
  104.     P2SEL |=BIT4;    //

  105.     P1DIR&=~BIT2;    //轉速捕獲    P1.2
  106.     P1SEL|=BIT2;     //

  107.     //查詢方式
  108.     P1DIR&=~(BIT0+BIT1+BIT3+BIT4);   //四個用戶按鍵    0加速   1減速   3加50   4減50
  109.     P1OUT|=BIT0+BIT1+BIT3+BIT4;      //輸出高電平
  110.     P1REN|=BIT0+BIT1+BIT3+BIT4;      //上拉(硬件有上拉)

  111.     P1DIR|=BIT7;                     //P1.7   LED指示燈   用于調試
  112. }

  113. /**************************************按鍵消抖延時函數*******************************************************/

  114. void delay_Nms(unsigned int n)
  115. {
  116.     unsigned int i;
  117.     unsigned int j;
  118.     for(i = n;i > 0;i--)
  119.         for(j = 100;j > 0;j--)
  120.             _NOP();
  121. }

  122. /****************************************主函數***************************************************/
  123. void main(void)
  124. {
  125.     WDTCTL = WDTPW | WDTHOLD;  //
  126.     OSC_CLK_Init();            //SMCLK  1M
  127.     Timer_A0_1_CAP();          //定時器A
  128.     lcdinit();
  129.     IO_RE();
  130.     _EINT();                   //開總中斷

  131. while(1)
  132. {
  133. /**************************************一級菜單************************************************/

  134.     if(key==4)                        //主界面
  135.     {
  136.       disp_str(1,0,"   A: MODE 1   ");
  137.       disp_str(2,0,"   B: MODE 2   ");
  138.       DUTY=1000;
  139.       PWM();
  140.     }
  141.          //功能選項一
  142.           if(!(P1IN&BIT0))
  143.                  {
  144.                    delay_Nms(10);
  145.                      if(!(P1IN&BIT0))
  146.                        {
  147.                           while(!(P1IN&BIT0));
  148.                              {
  149.                               key=1;
  150.                              }
  151.                        }
  152.                  }
  153.          //功能選項二
  154.           if(!(P1IN&BIT1))
  155.                   {
  156.                     delay_Nms(10);
  157.                       if(!(P1IN&BIT1))
  158.                         {
  159.                           while(!(P1IN&BIT1));
  160.                              {
  161.                               key=2;
  162.                              }
  163.                         }
  164.                   }
  165. /*******************************************對應功能***************************************************/
  166. switch(key)
  167. {
  168. /********************************************功能一***************************************************/
  169.     case 1:
  170.         while(1)
  171.         {
  172.         if(count==0)                    //清除主界面
  173.         {
  174.             count=1;
  175.             lcd_clr();
  176.         }


  177.                             /********************功能一主頁面***********************/
  178.                                   disp_str(1,0,"DUTY=");
  179.                                   int_to_char(DUTY/100);   //占空比數值顯示
  180.                                   disp_str(1,6,"   ");
  181.                                   disp_str(1,9,distr);
  182.                                   disp_str(1,11,"%   ");
  183.                                   disp_str(2,0,"n=");      //轉速
  184.                                   disp_str(2,6,"r/min ");

  185.                             /*****************計算顯示頻率(轉速)*********************/
  186.                                       if(flag==1)
  187.                                       {
  188.                                           frequence = (uint)(125000/AvgPeriod)*30;     //計算信號轉速
  189.                                           num_to_char(frequence);
  190.                                           disp_str(2,2,disp_table);
  191.                                           flag = 0;
  192.                                       }

  193. /*********************************************加速按鍵1************************************************/
  194.         if(!(P1IN&BIT0)&&key==1)
  195.            {
  196.              delay_Nms(10);
  197.                if(!(P1IN&BIT0)&&key==1)
  198.                  {
  199.                     disp_str(1,5,"+1%");
  200.                     while(!(P1IN&BIT0)&&key==1);
  201.                        {
  202.                             P1OUT^=BIT7;
  203.                             DUTY+=100;
  204.                                if(DUTY>9000)
  205.                                   {
  206.                                       DUTY=9000;
  207.                                   }
  208.                             PWM();
  209.                             disp_str(1,5,"   ");

  210.                        }
  211.                   }
  212.             }
  213. /*********************************************減速按鍵2**************************************************/
  214.         if(!(P1IN&BIT1)&&key==1)
  215.            {
  216.              delay_Nms(10);
  217.                if(!(P1IN&BIT1)&&key==1)
  218.                  {
  219.                     disp_str(1,5,"-1%");
  220.                     while(!(P1IN&BIT1)&&key==1);
  221.                        {
  222.                             P1OUT^=BIT7;
  223.                             DUTY-=100;
  224.                                if(DUTY<1000)
  225.                                   {
  226.                                       DUTY=1000;
  227.                                   }
  228.                             PWM();
  229.                             disp_str(1,5,"   ");
  230.                        }
  231.                   }
  232.             }

  233. /*********************************************返回按鍵4*********************************************/
  234.         if(!(P1IN&BIT4))
  235.                     {
  236.                       delay_Nms(10);
  237.                         if(!(P1IN&BIT4))
  238.                           {
  239.                              while(!(P1IN&BIT4));
  240.                                 {
  241.                                   key=4;
  242.                                   break;
  243.                                 }
  244.                           }
  245.                     }
  246.         }
  247.         ;
  248.      break;


  249. /********************************************功能二******************************************/
  250.     case 2:
  251.         while(1)
  252.         {
  253.         if(count==0)                    //清除主界面
  254.         {
  255.             count=1;
  256.             lcd_clr();
  257.         }
  258.         DUTY=0;
  259.         PWM();
  260.         disp_str(1,1,"Input:");
  261.         disp_str(2,1,"speed:");
  262.         /*****************計算顯示頻率(轉速)*********************/
  263.           if(flag==1)
  264.           {
  265.               frequence = (uint)(125000/AvgPeriod)*30;     //計算信號轉速
  266.               num_to_char(frequence);
  267.               disp_str(2,7,disp_table);
  268.               flag = 0;
  269.           }

  270.           /*******************************************加按鍵1***********************************************/
  271.                   if(!(P1IN&BIT0)&&key==2)
  272.                      {
  273.                        delay_Nms(10);
  274.                          if(!(P1IN&BIT0)&&key==2)
  275.                            {
  276.                               while(!(P1IN&BIT0)&&key==2);
  277.                                  {
  278.                                       speed+=60;
  279.                                       if(speed>2400)  speed = 2400;
  280.                                  }
  281.                             }
  282.                       }
  283.           /*******************************************減按鍵2***********************************************/
  284.                           if(!(P1IN&BIT1)&&key==2)
  285.                              {
  286.                                delay_Nms(10);
  287.                                  if(!(P1IN&BIT1)&&key==2)
  288.                                    {
  289.                                       while(!(P1IN&BIT1)&&key==2);
  290.                                          {
  291.                                               speed-=60;
  292.                                               if(speed<900)   speed = 900;
  293.                                          }
  294.                                     }
  295.                               }

  296.                           num_to_char(speed);
  297.                           disp_str(1,7,disp_table);
  298.          /*********************************************確認按鍵3*********************************************/
  299.                           if(!(P1IN&BIT3)&&key==2)
  300.                              {
  301.                                delay_Nms(10);
  302.                                  if(!(P1IN&BIT3)&&key==2)
  303.                                    {
  304.                                       while(!(P1IN&BIT3)&&key==2);
  305.                                          {
  306.                                            yes=3;
  307.                                          }
  308.                                     }
  309.                               }
  310.                             if(yes==3)
  311.                             {
  312.                                 DUTY=900;
  313.                                 PWM();
  314.                                 while(fanhui==0) //如果沒有按返回按鍵
  315.                                   {
  316.                                      delay_Nms(150);
  317.                                      if(flag==1) //檢測當前風扇轉速并顯示
  318.                                        {
  319.                                          frequence = (uint)(125000/AvgPeriod)*30; //計算信號轉速
  320.                                          num_to_char(frequence);
  321.                                          disp_str(2,7,disp_table);   //顯示當前轉速
  322.                                          flag = 0;
  323.                                        }
  324.                                        //根據設定轉速進行PID調節
  325.                                      if(fabs(frequence-speed)>20)
  326.                                        {
  327.                                          DUTY = DUTY + (int)Incremental_PID(frequence,speed);
  328.                                          TA1CCR2 = DUTY;
  329.                                        }
  330.                                      if(!(P1IN&BIT4))
  331.                                        {
  332.                                         delay_Nms(10);
  333.                                           if(!(P1IN&BIT4))
  334.                                              {
  335.                                                while(!(P1IN&BIT4));
  336.                                                    {
  337.                                                      fanhui=1;
  338.                                                      break;
  339.                                                    }
  340.                                              }
  341.                                        }
  342.                                   }

  343.                                 if(!(P1IN&BIT4))
  344.                                    {
  345.                                      delay_Nms(10);
  346.                                        if(!(P1IN&BIT4))
  347.                                          {
  348.                                             while(!(P1IN&BIT4));
  349.                                                {
  350.                                                  fanhui=0;speed=0;DUTY=0;yes=0;
  351.                                                  key=4;
  352.                                                  break;
  353.                                                }
  354.                                           }
  355.                                    }


  356.                            }
  357.          /*********************************************返回按鍵4*********************************************/
  358.       }
  359.      break;

  360. }

  361. }
  362. }





  363. /******************************************************************
  364. * TA0.1  P1.2捕獲中斷
  365. * 捕獲測頻原理:分別記錄第1次和第2次捕獲到上升沿的時刻Redge1、Redge2,
  366. * 則信號周期為:Period = Redge2 - Redge1
  367. *******************************************************************/
  368. #pragma vector = TIMER0_A1_VECTOR
  369. __interrupt void TIMER0_A1_ISR(void)
  370. {
  371.        switch(TAIV)
  372.        {
  373.            case  0x02:                   //Vector 2:TACCR1 CCIFG
  374.                  if(fre_num == 0)        // 捕獲上升沿信號
  375.                  {
  376.                      Redge = TACCR1;
  377.                      fre_num++;
  378.                  }
  379.                  else
  380.                  {
  381.                      _DINT();
  382.                      if(TACCR1 > Redge)  //第二次捕獲上升沿
  383.                          Period[n] = TACCR1 - Redge;  //計算周期
  384.                      else
  385.                          Period[n] = 65536 + TACCR1 - Redge;

  386.                      Redge = TACCR1; //保存上次捕獲值

  387.                      sum += (long)Period[n];
  388.                      n++;
  389.                      if(n==10)
  390.                      {flag=1;AvgPeriod = sum/10;n=0;sum=0;} //取10次捕獲值的平均
  391.                      _EINT();
  392.                  }
  393.                  break;
  394.            case 0x0A:
  395.                     //溢出次數計數
  396.                break;

  397.            default: break;
  398.      }
  399. }
復制代碼

所有資料51hei提供下載:
test speed 程序.rar (71.68 KB, 下載次數: 34)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:625113 發表于 2019-12-26 08:39 來自手機 | 只看該作者
感謝分享
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区二区久久久 | 精品国产乱码久久久久久闺蜜 | 国精产品一区一区三区免费完 | 97国产精品视频人人做人人爱 | 国产在线一区二区 | 久久精品一区二区视频 | 成人久久久 | 色片在线观看 | 91av在线看| 国产91久久久久蜜臀青青天草二 | 在线播放一区 | 国产精品久久午夜夜伦鲁鲁 | 97人澡人人添人人爽欧美 | 久草精品视频 | 一区观看| 精品国产一区二区三区四区在线 | 欧美精品第一页 | 亚洲国产精品福利 | 欧美aaa| 国产一级精品毛片 | 又爽又黄axxx片免费观看 | 国产视频日韩 | 亚洲一区 | 中文字幕综合 | 欧美日韩在线视频一区 | 亚洲自拍偷拍欧美 | 免费色网址 | 特级一级黄色片 | 国产av毛片| 亚洲国产精品久久久久久 | 一级毛片高清 | 欧美电影在线观看网站 | 天天av网 | 日本aⅴ中文字幕 | 午夜精品一区二区三区在线观看 | 日韩有码在线播放 | 美女张开腿露出尿口 | 午夜羞羞 | 国产精品久久久久久久久久久久冷 | 国产自产21区 | 国产精品日韩欧美一区二区三区 |