找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12751|回复: 36
收起左侧

基于STM32F103的无刷电机驱动板(包含有霍尔,无霍尔传感器)

  [复制链接]
ID:659402 发表于 2019-12-10 12:01 | 显示全部楼层 |阅读模式
本人几年前开发个的一个基于STM32的无刷驱动板,当时试过,有霍尔,和利用反向电动势的无感启动都是可以的,也可以正常的带载运行。
后来因为切换到其他项目,没有再继续优化,
但程序的基本框架是正确的,编译也可完全通过。
发到网上供大家参考,有疑问的同行可以发帖相互交流学习,谢谢!

单片机源程序如下:
cc0c55c0a1b4d5afe2d66acb8c0eca2.jpg 79989cce485b470289b957e3c1d6ded.jpg 13150583066a1080e0b95c04fd8647f.jpg

STM32单片机源程序如下:
  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;   //电机启动参数初始化,30ms,相当于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. //电机控制初始化函数
  26. void MotorCtr_ini(void)
  27. {
  28.         MotorCtr.sample_ok=0;            //电机采样参数初始化
  29.         MotorCtr.motor_voltage=0;
  30.         MotorCtr.motor_current=0;
  31.        
  32.         MotorCtr.speed_val=0;                        //电机速度参数初始化设定值
  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;                                  //电机转动控制初始化,顺时钟
  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,开始计时间

  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,开始计时间
  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,开始计时间
  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();                        //用于精确延时
  100.        
  101.         UART1_Initial(115200);                         //用于调试
  102.         UART2_Initial(115200);                         //用于调试
  103.          
  104.         TIM2_Configuration();                    //触发采样,用来设置ADC采样率          
  105.         MYDMA_Initial();                                          //ADC配置为DMA传输
  106.         ADC_Initial();                                           //充电电流,电池电压AD输入初始化
  107.          
  108.         TIM4_Configuration();                    //用于启动延时
  109.          
  110.         ISR_Initial();                                                  //必须在所有任务开始运行后,开启中断初
  111.          
  112.         //TIM3_Configuration();                    //霍尔输入触发配置
  113.         //TIM1_Configuration();                    //6路PWM产生配置,载波频率为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();                              //运控板命令处理
  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)                                                                //无感启动,或有霍尔传感器启动                                                     
  164.                 {
  165.                         MotorCtr.pwm_duty_set=FIXED_PHASE_PWM_DUTY;                                                   //max 1800       
  166.                         Ctr_Process(MotorCtr.start_holl_value,MotorCtr.motor_dir);                  //转子预定位
  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)                                //启动完毕速度,24步后,换向时间2.6ms,相当于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)          //加速启动后再,固定速度启动几步
  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);                                                                                    //理论上在启动中就要检测电流大小,进行保护,调试时跳过
  196.                                                 TIM_Cmd(TIM3, ENABLE);
  197.                                                 MotorCtr.start_step_cn=0;
  198.                                                 break;
  199.                                         }
  200.                                        
  201.                                 }
  202.                                                
  203.                                 if(MotorCtr.Holzer_sensor)                                                                                                                     //有感启动,固定霍尔输入
  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                                                                               //无感启动,实时读取霍尔输入
  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对磁极对数)*60=转/min,换向延时 1000ms*60/转/2对磁极对数/6步,4000转时,每换向一次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);                              //转/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. }
复制代码



全部资料51hei下载地址:
Brushless_Drive_0303.7z (360.09 KB, 下载次数: 656)

评分

参与人数 2黑币 +62 收起 理由
AAA_MCU + 12 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:340339 发表于 2019-12-10 17:19 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:98992 发表于 2019-12-10 19:09 | 显示全部楼层
很不错 不过 好像挺复杂
回复

使用道具 举报

ID:492919 发表于 2019-12-14 20:20 | 显示全部楼层
谢谢分享
     
         
回复

使用道具 举报

ID:627772 发表于 2020-1-5 19:41 | 显示全部楼层
下下来看看。正在学无霍尔的驱动,学习一下
回复

使用道具 举报

ID:682196 发表于 2020-1-6 15:19 | 显示全部楼层
大佬有流程图吗?
回复

使用道具 举报

