標(biāo)題: 基于STM32F103的無刷電機(jī)驅(qū)動(dòng)板(包含有霍爾,無霍爾傳感器) [打印本頁]

作者: briltl    時(shí)間: 2019-12-10 12:01
標(biāo)題: 基于STM32F103的無刷電機(jī)驅(qū)動(dòng)板(包含有霍爾,無霍爾傳感器)
本人幾年前開發(fā)個(gè)的一個(gè)基于STM32的無刷驅(qū)動(dòng)板,當(dāng)時(shí)試過,有霍爾,和利用反向電動(dòng)勢的無感啟動(dòng)都是可以的,也可以正常的帶載運(yùn)行。
后來因?yàn)榍袚Q到其他項(xiàng)目,沒有再繼續(xù)優(yōu)化,
但程序的基本框架是正確的,編譯也可完全通過。
發(fā)到網(wǎng)上供大家參考,有疑問的同行可以發(fā)帖相互交流學(xué)習(xí),謝謝!

單片機(jī)源程序如下:


STM32單片機(jī)源程序如下:
  1. #include "includes.h"  

  2. void Motor_Ctr(void);

  3. void send_wave_data(u16 send_data)
  4. {
  5.         usart1_send_byte(0xAA);
  6.         usart1_send_byte(send_data>>8);
  7.         usart1_send_byte(send_data);
  8. }



  9. void Motor_start_param_initial()
  10. {
  11.         MotorCtr.motor_start_delay=MAX_START_DELAY;   //電機(jī)啟動(dòng)參數(shù)初始化,30ms,相當(dāng)于60000/6/2/30=166圈/分鐘       
  12.         MotorCtr.start_step_cn=0;
  13.        
  14.         #ifdef  NO_HOLZER_SENSOR                                            //無霍爾傳感器
  15.        
  16.                 MotorCtr.Holzer_sensor=0;
  17.                 MotorCtr.No_Holzer_sensor_start_count=0;
  18.                 MotorCtr.start_holl_value=2;
  19.         #else                                                //有霍爾傳感器
  20.        
  21.                 MotorCtr.Holzer_sensor=1;
  22.                 MotorCtr.Holzer_sensor_start_count=0;
  23.         #endif               
  24. }       


  25. //電機(jī)控制初始化函數(shù)
  26. void MotorCtr_ini(void)
  27. {
  28.         MotorCtr.sample_ok=0;            //電機(jī)采樣參數(shù)初始化
  29.         MotorCtr.motor_voltage=0;
  30.         MotorCtr.motor_current=0;
  31.        
  32.         MotorCtr.speed_val=0;                        //電機(jī)速度參數(shù)初始化設(shè)定值
  33.         MotorCtr.speed_set=0;                       
  34.         MotorCtr.speed_time_cnt=0;
  35.         MotorCtr.speed_time_ok=0;       
  36.                
  37.         MotorCtr.holl_overtime_cnt=0;
  38.         MotorCtr.holl_cnt=0;
  39.         MotorCtr.sum_holl_time=0;                          
  40.         MotorCtr.sample_ok_cn=0;               
  41.         MotorCtr.stall_time_cn=0;       
  42.        
  43.         MotorCtr.motor_dir= NONE_DIR;                                  //電機(jī)轉(zhuǎn)動(dòng)控制初始化,順時(shí)鐘
  44.         MotorCtr.motor_run_state = MOTOR_IDLE;
  45.        
  46.         Motor_start_param_initial();
  47.        
  48.        
  49.         MotorCtr.motor_run_state=MOTOR_START;
  50.         MotorCtr.motor_dir= FORWARD_DIR;         
  51.         //MotorCtr.motor_dir= REVERSE_DIR;                 
  52.         TIM_Cmd(TIM4, ENABLE);                                          //使能TIM4,開始計(jì)時(shí)間

  53. }


  54. void MOTOR_CMD_process()
  55. {
  56.         if(Usart2Data.Usart_Rx_Data_OK)
  57.         {
  58.                
  59.                 if(Usart2Data.Usart_Rx_Cmd_H==CMD_ORDER)
  60.                 {
  61.                         if(Usart2Data.Usart_Rx_Cmd_L&MOTOR_START)
  62.                         {
  63.                                 Motor_start_param_initial();

  64.                                 MotorCtr.motor_run_state=MOTOR_START;
  65.                                 if(Usart2Data.Usart_Rx_Cmd_L&FORWARD_DIR)
  66.                                 {
  67.                                         MotorCtr.motor_dir= FORWARD_DIR;                 
  68.                                 }
  69.                                 if(Usart2Data.Usart_Rx_Cmd_L&REVERSE_DIR)
  70.                                 {
  71.                                         MotorCtr.motor_dir= REVERSE_DIR;                 
  72.                                 }
  73.                                 TIM_Cmd(TIM4, ENABLE);                                          //使能TIM4,開始計(jì)時(shí)間
  74.                                
  75.                         }
  76.                         else if(Usart2Data.Usart_Rx_Cmd_L&MOTOR_STOP)
  77.                         {
  78.                                 MotorCtr.motor_run_state=MOTOR_STOP;
  79.                                 stop_motor();
  80.                                 TIM_Cmd(TIM4, DISABLE);                                          //使能TIM4,開始計(jì)時(shí)間
  81.                         }                                       
  82.                 }       
  83.                 else if(Usart2Data.Usart_Rx_Cmd_H==CMD_DATA_SPEED)
  84.                 {
  85.                                         MotorCtr.pwm_duty_set=Usart2Data.Usart_Rx_Cmd_L*MIN_START_PWM_DUTY/SPEED_DUTY_NUM;   //速度檔位1-10檔
  86.                 }
  87.                 else if(Usart2Data.Usart_Rx_Cmd_H==CMD_DATA_ANGLE)
  88.                 {
  89.                                        
  90.                 }
  91.                                                                        
  92.                 Usart2Data.Usart_Rx_Data_OK=0;
  93.         }       
  94. }



  95. int main(void)
  96. {         
  97.         RCC_Configuration();  
  98.         IO_Initial();                               //初始化輸入輸出IO口及電平中斷輸入  

  99.         Delay_Initial();                        //用于精確延時(shí)
  100.        
  101.         UART1_Initial(115200);                         //用于調(diào)試
  102.         UART2_Initial(115200);                         //用于調(diào)試
  103.          
  104.         TIM2_Configuration();                    //觸發(fā)采樣,用來設(shè)置ADC采樣率          
  105.         MYDMA_Initial();                                          //ADC配置為DMA傳輸
  106.         ADC_Initial();                                           //充電電流,電池電壓AD輸入初始化
  107.          
  108.         TIM4_Configuration();                    //用于啟動(dòng)延時(shí)
  109.          
  110.         ISR_Initial();                                                  //必須在所有任務(wù)開始運(yùn)行后,開啟中斷初
  111.          
  112.         //TIM3_Configuration();                    //霍爾輸入觸發(fā)配置
  113.         //TIM1_Configuration();                    //6路PWM產(chǎn)生配置,載波頻率為25KHz
  114.        
  115.         MotorCtr_ini();
  116.        
  117.        
  118.         Motor_Ctr();
  119. }                                                            



  120. void Motor_Ctr(void)
  121. {
  122.         while(1)
  123.         {
  124.                 MOTOR_CMD_process();                              //運(yùn)控板命令處理
  125.                
  126.                 if(MotorCtr.sample_ok)
  127.                 {
  128.                     LED_ON=!LED_ON;
  129.                        
  130.                         MotorCtr.sample_ok=0;
  131.                        
  132.                         ADC1_Sample_filter(MotorCtr.sample_ok_cn);
  133.                        
  134.                         MotorCtr.motor_voltage+=single_motor_voltage[MotorCtr.sample_ok_cn];
  135.                         MotorCtr.motor_current+=single_motor_current[MotorCtr.sample_ok_cn];
  136.                        
  137.                         ADC1_sample(ENABLE);
  138.                        
  139.                     MotorCtr.sample_ok_cn++;
  140.                        
  141.                         if(MotorCtr.sample_ok_cn>=SAMPLE_OK_NUM)
  142.                         {
  143.                                 MotorCtr.sample_ok_cn=0;
  144.                                
  145.                                 MotorCtr.motor_voltage/=SAMPLE_OK_NUM;
  146.                                 MotorCtr.motor_current/=SAMPLE_OK_NUM;
  147.                                                       
  148.                                 if(MotorCtr.motor_voltage<BATTERY_MIN_V)                                 //mA,最大可測1.2A  
  149.                                 {
  150.                                        
  151.                                 }
  152.                                 if(MotorCtr.motor_current>MOTOR_STALL_A)                                //A
  153.                                 {
  154.                                        
  155.                                 }

  156.                                 printf("MotorCtr.motor_run_state %d\n",MotorCtr.motor_run_state);
  157.                                               
  158.                                 printf("MotorCtr.motor_voltage %d\n",MotorCtr.motor_voltage);    //mV
  159.                                 printf("MotorCtr.motor_current %d\n",MotorCtr.motor_current);    //mA
  160.                         }
  161.                 }
  162.                
  163.         if(MotorCtr.motor_run_state==MOTOR_START)                                                                //無感啟動(dòng),或有霍爾傳感器啟動(dòng)                                                     
  164.                 {
  165.                         MotorCtr.pwm_duty_set=FIXED_PHASE_PWM_DUTY;                                                   //max 1800       
  166.                         Ctr_Process(MotorCtr.start_holl_value,MotorCtr.motor_dir);                  //轉(zhuǎn)子預(yù)定位
  167.                         delay_ms(100);
  168.                         MotorCtr.start_holl_value=Manu_Ctr_Process(MotorCtr.start_holl_value,MotorCtr.motor_dir);          
  169.                         Ctr_Process(MotorCtr.start_holl_value,MotorCtr.motor_dir);                  //二次定位
  170.                         delay_ms(100);
  171.                         MotorCtr.pwm_duty_set=MIN_START_PWM_DUTY;                                                           //max 1800       
  172.                         MotorCtr.fixed_start_speed_cn=0;                        
  173.                         while(1)
  174.                         {
  175.                                 MotorCtr.start_step_cn++;
  176.                                
  177.                                 Ctr_Process(MotorCtr.start_holl_value,MotorCtr.motor_dir);                                                                  //控制與換相
  178.                                
  179.                                 if(MotorCtr.start_step_cn<=MAX_START_STEP_NUM)                                //啟動(dòng)完畢速度,24步后,換向時(shí)間2.6ms,相當(dāng)于60000/6/2/2.6=1923圈/分鐘       
  180.                                 {
  181.                                         MotorCtr.motor_start_delay=MotorCtr.motor_start_delay*STEP_PWM_DELAY;
  182.                                 }
  183.                                 else
  184.                                 {
  185.                      
  186.                                         if(MotorCtr.fixed_start_speed_cn<FIXED_SPEED_START_NUM)          //加速啟動(dòng)后再,固定速度啟動(dòng)幾步
  187.                                                 MotorCtr.fixed_start_speed_cn++;
  188.                                         else
  189.                                         {
  190.                                                 #ifdef  IO_INT_SENORLESS
  191.                                                         TIM_SetCounter(TIM3,0);
  192.                                                 #endif
  193.                                                
  194.                                                 MotorCtr.motor_run_state = MOTOR_RUN;
  195.                                                 ADC1_sample(ENABLE);                                                                                    //理論上在啟動(dòng)中就要檢測電流大小,進(jìn)行保護(hù),調(diào)試時(shí)跳過
  196.                                                 TIM_Cmd(TIM3, ENABLE);
  197.                                                 MotorCtr.start_step_cn=0;
  198.                                                 break;
  199.                                         }
  200.                                        
  201.                                 }
  202.                                                
  203.                                 if(MotorCtr.Holzer_sensor)                                                                                                                     //有感啟動(dòng),固定霍爾輸入
  204.                                 {
  205.                                         MotorCtr.start_holl_value =0;
  206.                                         MotorCtr.start_holl_value = FHASE_C_IN<<2 | FHASE_B_IN<<1 | FHASE_A_IN<<0;
  207.                                        
  208.                                         if(MotorCtr.Holzer_sensor_start_count<MAX_MOTOR_START_NUM)
  209.                                                 MotorCtr.Holzer_sensor_start_count++;
  210.                                         else
  211.                                         {
  212.                                                 MotorCtr.motor_run_state =MOTOR_STALL;
  213.                                                 motor_brake();
  214.                                         }   
  215.                                 }
  216.                                 else                                                                               //無感啟動(dòng),實(shí)時(shí)讀取霍爾輸入
  217.                                 {
  218.                                         MotorCtr.start_holl_value=Manu_Ctr_Process(MotorCtr.start_holl_value,MotorCtr.motor_dir);          
  219.                                         /*
  220.                                         if(MotorCtr.No_Holzer_sensor_start_count<MAX_MOTOR_START_NUM)
  221.                                                 MotorCtr.No_Holzer_sensor_start_count++;
  222.                                         else
  223.                                         {
  224.                                                 MotorCtr.motor_run_state =MOTOR_STALL;
  225.                                                 motor_brake();
  226.                                         }*/
  227.                                 }
  228.                                 delay_us(MotorCtr.motor_start_delay);
  229.                                
  230.                         }
  231.                 }
  232.                 else if(MotorCtr.motor_run_state == MOTOR_RUN)
  233.                 {
  234.                         if(MotorCtr.speed_time_ok)
  235.                         {
  236.                                 MotorCtr.speed_time_ok=0;
  237.                                 MotorCtr.speed_val=MotorCtr.holl_cnt*SPEED_K;                                             //(MotorCtr.holl_cnt/6步/2對磁極對數(shù))*60=轉(zhuǎn)/min,換向延時(shí) 1000ms*60/轉(zhuǎn)/2對磁極對數(shù)/6步,4000轉(zhuǎn)時(shí),每換向一次1.25ms
  238.                                                                                                                                                                        
  239.                                 MotorCtr.ave_holl_time=HOLL_SPEED_K/(MotorCtr.sum_holl_time/MotorCtr.holl_cnt);
  240.                                
  241.                                 send_wave_data(MotorCtr.speed_val);
  242.                                        
  243.                                 printf("MotorCtr.speed_val %d\n",MotorCtr.speed_val);                              //轉(zhuǎn)/min
  244.                                 printf("MotorCtr.ave_holl_time %d\n",MotorCtr.ave_holl_time);   
  245.                                 //printf("MotorCtr.holl_overtime_cnt %d\n",MotorCtr.holl_overtime_cnt);  
  246.                                 printf("MotorCtr.pwm_duty_set %d\n",MotorCtr.pwm_duty_set);  
  247.                                
  248.                                 MotorCtr.sum_holl_time=0;
  249.                                 MotorCtr.holl_cnt=0;
  250.                        
  251.                         }
  252.                 }
  253.                 else                                                                                                          //MOTOR_STOP
  254.                 {
  255.                         MotorCtr.speed_val=0;
  256.                         MotorCtr.holl_overtime_cnt = 0;
  257.                         MotorCtr.sum_holl_time=0;
  258.                         MotorCtr.holl_cnt=0;
  259.                 }       
  260.         }
  261. }
