stm32通过电调带动电机(可按键调速)
这几天在做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通过电调带动电机(可按键调速)的更多相关文章
- Java生鲜电商平台-API请求性能调优与性能监控
Java生鲜电商平台-API请求性能调优与性能监控 背景 在做性能分析时,API的执行时间是一个显著的指标,这里使用SpringBoot AOP的方式,通过对接口添加简单注解的方式来打印API的执行时 ...
- 自动调参库hyperopt+lightgbm 调参demo
在此之前,调参要么网格调参,要么随机调参,要么肉眼调参.虽然调参到一定程度,进步有限,但仍然很耗精力. 自动调参库hyperopt可用tpe算法自动调参,实测强于随机调参. hyperopt 需要自己 ...
- OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- LAMP 系统性能调优之网络文件系统调优
LAMP 系统性能调优之网络文件系统调优 2011-03-21 09:35 Sean A. Walberg 网络转载 字号:T | T 使用LAMP系统的用户,都想把自己LAMP性能提高运行的速度提高 ...
- stm32 pwm 电调 电机
先上代码 python 树莓派版本,通俗表现原理.stm32 C语言版本在后面 import RPi.GPIO as GPIO import time mode=2 IN1=11 def setup( ...
- STM32控制永磁同步电机 | FOC电机控制算法概述
1. FOC基本概念 参考:https://www.sohu.com/a/432103720_120929980 FOC(field-oriented control)为磁场导向控制,又称为矢量控制( ...
- STM32 掉电检测程序
当VDD下降到PVD阀值以下或当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断 void PVD_IRQHandler(void) { led_ctrl ...
- 第三篇、调优之路 Apache调优
1. 简介 在第一篇中整合了apache + tomcat ,利用了apache解析静态文件为tomcat解压.但是在测试机上发现两者性能不足,不能充分利用服务器的性能,该篇中将对apache进行性 ...
- 七、Hadoop学习笔记————调优之Hadoop参数调优
dfs.datanode.handler.count默认为3,大集群可以调整为10 传统MapReduce和yarn对比 如果服务器物理内存128G,则容器内存建议为100比较合理 配置总量时考虑系统 ...
随机推荐
- 用json传值时,最后一个不加逗号
<javascript> $('.obj').css( 'position':'relative', 'top':'100px', 'left':'100px' ); </javas ...
- .NET入行之工作前
时间就像轻风一样,刻意感受的时候几乎把你吹倒,不留意的时候又从你身边轻轻飘走了:长此以后,我怕自己会变得麻木,忘记了原来的样子.所以还是决定给自己留点什么,万一哪天忘记了,还可以再翻起来. 工作两年的 ...
- KoaHub平台基于Node.js开发的Koa的调试实用程序
debug small debugging utility debug tiny node.js debugging utility modelled after node core's debugg ...
- 使用js实现ajax的get请求步骤
(以下内容非原创,视频整合得来的) 1.创建XMLHttpRequest对象 2.浏览器与服务器建立连接 3.浏览器向服务器发送请求 4.服务器向浏览器响应请求 下面给出一个实例 1.创建一个test ...
- sqlplus入门使用
1.如果在PL/SQL 等工具里打开的话,直接修改下面的代码中[斜体加粗部分]执行 2.确保路径存在,比如[D:\oracle\oradata\Oracle9i\]也就是你要保存文件的路径存在 /*分 ...
- SLF4J 的几种实际应用模式--之三:JCL-Over-SLF4J+SLF4J
我们前面已经讲过了 SLF4J 的两种用法:SLF4J+Log4J 和 SLF4J+Logback,那是在比较理想的情况下,所用组件只使用了 SLF4J 这一种统一日志框架的时候.可是 JCL 一直 ...
- iOS开发之通过代码自定义一个控件
关于控件的继承关系(面试重点): (1)所有的控件都继承自UIView. (2)能监听事件的都是先继承自UIControl,UIControl再继承自UIView.比如UIButton. (3)能整体 ...
- cassandra高级操作之索引、排序以及分页
本次就给大家讲讲cassandra的高级操作:索引.排序和分页:处于性能的考虑,cassandra对这些支持都比较简单,所以我们不能希望cassandra完全适用于我们的逻辑,而是应该将我们的逻辑设计 ...
- Windows Mobile 常用键值VK对应表
#define VK_TSOFT2 VK_F2 // Softkey 2 #define VK_TTALK VK_F3 // Talk ...
- Lvs工作原理
DR模式的工作过程: 当一个client发送一个WEB请求到VIP,LVS服务器根据VIP选择对应的real-server的Pool,根据算法,在Pool中选择一台Real-server,LVS在ha ...