一文打尽PWM协议、PPM协议、PCM协议、SBUS协议、XBUS协议、DSM协议 | STM32的通用定时器TIM3实现PPM信号输出
1. PWM协议
电机(电调)上用到PWM信号种类很多,我们这里对常见的PWM信号特征进行一个描述:
1、 PWM信号是一个周期性的方波信号,周期为20ms,也就是50Hz的刷新频率。
2、 PWM每一周期中的高电平持续时间为1~2ms(1000us~2000us),代表了油门控制量。一般四旋翼中1100us对应0油门,1900us对应满油门
2. PPM(CPPM)协议、PCM协议
比如将两个遥控器之间连接起来的教练模式,比如遥控器接电脑玩模拟器,当然还有我们玩多轴,要将接收机的信号传输给飞控时,每个通道一组物理连线的方式就显得非常的繁琐和没有必要。这时候PPM就是救星了。
PCM(pulse-code modulation,脉冲编码调制,又称脉码调制)。这里顺便提一句,有些航模爱好者误将PPM编码说成是FM,其实这是两个不同的概念。前者指的是信号脉冲的编码方式,后者指的是高频电路的调制方式。
航模遥控器发射电路的工作原理是:操作通过操纵发射机上的手柄,将电位器组值的 变化信息送入编码电路。编码电路将其转换成一组脉冲编码信号(PPM或PCM)。这组脉冲编码信号经过高频调制电路(AM或FM)调制后,再经高放电路发送出去。PPM的编解码方式一般是使用积分电路来实现的,而PCM编解码则是用模/数(A/D)和数/模(D/A)转技术实现的。
航模遥控器中最常用的两种脉冲编码方式就是PPM和PCM;
最常用的两种高频调制方式是FM调频和AM调幅;
最常见的组合为PPM/AM脉位调制 编码/调幅、PPM/FM脉位调制编码/调频、PPM/FM脉冲调只编码/调频三种形式。
通常的PPM接收解码电路都由通用的数字集成电路组成,如 CD4013,CD4015等。对于这类电路来说,只要输入脉冲的上升沿达到一定的高度,都可以使其翻转。这样,一旦输入脉冲中含有干扰脉冲,就会造成输 出混乱。由于干扰脉冲的数量和位置是随机的,因此在接收机输出端产生的效果就是“抖舵”。除此之外,因电位器接触不好而造成编码波形的畸变等原因,也会影 响接收效果,造成“抖舵”。对于窄小的干扰脉冲,一般的PPM电路可以采用滤波的方式消除;而对于较宽的干扰脉冲,滤波电路就无能为力了。这就是为什么普 通的PPM比例遥控设备,在强干扰的环境下或超出控制范围时会产生误动作的原因。尤其是在有同频干扰的情况下,模型往往会完全失控。
3. SBUS(S-BUS/S.BUS)
SBUS:每11个bit位表示一个通道数值的协议,串口通信,但是sbus的接收机通常是反向电平,连接到无人机时需要接电平反向器,大部分支持sbus的飞行控制板已经集成了反向器,直接将以旧换新机连接到飞行控制器即可。
XBUS:常规通信协议,支持18个通道,数据包较大,串口通信有两种模式,可以在遥控器的配置选项中配置。接收机无需做特殊配置。
SBUS是一个串行通信协议,最早由日本厂商FUTABA(扶他爸~)引入,随后FrSky的很多接收机也开始支持,S.BUS是全数字化接口总线,数字化是指的该协议使用现有数字通信接口作为通信的硬件协议,使用专用的软件协议,这使得该设备非常适合在单片机系统中使用,也就是说适合与飞控连接。这也就是我为什么要将这个协议详细叙述的原因。总线是指他可以连接多个设备,这些设备通过一个Hub与这个总线相连,得到各自的控制信息。
SBUS使用RS232C串口的硬件协议作为自己的硬件运行基础。 使用TTL电平,即3.3V。 使用负逻辑,即低电平为“1”,高电平为“0”。 采用100K的波特率(注意:不兼容波特率115200),8位数据位,两位停止位,偶效验,即8E2的串口通信。
SBUS是一个接收机串行总线的输出,通过这根总线,可以获得遥控器上所有通道的数据。目前很多模型及无人机电子设备都支持SBUS总线的接入。使用SBUS总线获取通道数据,效率高,而且节省硬件资源,只需要一根线即可获取所有通道的数据。
SBUS一帧数据的长度为25个字节:
字节[0]:SBUS头,0x0F
字节[1-22]:16个伺服通道,每个伺服通道采用11位编码
字节[23]:
位7:数字通道17(0x80)
位6:数字通道18(0x40)
位5:丢帧(0x20)
位4:用来激活故障安全(0x10)
位0-3:n/a
字节[24]:SBUS结束字节,0x00
具体协议的格式如下:
[数据头] [第一个字节] [第二个字节] ......[第二十二的字节] [标志位] [数据尾]
数据头、标志位、数据尾 不携带信息,而且数据头和数据尾是固定的,数据头=0x0f; 数据尾=0x00;
数据头(1字节)+数据(22字节)+标志位(1字节)+数据尾(1字节)
SBUS的每个RC通道值映射为:
-100%= 173(相当于PWM伺服信号中的1000)
0%= 992(相当于PWM伺服信号中的1500)
100%= 1811(相当于PWM伺服信号中的2000)
值得注意的有三点:
(1)SBUS采用负逻辑,所以无论接收还是发送都要进行硬件取反(注意,一定要硬件取反),电路如下:
STM32F0芯片内置了反相电路,所以芯片外围不用加。
(2)SBUS有两种模式,
a.高速模式:每4ms发送一次
b.低速模式:每14ms发送一次
就是说每间隔4或者14ms这个串口就发送25个字节的数据,这25个字节的数据最多可以包含16个信息。
(3)100K的波特率不是标准波特率,一般串口工具都不能直接读取(所以不要直接用电脑调试,除非你的电脑写好了非标准串口),可以用单片机读取。
编码原理
一个信息是二进制的11bit,比如1111 1111 111就可以表示一个信息,一共16个这样的信息,按照顺序将这16个信息依次排成一串,得到一个176bit(11 *16)的数据,也就是22字节(176 / 8 = 22)的数据,再加上数据头数据尾校验位就组成了一个要通过串口传送的信息。每隔4或者14ms就传送一个这样的信息。
所以这16个信息每一个所能表示的最大值是2^11 = 2048,也就是他的精度。
标志位的高四位有特殊含义,第四位并没有使用,依照我的理解,第七位和第六位表示两个数字通道(通道17和18)信息(就是只有高低电平的通道,一般用来控制通断或者某个电机简单的启动或者停止,比如1表示启动电机0表示停止电机)。第五位表示帧丢失,接收机红色LED亮起,如果这一位为1,表示这一帧信号出问题了,接收机红色LED亮起。第四位表示故障保护激活,意思应该是说如果这一位为1,激活接受方故障保护。
bit7 = ch17 = digital channel (0x80)
bit6 = ch18 = digital channel (0x40)
bit5 = Frame lost, equivalent red LED on receiver (0x20)
bit4 = failsafe activated (0x10)
bit3 = n/a
bit2 = n/a
bit1 = n/a
bit0 = n/a
代码实现可以查看笔者这篇文章:https://www.bilibili.com/read/cv5824207
4. DSM2(DSMX)
5. STM32实现PPM信号输出
纸上得来终觉浅,绝知此事要躬行。
道理讲了这么多,让我们上手实现一下PPM输出,这是我们J20航模遥控器要用到的一个功能模块,迟早要加进去。
tim.c文件
#include "tim.h"
#include "main.h" #define PPM_NUM 18 //PPM数组中的个数,这里是8通道1+8*2+1 u16 PPM_Array[PPM_NUM] = {500,1000,500,1000,500,500,500,1000, 500,1000,500,1000,500,1000,500,1000,500,8000};
u16 PPM_Index = 0;//PPM数组索引号
/*TIM3的中断初始化*/
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3的中断号
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
} /*PPM引脚初始化*/
static void PPM_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能GPIO外设时钟
//设置PPM引脚为推挽输出功能,输出脉冲波形
GPIO_InitStructure.GPIO_Pin = PPM_Pin; //PPM引脚号
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(PPM_GPIO_Port, &GPIO_InitStructure);//初始化PPM端口
}
/*TIM3初始化*/
void PPM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟 TIM_TimeBaseStructure.TIM_Period = 500; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = 71; //设置用来作为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的时间基数单位
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//允许 更新 产生中断 PPM_GPIO_Configuration(); //GPIO初始化
NVIC_Configuration(); //中断初始化
TIM_Cmd(TIM3, ENABLE); //使能TIM3
PPM = 0;//前500us输出低电平
} /*TIM3中断服务子程序*/
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 清除标志位
TIM3->ARR = PPM_Array[PPM_Index]-1;//更新TIM3的自动重装载值,减1是给后几行程序留时间
PPM = !PPM;//更改电平
PPM_Index++;
if(PPM_Index>=PPM_NUM)
{
PPM_Index = 0;
}
}
}
tim.h文件
#ifndef __TIM_H
#define __TIM_H #include "main.h" void PPM_Init(void); #endif
main.c文件
/*
* 定时器TIM3实现PPM输出
* 具体说明见Doc/ReadMe.txt文档
*/ #include "main.h" /*变量定义*/ /*程序开始时运行一次的代码*/
void setup(void)
{
delay_init();//初始化延时函数
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2,2位抢占优先级和2位子优先级
usart_init(115200);//初始化串口1(波特率为115200,8个数据位,无校验,1个停止位)
PPM_Init();
} /*不断循环执行的代码*/
void loop(void)
{ } int main()
{
setup();
while(1){loop();}
}
main.h文件
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif /*main.h统一定义引脚,便于移植*/
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "tim.h" /*引脚定义*/ #define PPM_Pin GPIO_Pin_13
#define PPM_GPIO_Port GPIOC
#define PPM PCout(13) #ifdef __cplusplus
}
#endif
#endif
工程文件下载:https://files.cnblogs.com/files/cai-zi/PPM.zip
用逻辑分析仪接在PC13,查看波形输出如下,看起来时间还是很准确的。
一文打尽PWM协议、PPM协议、PCM协议、SBUS协议、XBUS协议、DSM协议 | STM32的通用定时器TIM3实现PPM信号输出的更多相关文章
- 深入理解HTTP协议(转) 浏览器和服务器如何通信(HTTP协议)
http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web C ...
- (转)协议森林03 IP接力赛 (IP, ARP, RIP和BGP协议)
协议森林03 IP接力赛 (IP, ARP, RIP和BGP协议) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 网络层(net ...
- 《TCP/IP详解卷1:协议》第6章 ICMP:Internet控制报文协议-读书笔记
章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...
- TCP/IP协议(一)网络基础知识 网络七层协议
参考书籍为<图解tcp/ip>-第五版.这篇随笔,主要内容还是TCP/IP所必备的基础知识,包括计算机与网络发展的历史及标准化过程(简述).OSI参考模型.网络概念的本质.网络构建的设备等 ...
- 我们检测到您的浏览器不兼容传输层安全协议 (TLS) 1.1 或更高版本,此协议在 Internet 上用于确保您通信的安全性。
早上使用.Net WebClient类采集亚马逊数据,返回http 400 Bad Request错误,内容里面有“我们检测到您的浏览器不兼容传输层安全协议 (TLS) 1.1 或更高版本,此协议在 ...
- (五)转载:通用定时器PWM输出
1. TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有 ...
- STM32(7)——通用定时器PWM输出
1.TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种 ...
- 协议森林03 IP接力赛 (IP, ARP, RIP和BGP协议)
网络层(network layer)是实现互联网的最重要的一层.正是在网络层面上,各个局域网根据IP协议相互连接,最终构成覆盖全球的Internet.更高层的协议,无论是TCP还是UDP,必须通过网络 ...
- 协议森林17 我和你的悄悄话 (SSL/TLS协议)
作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系. TLS名为传输层安全协议(Transport Layer Protocol),这个协议是一套加密的 ...
随机推荐
- JAVA学习准备
Java学习准备 MarkDown语法学习 字体 hello,world! hello,world! hello,world! 引用 即使最小的帆也能远航 分割线 图片 超链接 点击跳转到我的邮箱 列 ...
- 基于tcp的socket通信
# socket # socekt是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,socket其实就是一个门面模式,它 # 把复杂的tcp/ip协议族隐藏在socket接 ...
- php 与 docker php-fpm 共存问题
需求: 本地一个 php7 的 php-fpm,现在需要运行 php5.2版本的程序, 服务器安装的 nginx 解析域名,碰见 php 文件交给 php5的 php-fpm; 注意: fastcgi ...
- 面试BAT问的最多的27道MyBatis 面试题(含答案和思维导图总结)
前言 关于MyBatis总结了一个思维导图希望对大家有帮助 什么是 Mybatis? Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身, ...
- FL studio系列教程(十三):如何在FL Studio步进音序器中制作节奏
了解了FL Studio一些操作功能后,我们就要去用这些操作功能完成我们想要的作品.所以今天小编就来带领大家在FL Studio的步进音序器中制作出简单的节奏,与此同时大家也会了解到通道的几个基础功能 ...
- python中正则表达式
正则表达式是一种通用的字符串匹配技术,是不会因为编程语言不一样而发生变化的如果想查找对应规则的字符串,就可以用正则表达式python中要使用正则表达式需使用re模块,它是正则表达式在python中的封 ...
- input[type=file] 样式美化,input上传按钮美化
<style>.file { position: relative; display: inline-block; background: #D0EEFF; border: 1px sol ...
- appium服务器参数
appium服务器初始化参数 Appium服务器初始化参数(功能) 设置能力 能力参数项 获取appPackage与appActivity 查看当前活动名称 使用uiautomatorviewer定位 ...
- 蓝桥杯——字母阵列(2018JavaC组第3题)
字母阵列(18JavaC3) 标题:字母阵列 仔细寻找,会发现:在下面的8x8的方阵中,隐藏着字母序列:"LANQIAO". SLANQIAO ZOEXCCGB MOAYWKHI ...
- 微服务手册:API接口9个生命节点,构建全生命周期管理
互联网应用架构:专注编程教学,架构,JAVA,Python,微服务,机器学习等领域,欢迎关注,一起学习. 对于API,在日常的工作中是接触最多的东西,特别是我们软件这一行,基本就是家常便饭了,在百度百 ...