ID:328121 发表于 2020-1-10 09:01 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:340339 发表于 2020-2-17 14:46 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

ID:295789 发表于 2020-2-22 22:04 | 显示全部楼层
谢谢楼主!下载看看有没有用!
回复

使用道具 举报

ID:638203 发表于 2020-2-23 17:53 | 显示全部楼层
好帖子  谢谢
回复

使用道具 举报

ID:638203 发表于 2020-2-24 11:20 | 显示全部楼层
谢谢楼主的分享
回复

使用道具 举报

ID:686311 发表于 2020-2-24 14:00 | 显示全部楼层
学习学习,谢谢楼主
回复

使用道具 举报

ID:161929 发表于 2020-2-24 14:53 | 显示全部楼层
下下来看看。正在学无霍尔的驱动,学习一下
回复

使用道具 举报

ID:643968 发表于 2020-2-25 09:35 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:709056 发表于 2020-3-15 20:43 | 显示全部楼层
谢谢大佬
回复

使用道具 举报

ID:604109 发表于 2020-3-15 22:41 来自手机 | 显示全部楼层
不错,很好的资料!
回复

使用道具 举报

ID:367149 发表于 2020-3-18 10:03 | 显示全部楼层
正在学无霍尔的驱动,学习一下
回复

使用道具 举报

ID:535167 发表于 2020-3-30 10:42 | 显示全部楼层
谢谢楼主共享!正在学,谢谢!
回复

使用道具 举报

ID:240034 发表于 2020-3-30 23:18 | 显示全部楼层
正在学无霍尔的驱动
回复

使用道具 举报

ID:719220 发表于 2020-3-31 01:10 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:135281 发表于 2020-8-6 20:35 | 显示全部楼层
资料不错,就是扣分太多
回复

使用道具 举报

ID:135281 发表于 2020-8-25 17:42 | 显示全部楼层

谢谢楼主!下载看看有没有用!
回复

使用道具 举报

ID:92520 发表于 2020-11-16 09:53 | 显示全部楼层
正在做这个驱动,学习一下!
回复

使用道具 举报

ID:639666 发表于 2020-12-22 11:04 | 显示全部楼层
值得学习,设计得不错。
回复

使用道具 举报

ID:88896 发表于 2021-5-8 10:39 | 显示全部楼层
有PCB 的工程文件吗
回复

使用道具 举报

ID:4294 发表于 2021-5-10 11:12 | 显示全部楼层
谢谢了,电压在多少伏左右?
回复

使用道具 举报

ID:419063 发表于 2021-10-24 15:27 | 显示全部楼层
多谢分享,学习中。。。,想请教一下,带载不好启动如何调整?
回复

使用道具 举报

ID:760761 发表于 2022-5-24 22:53 | 显示全部楼层
感谢,正好可以参考
回复

使用道具 举报

ID:184706 发表于 2022-7-13 18:25 | 显示全部楼层
哦 原来有原理图
回复

使用道具 举报

ID:455220 发表于 2022-8-22 13:48 | 显示全部楼层
正学习BLDC,感谢楼主分享。
回复

使用道具 举报

ID:95059 发表于 2022-8-26 18:17 | 显示全部楼层
感谢分享,这电容在背面不太好吧? 在同一面会好安装一点,个人建议
回复

使用道具 举报

ID:638714 发表于 2022-9-29 18:46 | 显示全部楼层
做个记号,用的时候好找
回复

使用道具 举报

ID:399179 发表于 2022-10-5 15:08 来自手机 | 显示全部楼层
是不是能用在电动自行车上?
回复

使用道具 举报

ID:418515 发表于 2022-10-6 11:39 | 显示全部楼层
一个32IC现在好几十块钱了,没空间了。换国产
回复

使用道具 举报

ID:1002058 发表于 2022-10-6 12:51 | 显示全部楼层
高,能把原理简述一下,就更好了。毕竟有很多人不了解这个。
回复

使用道具 举报

ID:216265 发表于 2022-10-17 08:46 | 显示全部楼层
这个是方波的吗?如果方波的居逸的容易出成品吧
回复

使用道具 举报

ID:1033997 发表于 2023-1-16 10:40 | 显示全部楼层
很不错 不过 好像挺复杂
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表