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比较合理 配置总量时考虑系统 ...
随机推荐
- jQuery后续...
jQuery 选择器 1.jQuery选择器的简介 (1). Jquery中的选择器完全继承了CSS的风格,利用Jquery选择器,可以非常便捷和快速的找出特定的Dom元素,然后为他们添加相应的行为, ...
- JS邮箱验证-正则验证
<form act="">输入:<input type="text" name="qc" id="qc" ...
- 使用es6特性封装async-mysql
node.js的mysql模块本身没有提供返回promise的函数,即是说都是用的回调函数,那么对于我们使用async函数是很不方便的一件事.node.js有一个mysql封装库叫mysql-prom ...
- 1084: [SCOI2005]最大子矩阵
1084: [SCOI2005]最大子矩阵 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1325 Solved: 670[Submit][Stat ...
- java 学习 todoList
1.并发包的使用 2.线程相关的源码,怎么结束一个线程 3.单例模式代码 4.mixin 相关的理解代码 书单: effective java java 编程思想 spring 编程指南 深入理解jv ...
- ZJOI2017 Day1
私のZJOI Day1 2017-3-21 07:52:53 有人在暴力膜 苟-- 富贵 无相忘 ZJOI2017交流群 133135071 如果你足够厉害 如果你足够厉害 如果你足够厉害 其实完全可 ...
- nfs mount:reason given by server: Permission denied
遇到nfs mount的问题,以前从未遇到过,问题出的很奇怪,现象是 mount: 10.1.10.22:/cicro failed, reason given by server: Permissi ...
- virtualenv 安装不同版本的虚拟环境的办法
废话不多说直接上代码 virtualenv -p C:\Python27\python2.exe env 上面的*.exe是你要使用的python版本的exe文件的绝对路径. 官方文档参考:http: ...
- GWT开端
这篇文章是转载的,原地址:GWT开端 以前的基于GWT的项目中广泛使用的还是gwt-windows-1.5.3这个版本的. 1.下载地址:http://code.google.com/webtoolk ...
- VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)
一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...