復(fù)制代碼



全部資料51hei下載地址:
Brushless_Drive_0303.7z (360.09 KB, 下載次數(shù): 699)
原理圖.pdf (45.46 KB, 下載次數(shù): 671)
PCB圖.pdf (2.79 MB, 下載次數(shù): 392)

作者: asdfg221111    時(shí)間: 2019-12-10 17:19
感謝分享
作者: erli122    時(shí)間: 2019-12-10 19:09
很不錯(cuò) 不過 好像挺復(fù)雜
作者: ztsos123    時(shí)間: 2019-12-14 20:20
謝謝分享
     
         

作者: alsdfjiewlkjr56    時(shí)間: 2020-1-5 19:41
下下來看看。正在學(xué)無霍爾的驅(qū)動(dòng),學(xué)習(xí)一下
作者: ZGDE1    時(shí)間: 2020-1-6 15:19
大佬有流程圖嗎?

作者: hellowC8051    時(shí)間: 2020-1-10 09:01
謝謝樓主分享
作者: asdfg221111    時(shí)間: 2020-2-17 14:46
感謝樓主分享
作者: 芯源飛揚(yáng)    時(shí)間: 2020-2-22 22:04
謝謝樓主!下載看看有沒有用!
作者: stiu    時(shí)間: 2020-2-23 17:53
好帖子  謝謝
作者: stiu    時(shí)間: 2020-2-24 11:20
謝謝樓主的分享
作者: zhijie327    時(shí)間: 2020-2-24 14:00
學(xué)習(xí)學(xué)習(xí),謝謝樓主
作者: paomall    時(shí)間: 2020-2-24 14:53
下下來看看。正在學(xué)無霍爾的驅(qū)動(dòng),學(xué)習(xí)一下
作者: hlgchina    時(shí)間: 2020-2-25 09:35
謝謝分享
作者: 起來沒    時(shí)間: 2020-3-15 20:43
謝謝大佬
作者: liup2019    時(shí)間: 2020-3-15 22:41
不錯(cuò),很好的資料!
作者: xuezhiyang123    時(shí)間: 2020-3-18 10:03
正在學(xué)無霍爾的驅(qū)動(dòng),學(xué)習(xí)一下
作者: mamengxiang    時(shí)間: 2020-3-30 10:42
謝謝樓主共享!正在學(xué),謝謝!
作者: lvlv99    時(shí)間: 2020-3-30 23:18
正在學(xué)無霍爾的驅(qū)動(dòng)
作者: 游戲而已    時(shí)間: 2020-3-31 01:10
謝謝樓主分享
作者: waterbaby2011    時(shí)間: 2020-8-6 20:35
資料不錯(cuò),就是扣分太多
作者: waterbaby2011    時(shí)間: 2020-8-25 17:42

謝謝樓主!下載看看有沒有用!
作者: dmtianlang    時(shí)間: 2020-11-16 09:53
正在做這個(gè)驅(qū)動(dòng),學(xué)習(xí)一下!
作者: lhxtzlhxtz    時(shí)間: 2020-12-22 11:04
值得學(xué)習(xí),設(shè)計(jì)得不錯(cuò)。
作者: xuwenhua    時(shí)間: 2021-5-8 10:39
有PCB 的工程文件嗎
作者: luospring    時(shí)間: 2021-5-10 11:12
謝謝了,電壓在多少伏左右?
作者: hfei    時(shí)間: 2021-10-24 15:27
多謝分享,學(xué)習(xí)中。。。,想請教一下,帶載不好啟動(dòng)如何調(diào)整?
作者: vansnee    時(shí)間: 2022-5-24 22:53
感謝,正好可以參考
作者: mtk1625    時(shí)間: 2022-7-13 18:25
哦 原來有原理圖
作者: ttkkxx    時(shí)間: 2022-8-22 13:48
正學(xué)習(xí)BLDC,感謝樓主分享。
作者: lanxichang    時(shí)間: 2022-8-26 18:17
感謝分享,這電容在背面不太好吧? 在同一面會(huì)好安裝一點(diǎn),個(gè)人建議
作者: ustcge    時(shí)間: 2022-9-29 18:46
做個(gè)記號,用的時(shí)候好找
作者: 快樂眼淚    時(shí)間: 2022-10-5 15:08
是不是能用在電動(dòng)自行車上?
作者: liqiangcom    時(shí)間: 2022-10-6 11:39
一個(gè)32IC現(xiàn)在好幾十塊錢了,沒空間了。換國產(chǎn)
作者: tzh_123    時(shí)間: 2022-10-6 12:51
高,能把原理簡述一下,就更好了。畢竟有很多人不了解這個(gè)。
作者: dcc024    時(shí)間: 2022-10-17 08:46
這個(gè)是方波的嗎?如果方波的居逸的容易出成品吧

作者: zoubinbf    時(shí)間: 2023-1-16 10:40
很不錯(cuò) 不過 好像挺復(fù)雜
作者: diyukeji    時(shí)間: 2024-8-1 22:17
下載學(xué)習(xí),謝謝樓主分享
作者: pcf2000    時(shí)間: 2024-9-29 13:38
以前用STC驅(qū)動(dòng)無刷電機(jī),無霍爾,沒有成功,放棄了。。下來學(xué)習(xí)一下
作者: huaishang    時(shí)間: 2025-1-1 09:37

謝謝樓主分享




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1