STM32定时器输入捕获航模接收机信号

2024-02-22 09:50

本文主要是介绍STM32定时器输入捕获航模接收机信号,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32定时器输入捕获航模接收机信号

  • 前言
  • 一、舵机信号(PWM)
  • 二、STM32输入捕获功能框图
  • 三、输入捕获初始化结构体定义及说明
  • 三、代码


前言

最近在做一个检测航模接收机输出的舵机信号,并根据信号不同执行相应功能的小项目。硬件部分使用的是STM32F103C8T6通用定时器TIM3的通道1和通道2分别做两路信号的输入捕获(Input Capture)。


提示:以下是本篇文章正文内容,下面案例可供参考,如有错误,欢迎批评指正!

一、舵机信号(PWM)

PWM就是脉冲宽度调制,也就是占空比可调的脉冲信号。航模接收机输出的舵机PWM信号一般是频率为50HZ即周期为20ms,信号的高电平时间在1000us-2000us之间变化的PWM波,并且当遥控器打到中位时,信号高电平时间为1500us,如下图所:
在这里插入图片描述

二、STM32输入捕获功能框图

STM32F103通用定时器输入捕获功能框图如下所示,主要包括捕获通道选择、滤波器设置、捕获极性设置、映射关系设置及分频器配置等部分。在这里插入图片描述

三、输入捕获初始化结构体定义及说明

STM32标准库的stm32f10x_tim.h中定义了定时器输入捕获初始化结构体:

/** * @brief  TIM Input Capture Init structure definition  */typedef struct
{uint16_t TIM_Channel;      /*!< 输入通道选择,共4个通道。TIM_Channel_1->TIM_Channel_4 */uint16_t TIM_ICPolarity;   /*!< 输入捕获极性设置,可选择上升沿捕获或下降沿捕获或两者都可捕获。TIM_ICPolarity_Rising/TIM_ICPolarity_Falling/TIM_ICPolarity_BothEdge */uint16_t TIM_ICSelection;  /*!< 输入捕获通道选择,共3个通道。TIM_ICSelection_DirectTI/TIM_ICSelection_IndirectTI/TIM_ICSelection_TRC */uint16_t TIM_ICPrescaler;  /*!< 输入捕获通道预分频。可设置分频因子为1、2、4、8*/uint16_t TIM_ICFilter;     /*!< 输入捕获滤波器设置。可设置为0x00到0x0F,一般不用设置为0x00 */
} TIM_ICInitTypeDef;

三、代码

