这几天在做32通过电调带动电机的实验,上网一查,发现这方面的资料很少,经过自己的亲自实践,总结出以下经验,供大家参考。

论坛上也有很多人说自己在做,但是都遇到了同样的瓶颈。我想他们大多是pwm的频率和占空比没有调到合适的值吧。

首先,我在网上只找到一片很好的文章,是瑞生大神写的:http://www.rationmcu.com/lpc1114/1126.html

我的电机是银燕2212/1400kv经典电机 ,电调也是银燕40A无刷电调。

通过它知道,当pwm设置为500hz的 时候电调才能正常的工作,刚开始时高电平时间要控制在0.7-1.9左右,让电机带电自检。

通过按键控制占空比可以很好地 实现这一点。

好了,下面上我的代码。

先来头文件吧

#ifndef _Motor_H_
#define _Motor_H_
#include "stm32f10x.h" /******************************************************************************
全局函数声明
*******************************************************************************/
void Motor_Init(void);
//void Motor_Out(int16_t duty1,int16_t duty2,int16_t duty3,int16_t duty4); #endif

主菜:

 /***************************************************************************************
1/给单片机写程序:使得某引脚输出500Hz的PWM信号,初始化时高电平时间设置为1.9ms,
然后在while循环里面加入检测按键的程序,当按键按下,把高电平设置为0.7ms。
2/1.给单片机写程序,把刚才的PWM初始化的高电平设置为0.7ms,保证刚上电,电调不会让电机转动。
然后给修改按键按下的程序,修改为,按一次按键,高电平时间增加一点点,最大增加到1.9ms。 我的按键再c13(k2)和e0(k1)
日期:2016.3.4
***************************************************************************************/ #include "dianji.h" uint8_t indexWave[] = {,,,,,,,,,,,,,,}; //占空比表 //声明函数
void Tim2_init(void);
void Motor_Init(void);
void Init_NVIC(void);
void Delay_Ms(uint16_t time);
void Delay_Us(uint16_t time);
void Init_TI_KEY(void); int main(void)
{ SystemInit(); //系统时钟配置
Motor_Init();
Tim2_init();
Init_NVIC(); //中断向量表注册函数
Init_TI_KEY(); //按键引脚中断初始化 while(); } void Tim2_init(void)
{ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = -; //设置ARR的值为19,从0计数到19,刚好是2ms ,500hz
TIM_TimeBaseStructure.TIM_Prescaler = -;//设置PSC的值为7199,这样的话每计数一次为0.1ms TIM_TimeBaseStructure.TIM_ClockDivision = ; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMx向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseStructure中指定的参数初始化外设TIM2 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_Pulse = ; //设置待装入捕获比较寄存器的脉冲值,刚开始可以设置为0.
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器 TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIM2在ARR上的预装载寄存器
TIM_Cmd(TIM2, ENABLE); //使能TIM2外设
} /******************************************************************************
函数原型: void Motor_Init(void)
功 能: PWM初始化
*******************************************************************************/
void Motor_Init(void)
{ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能电机用的时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; //设置电机使用到得管脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); } /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: KEY_TI_Init
** 功能描述: 按键 中断配置
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Init_TI_KEY(void)
{
EXTI_InitTypeDef EXTI_InitStructure; //定义一个EXTI结构体变量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能IO复用功能,使用中断功能重要!!! GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);//配置端口C的13引脚为中断源 重要!! 板上标号INT2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0); //配置端口E的0引脚为中断源 重要!! 板上标号INT1
EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line13;//
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断模式为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿出发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线
EXTI_Init(&EXTI_InitStructure); //根据参数初始化中断寄存器
} /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Init_NVIC
** 功能描述: 系统中断配置 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Init_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组2 NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //设定中断源为PC13
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; //中断占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //副优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //设定中断源为PE0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; //中断占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //副优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure); //根据参数初始化中断寄存器
} /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: EXTI15_10_IRQHandler
** 功能描述: 中断15_10入口函数 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void EXTI15_10_IRQHandler(void) //占空比减小
{
static uint8_t pwm_index = ; //用于PWM查表
static uint8_t period_cnt = ; //用于计算周期数
//就是上面两个静态变量没有设置 ,导致一开始按键只能按一次,在往下按他的pwm表就不往下查表了,我想了一晚上啊。
//今天早晨我突然发现可能是这两个静态变量没有设置,一试,果然。开心至极。2016.3.5 if(EXTI_GetITStatus(EXTI_Line13)!= RESET) //判断是否发生中断,发生则中断标志置1
{
Delay_Ms(); //消抖 period_cnt++; TIM2->CCR1 = indexWave[pwm_index]; //根据PWM表修改定时器的比较寄存器值
pwm_index++; //标志PWM表的下一个元素 if( pwm_index >= ) //若PWM脉冲表已经输出完成一遍,重置PWM查表标志
{
pwm_index=;
} //TIM_ClearITPendingBit (TIM2, TIM_IT_Update); //必须要清除中断标志位 EXTI_ClearITPendingBit(EXTI_Line13); //清楚中断挂起位,重要!!
} } /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: EXTI0_IRQHandler
** 功能描述: 中断0入口函数
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void EXTI0_IRQHandler(void) //占空比增大
{
if(EXTI_GetITStatus(EXTI_Line0)!= RESET) //判断是否发生中断,发生则中断标志置1
{
Delay_Ms(); //暂时不用
}
EXTI_ClearITPendingBit(EXTI_Line0); //清楚中断挂起位,重要!!
} /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Delay_Ms_Ms
** 功能描述: 延时1MS (可通过仿真来判断他的准确度)
** 参数描述:time (ms) 注意time<65535
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Delay_Ms(uint16_t time) //延时函数
{
uint16_t i,j;
for(i=;i<time;i++)
for(j=;j<;j++);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Delay_Ms_Us
** 功能描述: 延时1us (可通过仿真来判断他的准确度)
** 参数描述:time (us) 注意time<65535
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Delay_Us(uint16_t time) //延时函数
{
uint16_t i,j;
for(i=;i<time;i++)
for(j=;j<;j++);
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
End:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/

本人也是新手,最近在做四旋翼,有什么问题欢迎交流。

stm32通过电调带动电机(可按键调速)的更多相关文章

  1. Java生鲜电商平台-API请求性能调优与性能监控

    Java生鲜电商平台-API请求性能调优与性能监控 背景 在做性能分析时,API的执行时间是一个显著的指标,这里使用SpringBoot AOP的方式,通过对接口添加简单注解的方式来打印API的执行时 ...

  2. 自动调参库hyperopt+lightgbm 调参demo

    在此之前,调参要么网格调参,要么随机调参,要么肉眼调参.虽然调参到一定程度,进步有限,但仍然很耗精力. 自动调参库hyperopt可用tpe算法自动调参,实测强于随机调参. hyperopt 需要自己 ...

  3. OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议

    注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...

  4. LAMP 系统性能调优之网络文件系统调优

    LAMP 系统性能调优之网络文件系统调优 2011-03-21 09:35 Sean A. Walberg 网络转载 字号:T | T 使用LAMP系统的用户,都想把自己LAMP性能提高运行的速度提高 ...

  5. stm32 pwm 电调 电机

    先上代码 python 树莓派版本,通俗表现原理.stm32 C语言版本在后面 import RPi.GPIO as GPIO import time mode=2 IN1=11 def setup( ...

  6. STM32控制永磁同步电机 | FOC电机控制算法概述

    1. FOC基本概念 参考:https://www.sohu.com/a/432103720_120929980 FOC(field-oriented control)为磁场导向控制,又称为矢量控制( ...

  7. STM32 掉电检测程序

    当VDD下降到PVD阀值以下或当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断 void PVD_IRQHandler(void) { led_ctrl ...

  8. 第三篇、调优之路 Apache调优

    1.  简介 在第一篇中整合了apache + tomcat ,利用了apache解析静态文件为tomcat解压.但是在测试机上发现两者性能不足,不能充分利用服务器的性能,该篇中将对apache进行性 ...

  9. 七、Hadoop学习笔记————调优之Hadoop参数调优

    dfs.datanode.handler.count默认为3,大集群可以调整为10 传统MapReduce和yarn对比 如果服务器物理内存128G,则容器内存建议为100比较合理 配置总量时考虑系统 ...

随机推荐

  1. 用json传值时,最后一个不加逗号

    <javascript> $('.obj').css( 'position':'relative', 'top':'100px', 'left':'100px' ); </javas ...

  2. .NET入行之工作前

    时间就像轻风一样,刻意感受的时候几乎把你吹倒,不留意的时候又从你身边轻轻飘走了:长此以后,我怕自己会变得麻木,忘记了原来的样子.所以还是决定给自己留点什么,万一哪天忘记了,还可以再翻起来. 工作两年的 ...

  3. KoaHub平台基于Node.js开发的Koa的调试实用程序

    debug small debugging utility debug tiny node.js debugging utility modelled after node core's debugg ...

  4. 使用js实现ajax的get请求步骤

    (以下内容非原创,视频整合得来的) 1.创建XMLHttpRequest对象 2.浏览器与服务器建立连接 3.浏览器向服务器发送请求 4.服务器向浏览器响应请求 下面给出一个实例 1.创建一个test ...

  5. sqlplus入门使用

    1.如果在PL/SQL 等工具里打开的话,直接修改下面的代码中[斜体加粗部分]执行 2.确保路径存在,比如[D:\oracle\oradata\Oracle9i\]也就是你要保存文件的路径存在 /*分 ...

  6. SLF4J 的几种实际应用模式--之三:JCL-Over-SLF4J+SLF4J

    我们前面已经讲过了 SLF4J 的两种用法:SLF4J+Log4J  和 SLF4J+Logback,那是在比较理想的情况下,所用组件只使用了 SLF4J 这一种统一日志框架的时候.可是 JCL 一直 ...

  7. iOS开发之通过代码自定义一个控件

    关于控件的继承关系(面试重点): (1)所有的控件都继承自UIView. (2)能监听事件的都是先继承自UIControl,UIControl再继承自UIView.比如UIButton. (3)能整体 ...

  8. cassandra高级操作之索引、排序以及分页

    本次就给大家讲讲cassandra的高级操作:索引.排序和分页:处于性能的考虑,cassandra对这些支持都比较简单,所以我们不能希望cassandra完全适用于我们的逻辑,而是应该将我们的逻辑设计 ...

  9. Windows Mobile 常用键值VK对应表

    #define VK_TSOFT2              VK_F2  // Softkey 2  #define VK_TTALK                VK_F3  // Talk  ...

  10. Lvs工作原理

    DR模式的工作过程: 当一个client发送一个WEB请求到VIP,LVS服务器根据VIP选择对应的real-server的Pool,根据算法,在Pool中选择一台Real-server,LVS在ha ...