• 好盈无刷电调驱动-stm32与arduino控制电调电调驱动原理以及试验,附源码与试验结果。

    好盈无刷电调驱动-stm32与arduino控制电调

    电调驱动原理以及注意事项

    原理:
    电调每次上电(电调由板子供电),即板子每次启动,都要给电调设置油门行程:最高油门与最低油门,方式是:调制一个占空比高一点pwn波设置最高油门与调制一个占空比低一点pwn波设置最低油门,这里的占空比是指一个pwn周期内高电平持续的时间,即高电平脉宽。
    电调图为:
    在这里插入图片描述在这里插入图片描述
    6V/5A:电调输出电压是6v,即电调的vcc与gen之间为6v,5A不知道啥意思
    2-6S Lipo是指2到6个锂电池(大概3.7V,具体百度)
    P:pwn输入
    R:6V输出
    G:地线
    电路图如下:
    在这里插入图片描述一个12V的铅酸蓄电池+一个arduino MEGA 2560(stm32)+电调+电机,接线的时候注意电调输出的三相不要接触(图中用红色胶布绝缘),电调的三个引脚中只有P与G接板子引脚,不要搞错了!!!
    操作方式与现象:
    1、打开电调电源开关,使得电路导通;
    2、打开单片机开关
    3、电调与电机发出两声短的“”滴”~“”滴”,在发出一声长的滴,油门行程设置完成;
    4、单片机给一个油门控制信号(代码中写好的),电机转动。

    注意事项:
    1、设置油门行程与操控油门时,pwn波频率为50HZ,即周期为20ms;
    2、设置油门行程与操控油门时,不是调制pwn波输出电压,而是调制pwn一个周期内(这里为20ms)中高电平持续的时间,这里一定要切记,作者在这里被坑了;
    3、油门行程一旦设置好了,只要电调的控制线,即P与G之间信号一直有,电调的电源通与不通都没有影响,比如说:先设置好了油门行程、然后把电调电源线断开,此时如果单片机不掉电的话,重新给电调接上电源线,此时单片机不需要再设置油门行程,直接给一个油门控制信号就可以让推进器转动;
    4、推进器速度大小控制:给定一个在油门行程中的脉宽,脉宽越大,速度越快,脉宽越小,速度越小,如何使得控制推进器速度更加平滑,需要多次测试。

    arduino控制电调

    我用的是arduino MEGA 2560
    这里参考了Mr.forgetful的博客:https://blog.csdn.net/weixin_43426470/article/details/89415726,感谢大佬!
    代码如下:

    void setup(){
      pinMode(9,OUTPUT);//选取9号引脚接电调信号线
    
      /*油门行程校准(i<=1000时,整个循环用时3-4秒)*/
      
      //该循环运行时会伴有“哔-哔-”油门最高点确认音
      for(int i=0;i<=1000;i++){
      digitalWrite(9,HIGH);
      delayMicroseconds(2000);//高电平持续2000微秒(油门最高点,脉宽为2毫秒)
      digitalWrite(9,LOW);
      delayMicroseconds(18000);}
    
      //该循环运行时会伴有N声短鸣声(表示锂电池节数)和“哔-”油门最低点确认音
       for(int i=0;i<=1000;i++){
      digitalWrite(9,HIGH);
      delayMicroseconds(1000);//高电平持续1000微秒(油门最低点,脉宽为1毫秒)
      digitalWrite(9,LOW);
      delayMicroseconds(19000);
        }
        
     
      /*现在可以加大高电平持续时间,即加大油门,实现电机的启动  */
      //该循环运行的时间即电机低速转动的时间,进一步证明了i<=1000时,整个循环用时3-4秒
      for(int i=0;i<=1000;i++){
      digitalWrite(9,HIGH);
      delayMicroseconds(1100);//油门1100
      digitalWrite(9,LOW);
      delayMicroseconds(18900);
        }
      }
      
      //loop()函数使油门保持在1600
      void loop(){
      for(int i=0;i<=1000;i++){
      digitalWrite(9,HIGH);
      delayMicroseconds(1600);
      digitalWrite(9,LOW);
      delayMicroseconds(18400);
        }  
        }
    

    这里的for循环内部就是一个周期了,可以看到这里电调的频率是50HZ,周期是20ms,最大油门2ms,最小油门1ms,下面是我测得的高电平脉宽-输出电压-速度表:
    高电平持续时间 pwn输出电压 速度
    1100 1.50 慢
    1150 1.57
    1200 1.60
    1250 1.65
    1300 1.70
    1350 1.78 较快
    1400 1.84
    1450 1.91
    1500 2.04 快
    ≥1500 没测试 估计很快

    stm32控制电调

    代码如下:

    int main(void)
     {		
    	delay_init();	    	 //延时函数初始化   
    	 TIM4_PWM_Init();    //定时器初始化 周期为20ms
    	 delay_ms(2000);	   //延时2s
    	 TIM_SetCompare1(TIM4, 320);   //设置最高油门 脉宽3.2 ms
    	  delay_ms(20000);    //延时2s
          delay_ms(20000);  //延时2s
    	 TIM_SetCompare1(TIM4, 90);  //设置最低油门 脉宽0.9 ms
    	  delay_ms(20000);    //延时2s
    	  delay_ms(20000);    //延时2s
    
       	while(1)
    	{
    	    TIM_SetCompare1(TIM4, 140);//设置油门 脉宽1.4 ms,此时推进器按照一定速度转动
    	}	 
     }
    

    源代码链接下载:
    链接:https://pan.baidu.com/s/1syOTvJleUZ-gDtnlHwW-Sg
    提取码:ggzf

    电调的P与G分别接stm的Pin_12与Pin_13,电调驱动放在真实的项目中的话,需要将上述设置油门代码写成一个函数,在main函数GPIOinit之后就马上调用,之后不在设置油门行程,就可以直接设置推进器速度。

    展开全文
  • 电调控制无刷电机制作遥控飞艇 蓝牙控制 调控电调 无刷电机 用电调控制无刷电机制作遥控飞艇 代码区 mian.c #include "delay.h" #include "sys.h" #include "usart.h" #include "usart3.h" #include "timer.h" #...

    用电调控制无刷电机制作蓝牙遥控飞艇

    【注:学习STM32总结做的笔记,大神勿喷。有不足之处还望不吝赐教,谢谢。工程代码在最后。】

    蓝牙控制 调控电调 无刷电机 STM32F103单片机 用电调控制无刷电机制作蓝牙遥控飞艇

    这是队友在某宝上买的无刷电机和电调,因为比赛需要,做了条飞艇出来。由于无刷电机质量问题(划重点),导致比赛失了败。
    在这里插入图片描述
    其实做出来是挺简单的,就是驱动电调去控制无刷电机,对于一些刚接触电调、无刷电机的人来说,有一定的难度(网上的教程很多,但很多都说得不明不白的)。下面我就完整的把我的讲一下吧,有不对的地方可以指出来,还望勿喷。

    说之前还是要强调一下
    注意事项:
    1.调试要看紧点电机(安全问题,防止浆翼打伤手,能拿掉浆翼就拿掉)
    2.防水措施一定要做好,不然进水会烧掉电路
    3.电调要跟无刷电机接对线(电机有正反浆,接错会打转,或者不动。。电调只会往一个方向给信号)
    4.船模设计要合理,要考虑船的承载能力和水位,不然飞艇会成潜艇(船头要轻,浮起来。不然前面太重,后面推动,飞艇还会成潜艇)
    5.我这款无刷电机能下水,做船的建议电机浆翼到水就好(倾斜对水),不要整只下到水,阻力太大船就没动力了。
    6.这些都是意见与经验之谈,觉得有用的就用。

    我用的单片机是STM32F103电调是好盈的(HOBBYWNG)(材料型号规格要按实际要求选择,还要看它的说明书)无刷电机是三线的(不懂可百度)。
    接线问题:黑线接GND(一定要和单片机共地接),红线接+5v(不接也没问题,还是建议接上),白线(信号线)接输出PWM的管脚另外两条粗粗的红黑线–自然是接电池电源

    下图是电调的说明
    在这里插入图片描述电调说明也可以参考这位博主的文章:https://blog.csdn.net/CalShell/article/details/44424347

    电调驱动
    驱动电调关键就是PWM频率,有的人用50Hz的PWM能驱动电调,也有的人用500Hz能驱动电调。这个要具体看电调的要求,以及PWM的输出(PWM设置分不分频会影响PWM的计数快慢,从而影响电调的控制),我下面的pwm设了分频,不理解PWM分不分频的可自行百度。如果按照我的这组数(1999,71)调不通,可以或者不分频多改改测测,接着就是解锁电调,电调第一次使用要设置量程,然后接上线就能动了,就是这么简单。
    我这电调驱动的值在(5—500),5—速度最大;500—速度最小,无刷电机停止

    TIM3_PWM_Init(1999,71);	 //不要问我怎么来的,这个数值的PWM频率是我测出来的((1999,71)这组数不唯一)。具体可以去理解一下PWM频率怎么计算	 
    /*/////////////////////解锁电调////////////////////*/	 
    /*电调第一次使用要设置量程,解锁两个电调步骤,先拉到最高油门,再拉到最低油门,这一步电机会动,一定要注意安全*/
    TIM_SetCompare2(TIM3,10);
    TIM_SetCompare3(TIM3,10);
    delay_ms(1000);  //先延时
    TIM_SetCompare2(TIM3,500);
    TIM_SetCompare3(TIM3,500);	 
    delay_ms(10);		//再延时
    /*/////////////////////解锁电调////////////////////*/
    

    在这里插入图片描述

    电调PWM信号输出–示波器

    电调驱动电机–第一次解锁和高速运行时的信号输出
    在这里插入图片描述
    电调驱动电机–电机停止时的信号输出
    在这里插入图片描述

    我做的飞艇用了三个电机–正反浆电机、加速喷水电机。正反浆无刷电机–控制前进左右方向,加速喷水电机–备用动力(终点快人一步)。

    L298N驱动加速喷水电机就不多做解释了,接线如下图,代码也在最下面了。
    接线图
    在这里插入图片描述

    调测–成品图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    代码区

    mian.c

    #include "delay.h"
    #include "sys.h"
    #include "usart.h"
    #include "usart3.h" 
    #include "timer.h"
    	
     int main(void)
     {		
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级  
    
    	uart_init(115200);	 //串口初始化为115200	 
    	usart3_init(9600);//蓝牙的串口初始化 注意手机与单片机的蓝牙连接波特率是要9600	 
    	TIM3_PWM_Init(1999,71);	 //不要问我怎么来的,这个数值的PWM频率是我测出来的。具体可以去理解一下PWM频率怎么计算
    	 
    /********************解锁电调**********************/
    /*电调第一次使用要设置量程,解锁两个电调步骤,先拉到最高油门,再拉到最低油门,这一步电机会动,一定要注意安全*/
        TIM_SetCompare2(TIM3,10);
    	TIM_SetCompare3(TIM3,10);	 
    	delay_ms(1000);  //先延时
    	TIM_SetCompare2(TIM3,500);
        TIM_SetCompare3(TIM3,500);
      delay_ms(10);		//再延时
    /********************解锁电调**********************/		 
    	 while(1)
    	{
    	
    		if(USART3_RX_STA&0x8000)
    		 {
    	 
    		 if(USART3_RX_BUF[0]=='l')//前进
    				{			 			 
    				 TIM_SetCompare2(TIM3,10);//电机1全速前进
    				 TIM_SetCompare3(TIM3,10);//电机2全速前进		 
    			  }
    		 if(USART3_RX_BUF[0]=='h')//停止
    			   {			 		 
    			  	TIM_SetCompare2(TIM3,500);//电机1停止
    			  	TIM_SetCompare3(TIM3,500);//电机2停止				
    			   }
    		  if(USART3_RX_BUF[0]=='z')//左转
    			    {
    			      TIM_SetCompare2(TIM3,100);//电机1减速
    				  TIM_SetCompare3(TIM3,400);//电机2全速
    			    }
    			if(USART3_RX_BUF[0]=='y')//右转
    			    {
                    TIM_SetCompare2(TIM3,400);//电机1全速				 
                    TIM_SetCompare3(TIM3,100);//电机2减速  
    			    }
    			if(USART3_RX_BUF[0]=='q')//备用电机启动
    			    {
                   TIM_SetCompare4(TIM3,10);//备用电机全速
    			    }
    			if(USART3_RX_BUF[0]=='t')//备用电机停止
    			    {
                   TIM_SetCompare4(TIM3,1999);//备用电机停止			  
    			    }
    								 			 
    			 USART3_RX_STA=0;//清空接收标记
    		 }
    							
    	}	
    		 
     }
    

    timer.c

    #include "timer.h"
      	  
    //通用定时器3中断初始化
    //这里时钟选择为APB1的2倍,而APB1为36M
    //arr:自动重装值。
    //psc:时钟预分频数
    //这里使用的是定时器3!
    void TIM3_Int_Init(u16 arr,u16 psc)
    {
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	NVIC_InitTypeDef NVIC_InitStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
    
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到5000为500ms
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 
    	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
    
    	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
    
    	TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
    							 
    }
    //定时器3中断服务程序
    void TIM3_IRQHandler(void)   //TIM3中断
    {
    	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
    		{
    		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 
    		LED1=!LED1;
    		}
    	
    }
    
    //TIM3 PWM部分初始化 
    //PWM输出初始化
    //arr:自动重装值
    //psc:时钟预分频数
    //PB5------TIM_SetCompare2------左边电机
    //PB0------TIM_SetCompare3------右边电机
    //PB1------TIM_SetCompare4------加速喷水电机
    void TIM3_PWM_Init(u16 arr,u16 psc)
    {  
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	//使能定时器3时钟
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
    	
    	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5     
       //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形	GPIOB.5
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_5; //TIM_CH2
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
    	GPIO_ResetBits(GPIOB,GPIO_Pin_1); 	//PB1要拉低,因为芯片默认高电平,而L298N一个脚接地,会形成回路,电机就默认驱动了的
    	
       //初始化TIM3
    	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    	
     	//初始化TIM3 通道2 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
    	
    	 	//初始化TIM3 通道3 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
    
    	 	//初始化TIM3 通道4 PWM模式	 
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    	TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
    	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
    
    	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
    	
    }
    

    timer.h

    #ifndef __TIMER_H
    #define __TIMER_H
    #include "sys.h"
    
    void TIM3_Int_Init(u16 arr,u16 psc);
    void TIM3_PWM_Init(u16 arr,u16 psc);
    #endif
    
    

    蓝牙部分
    usart3.c

    #include "sys.h"
    #include "usart3.h"
    
    u8 USART3_RX_BUF[USART3_REC_LEN]; //数组用来存储接收到的数据,而USART3_REC_LEN为最多能接收的字节限度
    u16 USART3_RX_STA=0;         		//接收状态标记	 0-14位为接收字节数,15位接收完成标志位
    
    void usart3_init(u32 bound)
    { 
    	  GPIO_InitTypeDef GPIO_InitStructure;
    	  NVIC_InitTypeDef NVIC_InitStructurea;
    	  USART_InitTypeDef USART_InitStruct;
    	 
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能串口3
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB
    	USART_DeInit(USART3);//串口3复位 不是必要的一步
    	
    	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
    	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	  GPIO_Init(GPIOB,&GPIO_InitStructure);    //PB10设置为复用推挽输出
    
    	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
    	  GPIO_Init(GPIOB,&GPIO_InitStructure);  //PB11设置为浮空输入	 
      
    	  NVIC_InitStructurea.NVIC_IRQChannel=USART3_IRQn;
    	  NVIC_InitStructurea.NVIC_IRQChannelCmd=ENABLE;
    	  NVIC_InitStructurea.NVIC_IRQChannelPreemptionPriority=2;
    	  NVIC_InitStructurea.NVIC_IRQChannelSubPriority=2;
    	  NVIC_Init(&NVIC_InitStructurea);          //串口3中断的设置
    		
    		USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//串口3中断使能和中断类型设置
    	    USART_InitStruct.USART_BaudRate=bound;//串口波特率
    		USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制
    		USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Rx;//收发模式
    		USART_InitStruct.USART_Parity=USART_Parity_No;//无奇偶校验位
    		USART_InitStruct.USART_StopBits=USART_StopBits_1;//一个停止位
    		USART_InitStruct.USART_WordLength=USART_WordLength_8b;//字长为8位数据格式
    	    USART_Init(USART3,&USART_InitStruct);                 //串口3的一些参数设置		
    		USART_Cmd(USART3,ENABLE);//串口3使能
    		  
    }
    void USART3_IRQHandler()//串口3的中断
    { 
    	 u8 res;//暂时缓存接收的数据
       if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)//判断是否为串口3接收中断
    	 {
    		   
    	      res=USART_ReceiveData(USART3);//接收到数据放进res
    		   USART3_RX_BUF[USART3_RX_STA&0x7FFF]=res;//数据放进数组中,则可以用到main函数中了
    		   USART3_RX_STA++;                         //字节长度++
    		   if(USART3_RX_STA>(USART3_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收	+; 
    		   USART3_RX_STA|=0x8000;//串口3接收完成
    		   USART_ClearITPendingBit(USART3,USART_IT_RXNE);//清除接收中断标志
    		   
    	  }
    }
    
    
    

    usart3.h

    #ifndef USART3_H_
    #define USART3_H_
    
    #include "sys.h"
    #include "stdio.h"	
    
    #define USART3_REC_LEN  200  	//定义最大接收字节数 200
    
    extern u8  USART3_RX_BUF[USART3_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节
    extern u16 USART3_RX_STA;         		//接收状态标记	 0-14位为接收字节数,15位接收完成标志位
    void usart3_init(u32 bound);
    #endif
    
    

    【注:文件源码是Keil uVision5–STM32工程文件】
    参考文件源码下载链接:
    https://download.csdn.net/download/qq_28056277/11232414
    原创文章,转载请注明出处,谢谢。

    展开全文
  • 新西达电调 hw30a 51单片机驱动无刷电机程序 里面有注释,通过两个按钮控制油门的增减
  • 本代码,实现用51单片机控制电调驱动无刷电机。可粘贴到keil再用。
  • 32单片机控制电调

    2019-04-20 15:58:21
    通过32单片机输出特定pwm波,驱动电调进而控制推进器。 对于单个的推进器进行控制,有时候数据手册提供的控制条件范围不准确; 明确速度变化pwm波的输出区间; 整体程序编写。 推进器的选取,如图1所示推进器型号...

     

    通过32单片机输出特定pwm波,驱动电调进而控制推进器。

    1. 对于单个的推进器进行控制,有时候数据手册提供的控制条件范围不准确;
    2. 明确速度变化pwm波的输出区间;
    3. 整体程序编写。

    推进器的选取,如图1所示推进器型号为T200水下推进器,图2为此次使用电调,资料在对应论坛下载http://forum.bluerobots.cn/t/topic/261下载。

     

                                                                              图1 T200推进器 

                                                                             图2 ESC30电调 

     电调一般是需要特定的频率波形才能进行驱动。32产生pwm波可以自己设定定时器模拟,也可以进行库里面的pwm波通道输出。

    (1) 主函数代码(测试用,通过按键逐步增加占空比)

    int main(void)
     {        
         u16 led0pwmval=0;
        int dir=0;              
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
        uart_init(115200);    //串口配置
         LED_Init();               
         KEY_Init();    //按键初始化
         TIM3_PWM_Init(19999,71); //输出制定的电调要求的50HZ频率波        
           while(1)
        {                                     
      
        switch(KEY_Scan(0))
            {
                case 1:
                {
                    dir++;
                    TIM_SetCompare2(TIM3,1100+100*dir);//根据资料数据提供
                    USART_SendData(USART1,'2');//为了便于检测是否按键执行正确,其实是通过看有几个2来确定输出的占空比
                }   break;
                default:break;
            }            
        }    
        
     }

    (2)按键检测(直接用的正点原子的,象征性的贴出代码)

    u8 KEY_Scan(u8 mode)
    {     
        static u8 key_up=1;//
        if(mode)key_up=1;  //     
        if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
        {
            delay_ms(10);//
            key_up=0;
            if(KEY0==0)return KEY0_PRES;
            else if(KEY1==0)return KEY1_PRES;
            else if(KEY2==0)return KEY2_PRES;
            else if(WK_UP==1)return WKUP_PRES;
        }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;         
         return 0;// 
    }

    (3) PWM波输出配置

    void TIM3_PWM_Init(u16 arr,u16 psc)
    {  
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    //
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //
        
        GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //  
     
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
     
       //TIM3
        TIM_TimeBaseStructure.TIM_Period = arr; //
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //
        
        //TIM3 Channel2 PWM 
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);  
        
        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //
        TIM_Cmd(TIM3, ENABLE); 
    }

    (4)而后不确定的就可以先通过示波器看输出的pwm波的频率与占空比是否正确,通过论坛资料吧输出的高电平需要为3.3V,在接推进器时,实现进行板子pwm输出测试,如图3所示。

                                                                    (a)输出电平 

                                                                    (b)输出占空比情况 

                                                                           图3 测试情况

    在测试时,我设置的基PWM高电平时间为1100us,通过按键当PWM高电平时间为1600us时,推进器运行。在高电平时间为1400时,推进器第二次声响,但是没有转动,当为1600us时启动。

    待更新中。。。1.19

     

    添加一位同学的补充:

    2019.4.20

     

    展开全文
  • 基本原理单片机发送一定频率和脉宽范围的PWM给电调电调根据脉宽和设置控制电机。好盈电调说明书如何操作 连接电调黑色线同单片机接地,除红色黑色外另外一根线,一般是白色,接你输出PWM的IO口,可以是硬件PWM,也...

    基本原理

    单片机发送一定频率和脉宽范围的PWM给电调,电调根据脉宽和设置控制电机。

    好盈电调说明书

    如何操作

    • 连接

      电调黑色线同单片机接地,除红色黑色外另外一根线,一般是白色,接你输出PWM的IO口,可以是硬件PWM,也可以使自己用定时器模拟PWM。

    • 设置电调

      油门的设置

      按照说明书操作,我们要先给电调发送一个高的油门,也就是对电调输出你所要设置的最大油门对应的PWM脉宽,这里要注意,电调关注的是脉宽,也就是高电平的时长,PWM的频率一般设置为50Hz左右就比较合适,一般我们脉宽的范围设置为1000us~2000us,对应电机的最小和最大油门。如说明书所说,油门最高点即输出PWM脉宽为2000us,油门最低点输出PWM脉宽为1000us,照说明书操作即可,这里要注意安全,最好不要让电机带桨,以免受伤。

    • 正常启动

      正常启动

      同理,向电调输出脉宽最小的PWM(这里是1000us),持续一定的时长,等待其完成自检,如说明书所说,即可增大PWM脉宽启动电机。

    展开全文
  • BLheli 电调大家都在使用,尤其在穿越机上更是遍地开花,因此博主准备写一下这几天对于BLheil电调的相关制作经验。 博主玩了一年航模,一直走改装和自制路线,目前接收机遥控器已经趋于稳定,航模遥控技术也突飞猛进...

    前言

    BLheli 电调大家都在使用,尤其在穿越机上更是遍地开花,因此博主准备写一下这几天对于BLheil电调的相关制作经验。
    博主玩了一年航模,一直走改装和自制路线,目前接收机遥控器已经趋于稳定,航模遥控技术也突飞猛进,于是阻拦博主继续嗨皮的有四大难题(主要是穷
    1、电池(博主购买了一批拆机的汽车应急点火电池,改装了不少2-4S电池,于是不愁电池)
    2、电机(博主掏了一堆大疆二手拆机无刷电机各种型号都有,以及闲鱼收一些损坏的电机翻修)
    3、舵机(淘宝有不少工厂尾货舵机,经过测试比较好用,三四块钱一个)
    4、电调(电调得用好的,而且普遍价格偏高,更主要涉及博主本专业,于是准备做个玩玩)
    BLheli电调是什么博主不再赘述,只要知道他的固件和相关信息都是开源的就行,具体地址:
    可以自行下载BLheli电调开源资料
    博主研究了BLheli电调的两个板本c8051F330和EFM8BB21F16G
    其中EFM8BB21F16G 主要用于多旋翼电调
    c8051F330可以作为多旋翼,固定翼,直升机尾桨,本文重点讲c8051F330的版本。

    一、C8051F330芯片引脚介绍

    C8051F330是一个8051内核的8位单片机,其内部资源也很有限,其价格也很是友好,制作起来成本也比较低。
    C8051F330电调大部分采用的QFN20封装。
    c8051f330

    其中P2.0和RST作为程序烧写口,他的最小系统电路如下:
    最小系统
    博主专门制作了一个小核心板用于测试固件:
    C8051F330

    二、XP-12A硬件案例分析

    	博主主要测绘了一下XP-12A小电调的电路。
    	这个电调长这样子:
    

    背面:在这里插入图片描述
    正面在这里插入图片描述
    通过C2接口读出其固件是XP12A,因此博主准备用设计的核心板和电调驱动板简单搭建一个XP12A电调。读取后软件界面如下图:
    在这里插入图片描述
    经过测绘和查阅XP12A的引脚定义文档发现其引脚功能如下:
    XP12A引脚定义文档位置:BLHeli-master\BLHeli-master\SiLabs\XP_12A.inc 可以用记事本打开查看。因为篇幅原因博主只摘出关键信息供大家参考:

    $include (c8051f330.inc)芯片型号
    
    ;**** **** **** **** ****
    ; Uses internal calibrated oscillator set to 24Mhz
    ;**** **** **** **** ****
    
    ;*********************
    ; PORT 0 definitions *     P0口相关定义
    ;*********************  
    Rcp_In		EQU	7	;i      PWM信号口
    Adc_Ip		EQU	6	;i      电池电压检测口
    Mux_A		EQU	5	;i      电机A反电动势
    ;			EQU	4	;i          未定义
    Mux_B		EQU	3	;i      电机B反电动势
    Comp_Com		EQU	2	;i   反电动势公共口
    Mux_C		EQU	1	;i      电机B反电动势
    Vref			EQU	0	;i      未知
    
    ;*********************
    ; PORT 1 definitions *P1口定义
    ;*********************
    ;			EQU	7	;i   未知
    ;			EQU	6	;i    未知
    ApFET		EQU	5	;o上桥A导通信号
    BpFET		EQU	4	;o上桥B导通信号
    CpFET		EQU	3	;o上桥C导通信号
    AnFET		EQU	2	;o下桥A导通信号
    BnFET		EQU	1	;o下桥B导通信号
    CnFET		EQU	0	;o下桥C导通信号
    
    MACRO AnFET_on   
    	setb	P1.AnFET    下管高电平导通
    ENDM
    MACRO AnFET_off
    	clr	P1.AnFET  下管低电平关闭
    ENDM
    MACRO BnFET_on
    	setb	P1.BnFET  下管高电平导通
    ENDM
    MACRO BnFET_off下管低电平关闭
    	clr	P1.BnFET
    ENDM
    MACRO CnFET_on
    	setb	P1.CnFET  下管高电平导通
    ENDM
    MACRO CnFET_off下管低电平关闭
    	clr	P1.CnFET
    ENDM
    MACRO All_nFETs_Off  下管低电平全关
    	clr	P1.AnFET
    	clr	P1.BnFET
    	clr	P1.CnFET
    ENDM
    
    MACRO ApFET_on   
    	setb	P1.ApFET上管高电平导通
    ENDM
    MACRO ApFET_off
    	clr	P1.ApFET
    ENDM
    MACRO BpFET_on
    	setb	P1.BpFET上管高电平导通
    ENDM
    MACRO BpFET_off
    	clr	P1.BpFET
    ENDM
    MACRO CpFET_on
    	setb	P1.CpFET上管高电平导通
    ENDM
    MACRO CpFET_off
    	clr	P1.CpFET
    ENDM
    MACRO All_pFETs_Off
    	clr	P1.ApFET
    	clr	P1.BpFET
    	clr	P1.CpFET
    ENDM
    
    MACRO Brake_FETs_On	 高电平刹车
    	AnFET_on
    	BnFET_on
    	CnFET_on
    ENDM
    
    ;*********************
    ; PORT 2 definitions * p2口定义
    ;*********************
    DebugPin		EQU	0	;o//仿真口
    
    P2_PUSHPULL	EQU	(1 SHL DebugPin)
    

    查看该文档需要注意的有以下几点:
    1、查看单片机型号,BLheli固件有很多单片机,不一定都是F330。
    2、引脚定义,那个引脚接那个信号线。
    3、MOS管的驱动逻辑,有的固件上下桥的导通逻辑不一样,硬件上做了反相器,所以大家要看清,这要和硬件配合使用。

    知道了引脚定义下来主要说硬件电路。

    三、硬件电路

    1、反电动势采集

    经过测绘其反电动势采集图如下:
    在这里插入图片描述

    2、电池电压反馈

    在这里插入图片描述

    3、PWM输入

    在这里插入图片描述

    4、电桥驱动

    电桥驱动方案很多,有的采用N-Pmos搭配驱动,有的纯NMOS,各有利弊,小电流电调都采用的NP搭配,大电流的采用Nmos。
    XP12A采用的就是NP搭配的情况,经过测绘,下桥的N管的G极直接接的单片机引脚,而上桥的P管栅极采用一个三极管做驱动,引出可以看出来上下桥都是高电平导通,低电平关断,其原理图如下:
    在这里插入图片描述
    而采用全N管时就需要做电桥驱动,航模电调大部分才用的电桥驱动芯片是FD6288,其线路如下图:
    在这里插入图片描述
    MOS连接图如下:
    在这里插入图片描述
    通过分析此图其实不难发现全N管驱动方式上下桥都是高电平驱动,所以大家采用其他固件时一定要注意硬件和软件逻辑的配合。

    四、博主测试的硬件图

    博主前段时间在某宝上买了个拆机电桥板,发现铝基板上贴了7片IPB160N04S4,实在太赞了
    在这里插入图片描述
    于是博主专门为其设计了一个驱动板:
    在这里插入图片描述
    最后的测试图:
    在这里插入图片描述
    博主用一个70涵道进行暴力测试,还是很带劲的。
    最后奉送大家我的测试电路原理图:
    在这里插入图片描述
    此图就是上图的驱动板,喜欢的朋友可以拿去测试。
    下期主要说一下EFM8BB21F16G 单片机电调以及BLheil suite的简单用法及固件烧录方法。

    展开全文
  • 最近刚接触四旋翼,主控用的是瑞萨的RX23T系列,表示以前从来没有接触过瑞萨的单片机,所以拿到手一脸的懵逼。在我好不容易搞懂了开发环境的使用,把在某宝上寻得的资料烧写到单片机上,期待电机嗡嗡转起来,可是只...
  • 自编 好赢电调 hw30a 51单片机驱动程序,可以驱动a2212/10t无刷电机。具体设置请参考好赢电调设置说明书。
  • 使用iap-15w58s4k控制,解锁好盈电调,并75的油门
  • 单片机驱动新西达30A 电调
  • c51单片机控制好盈新西达电调电机按键和非按键版本
  • ST电调方案

    2020-07-02 19:42:19
    ST官方基于STM32F030的电调方案,包含原理图
  • 后来发现不是这样,上网查资料的时候发现我们买回来电调之后没有调节它的油门行程就直接用了,这造成了两个电调参数的不对称。 而关于油门行程的调节,网上相关资料都感觉说的不是很清楚,我琢磨了好久才弄明白这个...
  • 新西达电调设置选项说明书
  • 话不多说直接上图: 使用的是89c52rc单片机电调驱动使用50~500Hz的脉冲 , 我用的400Hz脉冲 P2.0作为输出,电调驱动脉冲高电平时间0.7~1.9ms , 开始做一个油门行程,输出1.9ms高电平脉冲,听到电机“哔哔”两声...
  • 2、新西达30A电调 3、2212 920KV自锁无刷电机 4、STM32F103C8T6最小系统板 连线: PA0输出PWM连接电调的白色线 软件: TIM2_PWM_Init(1999,719);//占空比最大2000,50HZ TIM_SetCompare1(TIM2,200);//脉宽2ms ...
  • 电调的一些程序设计。电调 单片机程序 avr m8的 c语言写的。(转)
  • 2019独角兽企业重金招聘Python工程师标准>>> ...
  • 自制_夹心_无刷电调 (C8051F330单片机 + IR2103 + 全N管拓扑 + 双面洞洞板) (www.ourdev.cn自制_夹心_无刷电调 (C8051F330单片机 + IR2103 + 全N管拓扑 + 双面洞洞板) (www.ourdev.cn
1 2 3 4 5 ... 16
收藏数 303
精华内容 121