F7飞控项目调试过程的记录 系列文章第一部分
主控STM32F777NIHx
BL电调(J-H-20A)
SBUS接收机、福特8遥控器
STM32HAL库
设计/调试记录文档
捕捉下APM飞控输出的PWM波形,可以看出PWM方波的频率为489.2966Hz,证明默认情况下APM飞控确实是以490Hz的速率输出到电调的。好盈天行者系列电调为例,其最高为速率为432Hz,所以我们把输出速率设置为 402Hz (最好低于最高速率20-30Hz)
pwm输出:
PWM1--------------TIM1–>CH1,
PWM2--------------TIM1–>CH2,
PWM3--------------TIM1–>CH3,
PWM4--------------TIM1–>CH4.
设计50hz脉冲(周期20ms):因为TIM1和TIM8挂载在APB2上,根据下图时钟配置线上主频为216mhz.(其他定时器挂载在APB1上,线上主频是108MHZ)
所以时钟分频设置为2160分频 ,也就是100000hz,重装载值设置为2000,就会的到50hz(周期20ms)的pwm输出。
下载验证:实际输出。
改TIM1->CCRx值改变占空比。
将分频系数Prescaler改到270-1。也就是800000hz,重装载值还是2000-1。得到输出400hz的pwm,如下图
至此得到400hz的pwm输出频率给电调,通过调整占空比实现电机转速的控制。
-----------------------------------------start------------------------------------------
接收机的波形图(油门通道)
下图油门最小值
下图油门最大值
---------------------------------------------end---------------------------------------
20200922
重新调整pwm周期为14ms(福特8的油门通道输出就是14ms的脉冲,然后其中1ms-2ms的高电平为油门的整个行程)
所以分频系数改为2160,重装载值改为1400。 然后 ccr值占空比变化范围:计算公式1400*(1/14)~1400*(2/14),也就是100 ~ 200。
TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfigOC = {0};TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};htim1.Instance = TIM1;htim1.Init.Prescaler = 2160-1;htim1.Init.CounterMode = TIM_COUNTERMODE_UP;htim1.Init.Period = 1400-1;htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter = 0;htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);// user_pwm_setvalue(1000);//==========================pwm调试====================================
// delay_ms(500);TIM1->CCR2=100;//实际测试100也能让电调解锁(电调上电后响一声 然后再长响一声 表示电调解锁完成可以调速了。)
// delay_ms(500);TIM1->CCR2=110;//实际测试110,电机也不转,电调也能解锁,115,电机开始转动。
// delay_ms(500);TIM1->CCR2=115;//如果初始给的这个值大于等于115,电调上电只响一声(听不到长响的声音,说明电调没有解锁。) 然后下面的改动ccr值调速,电机也不会转。delay_ms(1000);TIM1->CCR2=110;//目前认为 这个值是电调的解锁油门值(在模拟福特8油门通道的频率下,14ms周期脉冲,频率约为71.428hz)
delay_ms(1000);
TIM1->CCR2=115;
delay_ms(500);
TIM1->CCR2=120;
电调声音说明:
1、当侦测到油门信号时,发出一声低沉响声。表示解锁信号序列开始
2、然后,当油门值为0,发出一声明亮响声,代表解锁信号序列结束
3、当在解锁信号序列中,检测到100%油门信号,则电调开始校准油门行程。
4、当电调已经被解锁,但油门在给定时间内保持0油门,每3秒钟发出警报声,下图就是时间的设置,10min后电调会控制电机发出报警音,上一个参数 beacon Volume是报警音的音量大小调节。
实际测试可知:
给电调最低油门数据(100-110),电调响两声之后,说明电调解锁完成可以调速(封装函数接口,设计电机解锁指令使用)
给电调pwm信号 输出低电平的时候,相当于锁定电调,此时电调只响一声,转速就不能调节了(封装函数接口,设计电机关锁指令使用)
delay_ms(500); TIM1->CCR2=0;//试验一下电调有没有上锁功能。(验证可以当成上锁用)delay_ms(1000);TIM1->CCR2=190;//试验一下电调有没有上锁功能。delay_ms(1000);TIM1->CCR2=120;//试验一下电调有没有上锁功能。
下一步将遥控输入数据 和pwm数据结合控电机转速(先不经过pid控制环路控制,直接驱动试试)
测试保证信号脉宽是1ms-2ms变化,然后改动频率 。
270(2.5ms周期) 800-1600,但是 115 电机也能转 这个明天分析。
540(5ms周期) 400-800
1080(10ms周期) 200-400
2160(20ms周期) 100-200
【转】
PWM信号的频率是通常是没有规定的,可以是50hz、100hz、200hz或500hz等等。控制频率越高,其周期越短,控制间隔也就越短,电调和电机响应速度也就越快。反之,控制频率越低,其周期就越长,控制间隔就越长,电调和电机的响应速度就越慢。早期电调响应PWM 信号的频率是50hz,但随着科技的发展和对控制流畅度的要求,现在多数电调都支持500hz以上的PWM信号,并且电调内部自带滤波器,可以很好的响应并控制电机的转动。
20200923
决定使用400hz的pwm驱动频率
先确定调速范围
delay_ms(1000);TIM1->CCR2=90;
delay_ms(1000);TIM1->CCR2=100;
测试发现90,100都能解锁电调,但是电机不转
delay_ms(500);TIM1->CCR2=105;
delay_ms(500);TIM1->CCR2=110;
delay_ms(500);TIM1->CCR2=115;
当电机≥115时,电机才开始转动。(可以设计成电机怠速值)
理论上算400hz的频率 值的范围是800-1600,为什么实际测试100-150也可以操作电机?
怀疑是 50hz的pwm 周期是20ms, 现在变成400hz,2.5ms
400hz的条件下 20ms时间里面 有 8个2.5ms ,
当设置ccr=100是,示波器检测高电平是120us。120us*8=960us。
所以在20ms时间内 电调认为是启动解锁了电机 。 这种现象 电调是算20ms内的高电平总和。
经过测试发现 100-150电机虽然能转动,但是过了150电机会异常
所以 还是使用理论值 800-1600(400hz频率值的范围)
验证800个值每单位数值都有速度的变化,值范围对应1ms-2ms的脉冲宽度。配置如下:
计算过程:
216000000/270/2000=400hz,1/400=2.5ms
1/2.5x2000=800 ,2/2.5x2000=1600
所以1ms-2ms的pwm值对应800-1600
void MX_TIM1_Init(void)
{TIM_MasterConfigTypeDef sMasterConfig = {0};TIM_OC_InitTypeDef sConfigOC = {0};TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};htim1.Instance = TIM1;htim1.Init.Prescaler = 270-1;htim1.Init.CounterMode = TIM_COUNTERMODE_UP;htim1.Init.Period = 2000-1;htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim1.Init.RepetitionCounter = 0;htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_PWM_Init(&htim1) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK){Error_Handler();}sConfigOC.OCMode = TIM_OCMODE_PWM1;sConfigOC.Pulse = 0;sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK){Error_Handler();}if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK){Error_Handler();}sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;sBreakDeadTimeConfig.DeadTime = 0;sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;sBreakDeadTimeConfig.BreakFilter = 0;sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;sBreakDeadTimeConfig.Break2Filter = 0;sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK){Error_Handler();}HAL_TIM_MspPostInit(&htim1);}
开启pwm输出
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
电机解锁指令
void MOTOR_OPEN_CMD(void) //电机解锁指令
{TIM1->CCR1=0; TIM1->CCR2=0; TIM1->CCR3=0; TIM1->CCR4=0;delay_ms(500);TIM1->CCR1=800; TIM1->CCR2=800; TIM1->CCR3=800; TIM1->CCR4=800;delay_ms(500);
}
电机上锁指令
void MOTOR_CLOSE_CMD(void) //电机上锁指令
{delay_ms(500);TIM1->CCR1=0; TIM1->CCR2=0; TIM1->CCR3=0; TIM1->CCR4=0;delay_ms(500);
}
与遥控通道数据比例融合
计算方法:
遥控通道数据 352-1696,pwm数据 800-1600。
1696-352=1344,1600-800=800,800/1344=0.5952380952380952(比例因子)
实际输出pwm=800+(α)*800/1344 ,(α 为0-1344)
其中α=β-352,(β为实际遥控数据值,352<β<1696),代入
实际输出pwm=800+(β-352)*800/1344 ,(352<β<1696)。
ps:计算可使用浮点数计算,实际输出可以取整。
//结构体指针作为形参
void rc_pwm_ctr_test(struct _att_control *_att_con,struct _RC_SBUS *_rc)//遥控数据转换为tim1的ccr值 输出pwm给电机
{u8 counts;if((*_rc).RcPitch<352||(*_rc).RcPitch>1696)//油门值越界不进行处理{return ;}for(counts=0;counts<4;counts++){(*_att_con).out_pwm_ccr[counts]=800+((*_rc).RcThrottl-352)*800/1344;}
}
然后将4个电机并联在一起重新校准一遍电调。运行程序
测试结果是可行的 ,可以直接用遥控器的油门给到f7主控然后经过转换输出 pwm给到电机了 ,实现了电机的调速。接下来就是加入pid反馈控制算法了,动态调节转速。
测试发现可以将这个油门附近的值作为后期飞机怠速使用的功能
如果用0-1之间的数值规定输出800-1600的范围数据,计算方法如下:
实际输出pwm=800+γ*800 (γ为0-1)
参考:
http://www.doc88.com/p-7505653338402.html
https://zhuanlan.zhihu.com/p/42742897
https://blog.csdn.net/qq_28056277/article/details/91347436
https://wx.renrenso.com/wx/show.php/zKil1Kudk2il1l6nx5uondNnqaFenKillNaVr3WDka22g6KWkMvMpmvIpnvbnKSNzA==
https://blog.csdn.net/moumde/article/details/107620142
https://blog.csdn.net/snail_dongbin/article/details/82803076?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242
F7飞控项目调试过程的记录 系列文章第一部分相关推荐
- Koa项目搭建过程详细记录
2019独角兽企业重金招聘Python工程师标准>>> Java中的Spring MVC加MyBatis基本上已成为Java Web的标配.Node JS上对应的有Koa.Expre ...
- caas k8s主控节点如何查询_k8s中部署prometheus监控告警系统prometheus系列文章第一篇...
前言 本篇文章主要介绍k8s集群中部署prometheus,并且配置prometheus的动态.静态服务发现,实现监控容器.物理节点.service.pod等资源指标,配置prometheus的web ...
- k8s中部署prometheus监控告警系统-prometheus系列文章第一篇
前言 本篇文章主要介绍k8s集群中部署prometheus,并且配置prometheus的动态.静态服务发现,实现监控容器.物理节点.service.pod等资源指标,配置prometheus的web ...
- 跟我学spring security系列文章第一章 实现一个基本的登入
文章目录 指定依赖 安全配置 添加controller测试代码 测试 源码地址: https://github.com/pony-maggie/spring-security-learn 指定依赖 s ...
- K8S大规模集群优化方案系列文章-第一篇
▲ 点击上方"DevOps和k8s全栈技术"关注公众号 Kubernetes 自 v1.6 以来,官方就宣称单集群最大支持 5000 个节点.不过这只是理论上,在具体实践 ...
- keil debug如何在watch直接修改变量值_python日志记录系列教程,内置logging模块(一),直接使用logging模块的基础日志记录
前言:成熟的软件开发不可避免的要进行日志记录,python内置模块logging提供了强大的日志记录能力,本文将从多个角度,由浅入深的介绍logging的常见使用方法和一些基本概念,本此系列文章分为两 ...
- cassss服务未启动_不要再本地启动项目调试了,试SpringBoot远程调试你会发现新大陆!...
前言 上周末一个朋友庆生,无意间听他说起了近况,说公司项目太多了,每天一堆BUG需要修复,项目来回切换启动,真是挺烦的. 随着项目越来越多,特别是身处外包公司的朋友,每天可能需要切换两三个项目,难道一 ...
- 信息化项目实施过程管理的解读(一)
序言 信息化项目实施过程管理是一个非常复杂的课题,本次主要就过程中几个大项的重点内容的实战经验和大家交流一下,希望能达到抛砖引玉的效果. 信息化项目的实施服务和家电的服务完全不是一个概念,家电服务讲究 ...
- 腾讯在线教育互动课堂——Demo调试过程记录
官方文档地址:https://cloud.tencent.com/document/product/680/17888 "Demo调试"不像集成使用,不需要完全按照文档一步步处理, ...
最新文章
- 使用DPM2007备份还原Exchange2007邮箱数据库
- python学习-条件语句
- Android多媒体开发-- android中OpenMax的实现整体框架
- 【BZOJ 2753】 2753: [SCOI2012]滑雪与时间胶囊 (分层最小树形图,MST)
- c#如何识别一张图片的格式
- 高等数学下-赵立军-北京大学出版社-题解-练习10.3
- 无法获取 vmci 驱动程序版本: 句柄无效
- 编写高质量代码的50条黄金守则-Day 04(首选字符串插值)
- eclipse每次闪退后都提示查看\workspace\.metadata\.log
- 啊哈算法——第一章第一节:桶排序
- Oracle获取日期大全(当月的第一天/后一天/上一天/最后一天/上个月这一天)
- QQ、微博、陌陌:社交难逃社交命
- yuyu终于考完了!我提前过生日了!(两者好像没有关联嘛^_^)
- P1359 租用游艇(dijkstra不优化)
- 35. 我用Compose开发了一款音视频处理app
- 亚马逊SP-API对接实践
- python 情感分析实例_基于Python的情感分析案例
- Windows下动态内存分配方式http://whx.tzgt.gov.cn/newOperate/html/7/71/711/3938.html
- 因果推理(八):工具变量(Intrusmental Variables)
- HDU 3031 ToBe Or Not To Be(模拟)
热门文章
- 编写一个函数判断一个整数是不是素数c语言,编写函数判断一个整数是否为素数....
- 知名插画师走尺,带你走进“薪”世界
- 插画师的配色灵感分享
- C++动态分配new(C++ primer,P320)
- HDU 6656 Kejin Player
- 一语中的丨高对抗重实战攻防视角下,企业安全运营到底该怎么做?
- python3进阶篇(二)——深析函数装饰器
- 布林通道参数用20还是26_boll参数20还是26好 股市的布林线的三根线是什么
- 187、商城业务-检索服务-页面排序功能
- TCP 包完整性检验