#include "drv_pwm.h"u8 TIM3_CHL1_CaptureFlag;												// TIM3 CH1捕获标志 
u32 TIM3_CHL1_Rising_Value ;											// TIM3 CH1捕获上升沿值
u32 TIM3_CHL1_Falling_Value ;											// TIM3 CH1捕获下降沿值
u16 TIM3_CHL1_PWM1_pulse;												// TIM3 CH1捕获PWM脉宽数值u8 TIM3_CHL2_CaptureFlag;												// TIM3 CH2捕获标志 
u32 TIM3_CHL2_Rising_Value ;											// TIM3 CH2捕获上升沿值
u32 TIM3_CHL2_Falling_Value ;											// TIM3 CH2捕获下降沿值
u16 TIM3_CHL2_PWM1_pulse;												// TIM3 CH2捕获PWM脉宽数值void drv_pwm_init(void)
{GPIO_InitTypeDef GPIO_InitStruct;TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_ICInitTypeDef TIM_ICInitStruct;NVIC_InitTypeDef NVIC_InitStruct;/* 打开GPIO时钟 */RCC_APB2PeriphClockCmd(TIMX_PORT_CLK, ENABLE);/* 打开定时器时钟 */RCC_APB1PeriphClockCmd(TIMX_CLK,  ENABLE); /* 初始化PA6/PA7为下拉输入 */GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;     GPIO_InitStruct.GPIO_Pin = PWM_TIMX_CHL1_PIN | PWM_TIMX_CHL2_PIN ;GPIO_Init(TIMX_PORT, &GPIO_InitStruct);GPIO_ResetBits(TIMX_PORT,PWM_TIMX_CHL1_PIN);GPIO_ResetBits(TIMX_PORT,PWM_TIMX_CHL2_PIN);/* 初始化定时器1配置 */TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;    	// 向上计数TIM_TimeBaseInitStruct.TIM_Period = 65535 - 1;TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;      				// 1usTIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIMX, &TIM_TimeBaseInitStruct);/* 初始化定时器3中断 */NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStruct.NVIC_IRQChannelSubPriority = TIMX_INTERRUPT;NVIC_Init(& NVIC_InitStruct);/* 初始化定时器3捕获通道1配置 */TIM_ICInitStruct.TIM_Channel = PWM_TIMX_CHL1 ;TIM_ICInitStruct.TIM_ICFilter = 0x00;TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling;    		// 下降沿开始捕获(由于原理图中光耦对PWM做了反向,所以下降沿开始捕获)TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInit(TIMX, &TIM_ICInitStruct);/* 初始化定时器3捕获通道1配置 */TIM_ICInitStruct.TIM_Channel = PWM_TIMX_CHL2 ;TIM_ICInitStruct.TIM_ICFilter = 0x00;TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling;    		// 下降沿开始捕获(由于原理图中光耦对PWM做了反向,所以下降沿开始捕获)TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInit(TIMX, &TIM_ICInitStruct);/* 使能 */TIM_ITConfig(TIMX,TIM_IT_CC1,ENABLE);TIM_ITConfig(TIMX,TIM_IT_CC2,ENABLE);/* 使能定时器 */TIM_Cmd(TIMX, ENABLE);
}void TIM3_IRQHandler(void)
{OS_CPU_SR cpu_sr = (OS_CPU_SR)0;OS_ENTER_CRITICAL();OSIntEnter();OS_EXIT_CRITICAL();if(TIM_GetITStatus(TIMX, TIM_IT_CC1) == SET){TIM_ClearITPendingBit(TIMX, TIM_IT_CC1);   						// 清除标志位if (TIM3_CHL1_CaptureFlag == 1){TIM3_CHL1_Rising_Value = TIM_GetCapture1(TIMX);       		// 获取当时检测到上升沿时候CCR寄存器的计数值if (TIM3_CHL1_Rising_Value < TIM3_CHL1_Falling_Value)       // 说明当时获取CCR的值大于65535Temp1_Value = 65535;elseTemp1_Value = 0;TIM3_CHL1_PWM1_pulse = TIM3_CHL1_Rising_Value - TIM3_CHL1_Falling_Value + Temp1_Value;	// 计算出PWM1脉宽值			TIM3_CHL1_CaptureFlag = 0;TIM_OC1PolarityConfig(TIMX, TIM_ICPolarity_Falling);    	// 设置下降沿捕获}else if (TIM3_CHL1_CaptureFlag == 0){TIM3_CHL1_Falling_Value = TIM_GetCapture1(TIMX);        	// 获取当时检测到下降沿时候CCR寄存器的计数值TIM3_CHL1_CaptureFlag = 1;TIM_OC1PolarityConfig(TIMX, TIM_ICPolarity_Rising);       	// 设置上升沿捕获}}if(TIM_GetITStatus(TIMX, TIM_IT_CC2) == SET){TIM_ClearITPendingBit(TIMX, TIM_IT_CC2);   						// 清除标志位if (TIM3_CHL2_CaptureFlag == 1){TIM3_CHL2_Rising_Value = TIM_GetCapture2(TIMX);       		// 获取当时检测到上升沿时候CCR寄存器的计数值if (TIM3_CHL2_Rising_Value < TIM3_CHL2_Falling_Value)       // 说明当时获取CCR的值大于65535Temp2_Value = 65535;elseTemp2_Value = 0;TIM3_CHL2_PWM1_pulse = TIM3_CHL2_Rising_Value - TIM3_CHL2_Falling_Value + Temp2_Value;	// 计算出PWM2的脉宽值TIM3_CHL2_CaptureFlag = 0;TIM_OC2PolarityConfig(TIMX, TIM_ICPolarity_Falling);    	// 设置下降沿捕获}else if (TIM3_CHL2_CaptureFlag == 0){TIM3_CHL2_Falling_Value = TIM_GetCapture2(TIMX);        	// 获取当时检测到下降沿时候CCR寄存器的计数值TIM3_CHL2_CaptureFlag = 1;TIM_OC2PolarityConfig(TIMX, TIM_ICPolarity_Rising);       	// 设置上升沿捕获}}OSIntExit();
}

TIM3_CHL1_PWM1_pulse 及TIM3_CHL2_PWM1_pulse 即为获取的两路PWM高电平的时间,单位为us。


提示:以上是本篇文章全部内容,如有错误,欢迎批评指正! ----2023年5月7日 南京 多云 微凉

这篇关于STM32定时器输入捕获航模接收机信号的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/734875

相关文章

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

无线路由器哪个品牌好用信号强? 口碑最好的三个路由器大比拼

《无线路由器哪个品牌好用信号强?口碑最好的三个路由器大比拼》不同品牌在信号覆盖、稳定性和易用性等方面各有特色,如何在众多选择中找到最适合自己的那款无线路由器呢?今天推荐三款路由器让你的网速起飞... 今天我们来聊聊那些让网速飞起来的路由器。在这个信息爆炸的时代,一个好路由器简直就是家庭网编程络的心脏。无论你

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu