单片机模拟输出PPM信号

2023-05-16

    PPM信号就是将多个PWM信号放在一起传输,一个PPM的周期为20ms,其中一个通道信号的范围为1~2ms,所以一个PPM信号,最多可以传输10个通道的PWM信号。

 PPM信号以0.5ms的低电平信号代表一个通道的起始信号,其后的高电平信号,范围在0.5~1.5ms,代表该通道的PWM占空比。

  • 占空比为0,高电平0.5ms
  • 占空比50%,高电平信号1ms
  • 占空比100%,占空比1.5ms

在所有的通道信号结束之后,用一个0.5ms的低电平信号,代表结束。此时,时间未满20ms的,剩下时间用高电平填充。

明白了原理,我们就思考一下,用单片机怎么模拟输出?

首先采用定时器,在定时中断时去改变PPM输出引脚的电平状态。且在中断发生时,改变定时器的重装载值,也就是改变这个电平信号的持续时间。下面,我以GD32F130单片机来模拟输出四通道的PPM信号。

//定时器初始化与PPM输出引脚初始化
void ppm_init(void)
{
    GPIO_InitPara GPIO_InitStructure;
    TIMER_BaseInitPara TIMER_BaseInitParaStructure;
    NVIC_InitPara NVIC_InitStructure;

    RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOF,ENABLE);
    RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER2,ENABLE);


    GPIO_InitStructure.GPIO_Pin     = PPM_Out_Pin ;
    GPIO_InitStructure.GPIO_Mode    = GPIO_MODE_OUT;
    GPIO_InitStructure.GPIO_OType   = GPIO_OTYPE_PP;
    GPIO_InitStructure.GPIO_PuPd    = GPIO_PUPD_NOPULL;
    GPIO_InitStructure.GPIO_Speed   = GPIO_SPEED_50MHZ;
    GPIO_Init(GPIOF,&GPIO_InitStructure );

    TIMER_DeInit(TIMER2);
    TIMER_BaseInitParaStructure.TIMER_Prescaler = 72-1; /* 1MHz */
    TIMER_BaseInitParaStructure.TIMER_CounterMode = TIMER_COUNTER_UP;
    TIMER_BaseInitParaStructure.TIMER_Period = 500-1; /* 500*1MHz = 500us */
    TIMER_BaseInitParaStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;
    TIMER_BaseInit(TIMER2,&TIMER_BaseInitParaStructure); 
		
		TIMER_ClearIntBitState(TIMER2,TIMER_INT_UPDATE);

    TIMER_INTConfig(TIMER2, TIMER_INT_UPDATE, ENABLE);
    NVIC_InitStructure.NVIC_IRQ = TIMER2_IRQn;
    NVIC_InitStructure.NVIC_IRQPreemptPriority = 6;
    NVIC_InitStructure.NVIC_IRQSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQEnable = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIMER_Enable(TIMER2,ENABLE);
		
    PPM_Out_L//输出低电平

}

 

GD32F130的定时器2时钟是72MHz的 ,所以将其72分频,获得1MHz的时钟,即每记一个数,就是1us。

TIMER_BaseInitParaStructure.TIMER_Prescaler = 72-1; /* 1MHz */

前面,我们说过,通道起始是一个0.5ms的低电平信号,所以,首先输出一个低电平,在定时500u中断发生后去改变它的状态。

下面是定时中断函数

//输出PPM信号
u8 ppm_count=1;  //步骤计数
u16 toal_time=0;//总的通道高电平时间
extern u16 ppm_data[4];//通道摇杆的AD采样数据
void TIM2_IRQHandler(void)
{
     float time;
    TIMER_ClearIntBitState(TIMER2,TIMER_INT_UPDATE);


    switch(ppm_count)
    {
    case 1://第一通道开始  -----------------------------(1)
        PPM_Out_H
		time=((float)ppm_data[0]/819.0)*200+499;//(通道高电平时间在500us~1500us)
		toal_time+=time;
        TIMER_SetAutoreload(TIMER2,(u32)time);
        ppm_count++;
        break;

    case 2://第一通道结束,开始0.5ms低电平---------------(2)
        PPM_Out_L
        TIMER_SetAutoreload(TIMER2,499);
        ppm_count++;
        break;
    case 3://第二通道开始------------------------------(3)
        PPM_Out_H
		time=((float)ppm_data[1]/819.0)*200+499;
		toal_time+=time;
        TIMER_SetAutoreload(TIMER2,(u32)time);
        ppm_count++;
        break;
    case 4://第二通道结束,开始0.5ms低电平
        PPM_Out_L
        TIMER_SetAutoreload(TIMER2,499);
        ppm_count++;
        break;
    case 5://第三通道开始
        PPM_Out_H
		time=((float)ppm_data[2]/819.0)*200+499;
		 toal_time+=time;
        TIMER_SetAutoreload(TIMER2,(u32)time);
        ppm_count++;
        break;
    case 6://第三通道结束,开始0.5ms低电平
        PPM_Out_L
        TIMER_SetAutoreload(TIMER2,499);
        ppm_count++;
        break;
    case 7://第四通道开始
        PPM_Out_H
        time=((float)ppm_data[3]/819.0)*200+499;
		toal_time+=time;
        TIMER_SetAutoreload(TIMER2,(u32)time);
        ppm_count++;
        break;
    case 8://第四通道结束,开始0.5ms低电平---------------(4)
        PPM_Out_L
        TIMER_SetAutoreload(TIMER2,499);
        ppm_count++;
        break;
    case 9://四路信号结束,20ms剩下的时间高电平----------(5)
        PPM_Out_H
		time=17500-toal_time;
        TIMER_SetAutoreload(TIMER2,time);
        ppm_count++;
        break;
    case 10://重新开始---------------------------------(6)
        PPM_Out_L
        TIMER_SetAutoreload(TIMER2,499);
		toal_time=0;//通道高电平清零,重新开始
        ppm_count=1;
    }

}
  1. 第一通道的起始信号0.5ms低电平结束,根据摇杆通道的AD采样值去计算第一通的高电平时间,GD32F130的ADC是12位的,若摇杆打到最高,采样值为4095,根据前面所说的PPM对应高电平应该为1.5ms,所以Time=(采样值/4095)*1000+499,程序里化简了。累加通道高电平时间,便于最后计算剩下的高电平时间。调用TIMER_SetAutoreload(TIMER2,(u32)time)改变定时器重装载值,步骤计数加一。
  2. 第一通道结束,开始0.5ms的第二通道起始信号

  3. 同1,计算通道二的高电平时间。

  4. 四个通道都结束了,以一个0.5ms的低电平时间结束。

  5. 计算剩下的高电平时间,因为一共四通道,所以四个0.5ms的通道起始信号,加上最后一个0.5ms的结束信号,20ms还剩下17.5ms,减去四个通道的高电平累加时间,就是最后的高电平时间

  6. 一个ppm信号结束了,重新开始下一个新的PPM信号。

以上仅为个人理解,实践使用该程序,可以玩凤凰模拟器。如有错误,请指正。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机模拟输出PPM信号 的相关文章

  • 数字直流电源设计

    设计目标 xff1a 市电输入 开关频率50KHz 60V 20A 1200W输出 输出电压纹波0 2 输出电流纹波20 效率0 8 1 确定输入电压 经查阅 xff0c 我国市电电压标准 xff0c 220V单相供电时 xff0c 为额定
  • CAN报文格式

    CAN协议的报文传输过程中有 数据帧 远程帧 错误帧 过载帧和帧间隔 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 1 数据帧 用于发送节点向接收节点传送数据的帧 nbsp nbsp nbsp nbsp nbsp n
  • FreeRTOS调度器启动

    nbsp 在真正启动调度器之前 先创建空闲任务 初始化一些变量 真正启动调度器的函数是xPortStartScheduler 启动调度器 void vTaskStartScheduler void BaseType t xReturn if
  • 安装novnc,并加入开机自启

    1 安装git工具 apt get install git y 2 下载novnc git clone https github com novnc noVNC 3 ls 查看 xff0c 已经下载完成 4 vim novnc sh把启动命
  • 【C++初阶11-模版进阶】解锁C++模版更多玩法

    今天 xff0c 带来模版进阶的讲解 主要讲解 xff1a 非类型模版参数模版的特化模版的分离编译 文中不足错漏之处望请斧正 xff01 非类型模版参数 模版参数分为类型模版参数和非类型模版参数 可以这么理解 xff1a 前者是为了泛化类型
  • Qt 获取当前时间

    1 获取带日期的时间 xff0c 使用QDateTime类 QDateTime current date time 61 QDateTime currentDateTime QString current date 61 current d
  • Qt 判断文件或文件夹是否存在及创建文件夹

    1 判断文件夹是不是存在 参数说明 xff1a QString fullPath 文件夹全路径 方法1 bool isDirExist QString fullPath QDir dir fullPath if dir exists ret
  • Qt阻塞延时与非阻塞延时(四种方法之个人笔记)

    功能描述 毫秒级非阻塞延时函数 参数 延时毫秒数 其他说明 已试验 可用 但CPU占用率较高 void VdpuMngUI msecSleep int msec QTime dieTime 61 QTime currentTime addM
  • 获取本机所有网卡的网卡名、网卡描述、网卡MAC地址、网卡IP、网卡类型等信息及网线是否插入状态

    使用windows sdk提供的API函数GetAdaptersInfo 可以获得本机所有网卡的网卡名 网卡描述 网卡MAC地址 网卡IP 网卡类型等信息 xff0c 并用IP ADAPTER INFO结构体存储 xff0c 使用GetIf
  • C++ GUI Programming with Qt4 Second Edition 之 附录C.1 Qt Jambi入门

    Qt Jambi入门 本节 xff0c 我们将开发一个简单的Java应用程序并显示如图C 1所示的窗口 除窗口标题之外 xff0c Jambi Find对话框与第二章中创建的Find对话框的外观和功能均相同 通过使用相同的例子 xff0c
  • WinRAR 5.5 简体中文版去广告弹窗方法

    WinRAR 5 5 简体中文版去广告弹窗方法 1 下载WinRAR 5 5WinRAR官网 xff08 http www rarlab com xff09 2 下载 Resource Hacker 3 用压缩软件打开WinRAR安装包 x
  • C++子类的构造函数后面加:冒号的作用

    在C 43 43 类的构造函数中经常会看到如下格式的写法 xff1a MyWindow MyWindow QWidget parent Qt WindowFlags flag QMainWindow parent flag 上述语句中单冒号
  • “真相”重要吗?

    这是一篇个人思索的鸡汤 xff0c 并不想表达什么观点 xff0c 只是因为有了要写的冲动才写的 言归正传 xff0c 我认为 真相很重要 周末回老家看了一岁半儿子 xff0c 从国庆送回老家已经一个半月了 周日下午我临走时 xff0c 他
  • TDD(测试驱动开发)

    今天看到的新的有意思的名词 xff0c 在此将其记录下来 一 TDD是什么 xff1f Test Drive Development xff0c 是敏捷开发中的一项核心实践和技术 也是一种设计方法论 xff0c 其基本思想就是 xff1a
  • c++ 常见的一些问题总结

    目录 目录 1 深拷贝 xff08 string xff09 深拷贝的实现 xff08 xff09 2 迭代器失效 xff08 vector insert xff0c earse xff09 3 头文件展开问题 4 vector 的深浅拷贝
  • airflow 文档学习(二) - 概念

    1 核心功能 1 1 DAGs 有向无环图 反映所涉及的task的依赖关系 注 xff1a 搜索dag的时候 xff0c airflow只会关注同事包含 34 DAG 34 和 34 airflow 34 字样的py文件 1 2 scope
  • 2014创新工场校园招聘笔试题(9.16北京)

    选择题 1 若进栈序列为a b c d xff0c 进栈过程中可以出栈 xff0c 那么 xff08 xff09 不可能是一个出栈序列 A cbad B bdca C adbc D cdba 2 完全二叉树中编号为i的结点存在右孩子 xff
  • 2014美团校园招聘笔试(10.8北京)

    按照试卷要求不能透露题目具体内容 xff0c 因此本文只写考点 一共六道大题 xff0c 如下 xff1a Q1 基础题 xff0c 给出中序后序 xff0c 求前序 Q2 概率题 xff0c 求期望 Q3 概率题 xff0c 求可能性 Q
  • 2014去哪儿网校园招聘笔试(10.13北京)

    三道大题 43 两题TestCase 编程题 Q1 xff1a 实现一个字符串反转 xff0c 规则如下 xff1a 输入一个字符串str xff0c 一个分隔符delim xff0c 要求实现对分隔符之间的字符串做反转操作 xff0c 但
  • 图像处理算法工程师职位面试题汇总

    最近面试了几个图像的职位 xff0c 汇总一下面试题 图像基础知识 xff1a 1 常用的图像空间 2 简述你熟悉的聚类算法并说明其优缺点 3 请描述以下任一概念 xff1a SIFT SURF LDA PCA 4 请说出使用过的分类器和实

随机推荐

  • 软件开发职位面试题汇总

    10 19 去哪儿面试 1 struct和class的成员函数调用1000次后有什么执行效率方面的差异 xff1f 2 给两个int型数组A和B xff0c 长度都为n xff0c 编程实现A B 61 a1 b1 43 a2 b2 43
  • iOS8 新特性

    苹果公司在WWDC 2014上发布了许多新特性 xff0c 让我们一起来看看都有哪些内容 Contents App Extensions Touch ID Authentication Photos Games Health Kit Fra
  • 获取当前view所在页面的viewController

    一般来说 xff0c 我们可以知道一个viewController所在的view self view xff0c 或者它的子视图 self subViews 然而 xff0c 怎样知道一个view所在页面的viewController呢 x
  • [iOS] Get all UIView subviews with all property values

    转自StackOverFlow span class com style margin 0px padding 0px border 0px color rgb 128 128 128 background transparent span
  • Upgrading the delete confirmation button

    本文转载自andy heydon个人博客 ANDY HEYDON ARCHIVES ABOUT Upgrading the delete confirmation button by Andy iOS has a nice pattern
  • Linux系统的GPIO设置(以UpBoard为例)

    GPIO往往是通过sys文件系统进行操作的 xff0c 当我们需要验证一个GPIO口置1还是置0的话 xff0c 可以通过操作sys文件来完成 UpBoard官方所提供的linux系统已经安装了支持UP Board的RPi GPIO和相应的
  • ubuntu远程桌面

    xff08 一 xff09 可视化界面远程访问Linux服务器 这里以Ubuntu为例 xff0c 最常见的是通过xrdp和vnc这两种远程桌面协议来进行可视化远程操作 1 关于xrdp协议和vnc协议之间区别 参考自 xff1a http
  • 针对Linux 错误make: *** No rule to make target ` ‘, needed by xxx. Stop. (webots调试出现这个错误,原因相同)

    导致出现make No rule to make target 96 needed by xxx Stop 的主要原因就是因为Makefile出现问题 xff0c 编写Makefile的时候多加了空格 括号等原因导致报这个错误 具体的参考实
  • eigen库的安装与基本使用教程

    Eigen是可以用来进行线性代数 矩阵 向量操作等运算的C 43 43 库 xff0c 它里面包含了很多算法 在用C 43 43 写运动控制算法 xff08 例如MPC控制算法 xff09 的时候 由于算法包括矩阵运算 xff0c c 43
  • CMakeLists.txt的简单学习教程汇总

    最近因为要编辑一个T265的例程 xff0c 但是里面的CMakeLists中的含义自己不明白 xff0c 在网上搜集了一些资料 xff0c 对自己学习进行一下总结也是让需要的人更加明白清楚 学习这个的最好的方式是自己理解了以后 xff0c
  • LEGION联想Y7000P Ubuntu18.04的无线网卡驱动安装

    安装无线网卡的驱动的第一步大家应该弄清楚自己的无线网卡型号 建议最好的方式是在Windows下面确定类型 xff0c 在设备管理器中查看对应的无线适配器型号 xff0c 在下载对应的驱动 在Ubuntu下面也可以通过指令进行查看但是看不到具
  • 向量点乘(即内积)和叉乘(即外积、向量积)区别与意义分析

    向量之间的叉乘和点乘 xff0c 概念易混淆 xff0c 分别不清楚 xff0c 因此本文专门对这个概念进行了详细分析介绍 首先 xff0c 介绍一下向量 xff08 Vector xff09 xff0c 在几乎所有的几何问题中 xff0c
  • MATLAB图中加入阴影

    在绘制MATLAB 图时 xff0c 想表示不同的阶段 xff0c 所以将其中一部分用阴影颜色强调出来 xff0c 因此进行了一下绘制图像的知识补充 其中想要的效果是类似于下面这张 xff1a 具体如何实现呢 xff0c 有两种方式 xff
  • Matlab调整子图位置及大小

    为了绘制多个子图的MATLAB图 xff0c 但是使用导出设置时无法将子图全屏铺满整个屏幕 xff0c 因此本文对设置MATLAB子图位置进行了研究 xff0c 达到如下的效果 1 首先 xff0c 明确其中每个变量的含义 xff0c 从M
  • excel计算出均方根值(RMS)+ 均方根误差(RMSE)+标准差(Standard Deviation)

    首先弄明白这几者的区别 xff0c 方差 标准差和均方根误差的区别总结 均方根值 xff08 RMS xff09 43 均方根误差 xff08 RMSE xff09 43 标准差 xff08 Standard Deviation xff09
  • Matlab画图和点标记

    从csv中导出数据 xff0c 然后需要在MATLAB图中进行标记个别点 xff0c 但是利用MTALB自身标记的比较丑 xff0c 因此搜了一下别的方法 xff0c 具体效果如下 xff0c 其中的 可以改成O或者其他的自定义的符号 xf
  • word因导入mathtype不能使用复制粘贴快捷键的解决方法

    经查阅有两种解决方式 xff1a 1 直接删除你安装的原office中的MathType Commands 2016 dotm这个文件 2 是更换为mathtype里面的文件 xff0c 具体过程如下两个参考 xff1a 官网给出的解决办法
  • 强力推荐90个优秀外国英文网站

    一 大陆可访问的优秀英文信息源 1 英国 经济学家 http www economist com 2 美联社 http wire ap org GoToAP cgi 3 英国BBC http news bbc co uk 4 纽约时报 ht
  • 学习笔记(01):MFC上位机与STM32下位机通讯精讲-STM32串口实战1之串口发送1(串口初始化实践)...

    立即学习 https edu csdn net course play 6375 122556 1 GPIO PinAFConfig 函数复用功能 xff0c 将GPIO和USART连接起来
  • 单片机模拟输出PPM信号

    PPM信号就是将多个PWM信号放在一起传输 xff0c 一个PPM的周期为20ms 其中一个通道信号的范围为1 2ms 所以一个PPM信号 xff0c 最多可以传输10个通道的PWM信号 PPM信号以0 5ms的低电平信号代表一个通道的起始