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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

無刷無感電機過零檢測單片機源程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:299262 發表于 2018-3-30 09:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
附件中的源文件是無感三相電機零速定位,開環加速以前閉環控制(含過零檢測的程序)

單片機源程序如下:

  1. #include "hardware.h"
  2. #include "bldc.h"

  3. u16 Temp = 0;

  4. volatile State_TypeDef State = Idle;

  5. Task_TypeDef Task;

  6. Flag_TypeDef Flag;

  7. vu16        ADC_VALUE[ADC_NUMBER*ADC_BUFFER]={0};
  8. u16          SysTime = 0;                                                                                                                                                                                /* 系統時間 */
  9. u8                 Phase = 0;                                                                                                                                                                                        /* 通電繞組 */
  10. u16         PwmDuty = 0;                                                                                                                                                                                /* PWM占空比 */
  11. u8                 AlignRotorCount = 0;                                                                                                                                                /* 電機啟動時鎖定轉子的次數 */
  12. u8                 BlankingCount = 0;                                                                                                                                                        /* 消隱時長 */
  13. //u8         ZeroBeforeCount = 0;                                                                                                                                                /* 過零點之前的檢測次數 */
  14. u8                 ZeroCrossCount = 0;                                                                                                                                                        /* 到達過零點的檢測次數 */
  15. u8                 ZeroAcquireCount = 0;                                                                                                                                                /* 進入到同步運行狀態前的過零點次數 */
  16. u16         CommutateTime = 0;                                                                                                                                                        /* 過零檢測到到換向的時間 */
  17. u16         AccelerateCommutateTime = 0;                                                                                                                /* 電機加速的換向的時間 */
  18. u16         AdcPotentiometer = 0;                                                                                                                                                /* 電位器ADC轉換結果 */
  19. u16         AdcBEMF = 0;                                                                                                                                                                                /* BEMF電壓ADC轉換結果 */
  20. u16         AdcCurrent = 0;                                                                                                                                                                        /* 電流放大器ADC轉換結果 */
  21. u16         AdcVbus = 0;                                                                                                                                                                                /* 電源電壓ADC轉換結果 */
  22. u16         ZeroVref = 0;                                                                                                                                                                                /* 過零檢測基準電壓,等于電源電壓的一半 */
  23. u8                 SpeedErrorCount = 0;                                                                                                                                                /* 電機速度異常次數 */
  24. u16         ZeroPeriod = 1000;                                                                                                                                                        /* 過零周期即60度換向時間 */
  25. u16         MotorRpm = 0;                                                                                                                                                                                /* 電機轉速,單位RPM */
  26. u16                AccelerateTime = 0;                                                                                                                                                        /* 電機加速運轉的時間 */
  27. //u16 PhaseAdvance = 0;                                                                                                                                                                /* 超前相位 */
  28. u16         Current = 0;                                                                                                                                                                                /* 電流值 */
  29. u16         Iref = 0;                                                                                                                                                                                                /* 電流放大器輸出偏置 */

  30. #define MaxIX                                                                999                                                                                                                         //最大記錄條數
  31. vu16        BEMF_REC[MaxIX+1]={0};                                                                                                                                        // 反電動勢記錄
  32. u16   ix = 0;                                                                                                                                                                                                        // 記錄下標
  33. /********************************************************************************************
  34. * Function Name  : void Scan_Key(void)
  35. * Description    : 按鍵掃描程序,用于啟動或者停止電機運轉
  36. * Input          : 無
  37. * Return         : 無
  38. *********************************************************************************************/
  39. void Scan_Key(void)
  40. {
  41.     if(Key_Status() == PRESS)
  42.     {
  43.         if(State == Idle)
  44.         {
  45.             while(Key_Status() != RELEASE);
  46.             State = Start;
  47.         }
  48.         else
  49.         {
  50.             while(Key_Status() != RELEASE);
  51.             State = Stop;
  52.         }
  53.     }
  54. }


  55. void Start_Motor(void)
  56. {
  57.     Close_LED7();
  58.     Close_LED8();
  59.     Close_LED9();

  60.     Flag.AcquireZero         = 0;
  61.     Flag.ZeroCross                 = 0;
  62.     SpeedErrorCount                = 0;
  63.     AccelerateTime                 = 0;
  64.     AlignRotorCount         = 3;                                                                                                                                                                                                                                /* 初始化電機轉子定位次數 */

  65.     Update_PwmDuty((u32)ALIGN_ROTOR_PWM*FULL_DUTY/100);
  66.     Phase                                                 = 0;
  67.     Commutate();
  68.     TIM_CtrlPWMOutputs(TIM1, ENABLE);
  69.     State                                                 = AlignRotor;
  70.     SysTime                                         = 0;
  71.     Task.AlignRotor         = 0;
  72.     printf("Start AlignRotor !!!\n\r");
  73. }

  74. /********************************************************************************************
  75. * Function Name  : void AlignMotorRotor(void)
  76. * Description    : 轉子定位程序
  77. * Input          : 無
  78. * Return         : 無
  79. *********************************************************************************************/
  80. void Align_MotorRotor(void)
  81. {
  82.     if(AlignRotorCount > 0)
  83.     {
  84.                                 Phase                                                 = 0;
  85.         Commutate();
  86.         Update_PwmDuty((u32)ALIGN_ROTOR_PWM*FULL_DUTY/100);
  87.         AlignRotorCount --;
  88.         if (AlignRotorCount == 0)
  89.         {
  90.             Update_PwmDuty((u32)PWM_ACCELERATE_START*FULL_DUTY/100);                                                                                //更新初始加速占空比
  91.             AccelerateCommutateTime = TIM2_FREQ*20/START_RPM/MOTOR_POLES;                                                                //設計初始加速時間參數

  92.             /* 啟動TIM2,進入到加速狀態 */
  93.             TIM2_Counter = 0;
  94.             Clear_TIM2_Update_IF();
  95.             Enable_TIM2_Update_IT();

  96.             Clear_TIM1_CC4_IF();
  97.             Enable_TIM1_CC4_IT();

  98.             State = Accelerate;
  99.             //State = Stop;
  100.         }
  101.     }
  102. }

  103. void Commutate(void)
  104. {
  105.     Disable_AH();
  106.     Disable_AL();
  107.     Disable_BH();
  108.     Disable_BL();
  109.     Disable_CH();
  110.     Disable_CL();

  111.     switch(Phase)
  112.     {
  113.         case 0:                                                                                                                                                                                                                                                                                                /* AB相 */
  114.         {
  115.             //Disable_CH();
  116.             Enable_AH();
  117.             Enable_BL();
  118.             #if (DIRECTION == COUNTER_CLOCKWISE)
  119.                 Flag.BemfEdge = FALLING;
  120.                 Phase = 1;
  121.             #else
  122.                 Flag.BemfEdge = RISING;
  123.                 Phase = 5;
  124.             #endif
  125.         }
  126.         break;

  127.         case 1:                                                                                                                                                                                                                                                                                                /* AC相 */
  128.         {
  129.             Enable_AH();
  130.             //Disable_BL();
  131.             Enable_CL();
  132.             #if (DIRECTION == COUNTER_CLOCKWISE)
  133.                 Flag.BemfEdge = RISING;
  134.                 Phase = 2;
  135.             #else
  136.                 Flag.BemfEdge = FALLING;
  137.                 Phase = 0;
  138.             #endif
  139.         }
  140.         break;

  141.         case 2:                                                                                                                                                                                                                                                                                                /* BC相 */
  142.         {
  143.             //Disable_AH();
  144.             Enable_BH();
  145.             Enable_CL();
  146.             #if (DIRECTION == COUNTER_CLOCKWISE)
  147.                 Flag.BemfEdge = FALLING;
  148.                 Phase = 3;
  149.             #else
  150.                 Flag.BemfEdge = RISING;
  151.                 Phase = 1;
  152.             #endif
  153.         }
  154.         break;
  155.                                
  156.         case 3:                                                                                                                                                                                                                                                                                                /* BA相 */
  157.         {
  158.             Enable_BH();
  159.             //Disable_CL();
  160.             Enable_AL();
  161.             #if (DIRECTION == COUNTER_CLOCKWISE)
  162.                 Flag.BemfEdge = RISING;
  163.                 Phase = 4;
  164.             #else
  165.                 Flag.BemfEdge = FALLING;
  166.                 Phase = 2;
  167.             #endif
  168.         }
  169.         break;

  170.         case 4:                                                                                                                                                                                                                                                                                                /* CA相 */
  171.         {
  172.             //Disable_BH();
  173.             Enable_CH();
  174.             Enable_AL();
  175.             #if (DIRECTION == COUNTER_CLOCKWISE)
  176.                 Flag.BemfEdge = FALLING;
  177.                 Phase = 5;
  178.             #else
  179.                 Flag.BemfEdge = RISING;
  180.                 Phase = 3;
  181.             #endif
  182.         }
  183.         break;

  184.         case 5:                                                                                                                                                                                                                                                                                                /* CB相 */
  185.         {
  186.             Enable_CH();
  187.             //Disable_AL();
  188.             Enable_BL();
  189.             #if (DIRECTION == COUNTER_CLOCKWISE)
  190.                 Flag.BemfEdge = RISING;
  191.                 Phase = 0;
  192.             #else
  193.                 Flag.BemfEdge = FALLING;
  194.                 Phase = 4;
  195.             #endif
  196.         }
  197.         break;

  198.         default:
  199.             break;
  200.     }

  201.     Flag.ZeroCross = 0;
  202.     BlankingCount = BLANKING_COUNT;
  203.     ZeroCrossCount = 0;
  204. }

  205. void Stop_Running(void)
  206. {
  207.     Disable_PwmOutput();
  208.     Clear_TIM1_CC4_IF();
  209.     Disable_TIM1_CC4_IT();
  210.     Clear_TIM2_Update_IF();
  211.     Disable_TIM2_Update_IT();
  212.     State = Idle;

  213.     if(Flag.FailedStart)                                                                                                                                                                                                                                                                                        /* 輸出錯誤標志 */
  214.     {
  215.         Flag.FailedStart = 0;
  216.         printf("Error: Failed to start!!!\n\r");
  217.     }

  218.     if(Flag.CurrentHigh)
  219.     {
  220.         Flag.CurrentHigh = 0;
  221.         printf("Error: Current is too large!!!\n\r");
  222.     }

  223.     if(Flag.SpeedHigh)
  224.     {
  225.         Flag.SpeedHigh = 0;
  226.         printf("Error: Motor speed is too high !!!\n\r");
  227.     }

  228.     if(Flag.SpeedLow)
  229.     {
  230.         Flag.SpeedLow = 0;
  231.         printf("Error: Motor speed is too low !!!\n\r");
  232.     }

  233.     if(Flag.LostZero)
  234.     {
  235.         Flag.LostZero = 0;
  236.         printf("Error: Sensor error !!!\n\r");
  237.     }

  238.     printf("Motor stop !!!\n\r");
  239. }
  240. //  ROUNDUP(    INDIRECT("E7") * 20      /    (    INDIRECT("D13")*   B7*B7   /   INDIRECT("F13")   /    INDIRECT("F13")   +   INDIRECT("F7")   )  /   INDIRECT("G7")            ,0     )
  241. void Accelerate_Motor(void)                                                                                                                                                                                                                                                                                // 加速
  242. {
  243.     u16 speed = 0;                                                                                                                                                                                                                                                                                                     // 新的目標速度
  244.     u32 ct = 0;                                                                                                                                                                                                                                                                                                        // 新的換向時間

  245.     speed = ((u32)AccelerateTime*AccelerateTime)/ACCELERATE_TIME;                                                                                                                        /* 計算新的目標速度 */
  246.     speed = ((u32)(END_RPM - START_RPM)*speed)/ACCELERATE_TIME;
  247.     speed += START_RPM;
  248.                
  249.     ct = (u32)TIM2_FREQ*20/speed/MOTOR_POLES;                                                                                                                                                                                                        /* 將速度轉換為相應的換向時長 */
  250.                
  251.                 //ct = AccelerateCommutateTime*14/15-1;
  252.     if(ct > 65535)        AccelerateCommutateTime = 65535;
  253.     else                                                AccelerateCommutateTime = ct;
  254.        
  255.                

  256.     PwmDuty = ((u32)PWM_ACCELERATE_DELTA*AccelerateTime/ACCELERATE_TIME);                                                                                        /* 計算PWM增量 */
  257.     PwmDuty += (u16)((u32)PWM_ACCELERATE_START*FULL_DUTY/100);                                                                                                                                /* 更新PWM */
  258.     Update_PwmDuty(PwmDuty);

  259.     if((AccelerateCommutateTime <= TIM2_FREQ*20/ZERO_ACQUIRE_RPM/MOTOR_POLES)&&                                                                /* 開始捕獲過零點 */
  260.        (Flag.AcquireZero == 0))
  261.     {
  262.                                 Flag.AcquireZero = 1;
  263.         ZeroAcquireCount = 0;
  264. //                                Open_LED7();
  265.                 }

  266.                 if(AccelerateCommutateTime <= TIM2_FREQ*20/END_RPM/MOTOR_POLES)                                                                                                                /* 加速到啟動終止速度時,啟動失敗 */
  267.     {
  268.         State = Stop;
  269.         Flag.FailedStart = 1;
  270.                                 Open_LED6();
  271.                 }
  272. }

  273. void Check_ZeroCrossing(void)
  274. {
  275.     u16 t = 0;

  276.     if(BlankingCount > 0)                                                                                                                                                /* 等待消隱 */
  277.     {
  278.         BlankingCount --;
  279.         return;
  280.     }

  281.     if((Flag.BemfEdge == FALLING)&&(AdcBEMF < ZeroVref))                /* 判斷BEMF電壓是否過零 */
  282.         ZeroCrossCount ++;

  283.     if((Flag.BemfEdge == RISING)&&(AdcBEMF > ZeroVref))
  284.         ZeroCrossCount ++;
  285.        
  286.     //Open_LED7();
  287.     if (ZeroCrossCount > ZERO_SAMPLES-1)                                                                                /* 達到預期的過零次數 */
  288.     {
  289.                                 BEMF_REC[ix] = AdcBEMF;
  290.                                 ix++;
  291.                                 if(ix>MaxIX) ix = 0;
  292.         //Open_LED8();
  293.         ZeroPeriod = TIM3_Counter;                                                                                                        /* 從TIM3計數器讀取2次過零點的周期 */
  294.         TIM3_Counter = 0;

  295.         t = ZeroPeriod >> 1;                                                                                                                                /* 計算30度換向時長 */
  296.         CommutateTime = ((u32)t * (30 - ADVANCE_ANGLE))/30;        /* 超前相位補償 */

  297.         if(CommutateTime > ZERO_CHECK_DELAY)                                                                /* ADC過零檢測延遲補償 */
  298.                                           CommutateTime -= ZERO_CHECK_DELAY;
  299.         else
  300.             CommutateTime = 1;

  301.         if (State == Running)
  302.         {
  303.             Flag.ZeroCross = 1;

  304.             Disable_TIM2_Update_IT();
  305.             TIM2->ARR = CommutateTime;
  306.             TIM2_Counter = 0;
  307.             Clear_TIM2_Update_IF();
  308.             Enable_TIM2_Update_IT();
  309.                                                 Open_LED9();                                                                                                                                                // 標志著已經切換到閉環控制狀態
  310.         }
  311.         else                                                                                                                                                                                                /* 電機加速到同步運轉狀態的判斷 */
  312.         {
  313.             ZeroAcquireCount ++;
  314.             
  315.             if(ZeroAcquireCount > ZERO_ACQUIRE_COUNT-1)                        /* 進入過零點同步狀態 */
  316.             {
  317.                 Flag.ZeroCross = 1;
  318.                 Disable_TIM2_Update_IT();
  319.                 Flag.AcquireZero = 0;
  320.                 State = Running;

  321.                 TIM2->ARR = CommutateTime;                                                                        /* 更新TIM2定時換向 */
  322.                 TIM2_Counter = 0;
  323.                 Clear_TIM2_Update_IF();
  324.                 Enable_TIM2_Update_IT();
  325. //                                                                Open_LED9();                                                                                                                                // 標志著已經從開環加速正在切換到閉環控制狀態
  326.             }
  327.         }
  328.     }
  329. }

  330. /********************************************************************************************
  331. * Function Name  : void Get_MotorSpeed(void)
  332. * Description    : 計算電機速度程序
  333.                    RPM = 60/((60°換向周期(秒)*6)*(極數/2)) = 20/(T*P)
  334. * Input          : 無
  335. * Return         : 無
  336. *********************************************************************************************/
  337. void Get_MotorSpeed(void)
  338. {
  339.     static u16 t = 0;

  340.     t += ZeroPeriod;                                                                                                                                                        /* 計算2次60度換向周期的平均值 */
  341.     t = t >> 1;
  342.     MotorRpm = (u32)TIM2_FREQ*20/t/MOTOR_POLES;                                                /* RPM = 60/((60°換向周期(秒)*6)*(極數/2)) = 20/(T*P) */
  343. }

  344. void Control_Speed(void)
  345. {
  346.     u16 duty = 0;

  347.     duty = ((u32)AdcPotentiometer*FULL_DUTY)/4095;                                /* 將ADC轉換結果線性轉換為PWM的占空比 */
  348.     if(duty > PwmDuty)                                                                                                                                                /* 逐漸調整PWM占空比,避免占空比調整步長太大導致電機失速 */
  349.     {
  350.         PwmDuty += 4;
  351.         if(PwmDuty > FULL_DUTY)                PwmDuty = FULL_DUTY;
  352.     }
  353.     else if(duty < PwmDuty)
  354.     {
  355.         if(PwmDuty < 4)         PwmDuty = 0;
  356.         else                                 PwmDuty -= 4;
  357.     }
  358.     else     return;
  359.     Update_PwmDuty(PwmDuty);                                                                                                                        /* 更新PWM占空比 */
  360. }

  361. /********************************************************************************************
  362. * Function Name  : void Monitor_Speed(void)
  363. * Description    : 電機失速監控程序
  364. * Input          : 無
  365. * Return         : 無
  366. *********************************************************************************************/
  367. void Monitor_Speed(void)
  368. {
  369.     if(MotorRpm < MIN_SPEED)                                                                                                                        /* 檢查電機速度是否過低 */
  370. ……………………

  371. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

下載:
bldc.rar (3.46 KB, 下載次數: 183)

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

使用道具 舉報

沙發
ID:268389 發表于 2018-4-19 21:03 | 只看該作者
正在做相關方向,參考一下,謝謝無私分享
回復

使用道具 舉報

板凳
ID:324611 發表于 2018-7-9 11:00 | 只看該作者
好東西,學習下。
回復

使用道具 舉報

地板
ID:324611 發表于 2018-7-9 11:01 | 只看該作者
正在研究BLCD相關的東西,學習下。
回復

使用道具 舉報

5#
ID:427831 發表于 2018-11-16 17:16 | 只看該作者
led是8位IO口嗎?沒太看懂你的
回復

使用道具 舉報

6#
ID:460143 發表于 2019-1-2 15:43 | 只看該作者
樓主可以提供電路圖嗎?
回復

使用道具 舉報

7#
ID:460143 發表于 2019-1-2 16:15 | 只看該作者
程序中的兩個頭文件在哪里呢?
回復

使用道具 舉報

8#
ID:691135 發表于 2020-2-10 22:51 | 只看該作者
正在做相關方向,參考一下,謝謝無私分享,如果有原理圖配合程序那就更完美了。
回復

使用道具 舉報

9#
ID:967978 發表于 2021-9-28 14:05 | 只看該作者
請問樓主有頭文件嗎?
回復

使用道具 舉報

10#
ID:640527 發表于 2021-10-18 10:45 | 只看該作者
正要做這塊,幫大忙了,非常感謝
回復

使用道具 舉報

11#
ID:194006 發表于 2021-11-27 21:03 | 只看該作者
正在學習無刷驅動,謝謝分享
回復

使用道具 舉報

12#
ID:826226 發表于 2022-1-7 18:14 | 只看該作者
有更完整源碼嗎?
回復

使用道具 舉報

13#
ID:412301 發表于 2023-9-9 15:51 | 只看該作者
配上原理圖就更完善了
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 自拍偷拍精品 | 中文字幕在线免费观看 | 国产精品www | 亚洲成人综合网站 | 国产黄色大片在线免费观看 | 精品一区二区在线观看 | 欧洲一区在线观看 | 日韩欧美在线播放 | 中文字幕在线精品 | 97超碰人人| 天天干天天玩天天操 | av资源中文在线 | 日韩欧美专区 | 黄色网址在线免费观看 | 密色视频| 中文字幕四虎 | 国产情品 | 久久久久久成人 | 成人一级片在线观看 | 国产高清在线精品一区二区三区 | 黄色国产| 日韩久久综合 | 国产伦精品一区二区三区高清 | 日本aaa视频| 欧美成人精品 | 亚洲精品视频一区二区三区 | 久久久综合精品 | 精品一区二区三区在线观看国产 | 国产免费高清 | 国产精品视频综合 | 成人免费看片 | 国产人免费人成免费视频 | 久久精品亚洲成在人线av网址 | 狠狠操天天干 | 国产视频一区二区在线观看 | 欧洲性生活视频 | 久久九精品 | 色天天综合 | 午夜午夜精品一区二区三区文 | 日韩中文字幕一区 | 国产欧美视频一区 |