STM32 TIM1输入捕获测试输入信号的频率
测试芯片STM32F103C8T6,外部时钟
1、输入捕获通道测试
TIM1的CH1N,无法进行输入捕获(估计是没找到其他原因,测试就也没有测试出来效果),直接改用TIM1的CH1通道进行测试,可以进行捕获中断测试;
在用CH1的通道输入捕获配置时,必须TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;对此初始化,第一次测试发现这个参数默认是10,不知道什么原因,后来加上这句好就好了,意思代表的是多少次计数周期更新一次中断事件;
2、输入捕获中断中不要做太多事情,尽量用寄存器操作
初始配置采用的上升沿配置,在捕获中断中更改捕获中断的沿方式;
一进入捕获中断,先对TIM1->CNT = 0;,然后再是其他操作,注意操作顺序,顺序不同会导致误差不同,见代码;
3、设置的存储计数器的值,采用的变量类型是volatile,否则会导致偶尔数据不对;
4、在用串口显示测试信号的信息时,会关闭总中断,执行结束后,再打开,否则会导致偶尔数据不对;
5、实际用捕获中断进行捕获时,总会存在误差的,在此我在串口输出显示时,做了矫正处理,每个处理器不同,矫正的大小也不同,尤其在TIM1更新中断发生时,产生的误差更大;
6、用PB0(输出PWM)和PA8(检测信号频率)进行测试的
当PB0输出较低频率时,会导致TIM_Period超过65535,实际测试好像超过也没什么问题;
//
/*************************1---main函数串口信息打印********************************/while(1){if(delayFlag == 1)//定时1s{delayFlag = 0; if(IC_OccurFlag == 1){__disable_irq();CheckNoSignalCount = 0;IC_OccurFlag = 0;// LED_On_OFF();PWM_OverFlow_temp1 = PWM_OverFlow_temp11;PWM_OverFlow_temp2 = PWM_OverFlow_temp22;IC1_High_temp = IC1_High;IC1_Low_temp = IC1_Low+81;//矫正,只需矫正这一个,高电平不用矫正printf("高电平溢出次数:%d \r\n",PWM_OverFlow_temp1);printf("低电平溢出次数:%d \r\n",PWM_OverFlow_temp2);while(PWM_OverFlow_temp1--){IC1_High_temp += (65536-5528);//矫正}while(PWM_OverFlow_temp2--){IC1_Low_temp += (65536-5528);//矫正}printf("高电平时间:%.1f us\r\n",IC1_High_temp/Calc_PWM_TimerFreq_M);printf("低电平时间:%.1f us\r\n",IC1_Low_temp/Calc_PWM_TimerFreq_M);TestPWM_Period = (float)((float)IC1_High_temp+IC1_Low_temp)/Calc_PWM_TimerFreq_M;printf("测试信号周期:%.1f us\r\n",TestPWM_Period);TestPWM_Freq = (float)(1000000.0f)/TestPWM_Period;printf("测试信号频率:%.2f HZ\r\n",(TestPWM_Freq));printf("-----------------------------------------\r\n");IC1_High_temp = IC1_Low_temp = 0;__enable_irq();}else{if(CheckNoSignalCount++ >= 3){CheckNoSignalCount = 3;printf("没有检测到测试信号\r\n"); }}} if(EXTIFlag == 1){EXTIFlag = 0;printf("外部中断进入");}}/*************************2---PWM输出信号********************************/
#ifndef __PWM_OUT_H
#define __PWM_OUT_H
#include "stm32f10x.h"#define PWM_Out_GPIO GPIOB
#define PWM_Out_Pin GPIO_Pin_0
#define PWM_Out_Timer TIM3
#define PWM_Out_TimerFreq (u32)(72000000)
#define PWM_Out_TimerPre (u16)(72)
#define PWM_Out_Freq (u16)(1200)//
#define PWM_Out_TimerPeriod (u16)(PWM_Out_TimerFreq/PWM_Out_TimerPre/PWM_Out_Freq)void PWM_OUT_Config(void);
#endif#include "PWM_Out.h"void PWM_OUT_Config(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;GPIO_InitTypeDef GPIO_InitStructure;TIM_OCInitTypeDef TIM_OCInitStructure;//定义结构体RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE );RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能GPIO_InitStructure.GPIO_Pin = PWM_Out_Pin;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 上拉输入GPIO_Init(PWM_Out_GPIO, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = PWM_Out_TimerPeriod; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500msTIM_TimeBaseStructure.TIM_Prescaler = PWM_Out_TimerPre-1; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(PWM_Out_Timer, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//选择定时器模式,TIM脉冲宽度调制模式2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//输出比较极性低TIM_OC3Init(PWM_Out_Timer, &TIM_OCInitStructure);//根据结构体信息进行初始化TIM_OC3PreloadConfig(PWM_Out_Timer, TIM_OCPreload_Enable); //使能定时器TIM2在CCR2上的预装载值TIM_Cmd(PWM_Out_Timer, ENABLE); TIM_SetCompare3(PWM_Out_Timer,(u32)PWM_Out_TimerPeriod*3/4);//得到占空比为50%的pwm波形
}/*************************3---检测信号的频率********************************/
#ifndef __CALC_PWM_H
#define __CALC_PWM_H
#include "stm32f10x.h"#define Calc_PWM_GPIO GPIOA
#define Calc_PWM_Pin GPIO_Pin_8
#define Calc_PWM_Timer TIM1
#define Calc_PWM_TimerFreq (u32)(72000000)
#define Calc_PWM_TimerFreq_M (u32)(Calc_PWM_TimerFreq/1000000)
#define Calc_PWM_TimerPre (u16)(1)
#define Calc_PWM_Freq (u16)(1200)//测试最小PWM频率
#define Calc_PWM_TimerPeriod (u16)(Calc_PWM_TimerFreq/Calc_PWM_TimerPre/Calc_PWM_Freq)//此值最大65535 ;833us的周期时间extern volatile float IC1_High,IC1_Low,IC1_Period;
extern volatile float IC1_High_temp,IC1_Low_temp;
extern volatile u8 IC_OccurFlag;
extern volatile u8 Control_OccurFlag;
extern volatile u16 PWM_OverFlow,PWM_OverFlow_temp1,PWM_OverFlow_temp11,PWM_OverFlow_temp2,PWM_OverFlow_temp22;
void Calc_PWM_Config(void);
#endif#include "Calc_PWM.h"volatile float IC1_High,IC1_Low,IC1_Period;
volatile float IC1_High_temp,IC1_Low_temp;
volatile u8 IC_OccurFlag;
volatile u8 Control_OccurFlag;
volatile u16 PWM_OverFlow=0,PWM_OverFlow_temp1,PWM_OverFlow_temp11,PWM_OverFlow_temp2,PWM_OverFlow_temp22;
void Calc_PWM_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;NVIC_InitTypeDef NVIC_InitStructure;TIM_OCInitTypeDef TIM_OCInitStructure;//定义结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE );GPIO_InitStructure.GPIO_Pin = Calc_PWM_Pin;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //GPIO_Mode_IN_FLOATING GPIO_Mode_Out_PP GPIO_Mode_AF_PPGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(Calc_PWM_GPIO, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = Calc_PWM_TimerPeriod; TIM_TimeBaseStructure.TIM_Prescaler = Calc_PWM_TimerPre-1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
// TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(Calc_PWM_Timer, &TIM_TimeBaseStructure);TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICInitStructure.TIM_ICFilter = 0x0;TIM_PWMIConfig(Calc_PWM_Timer, &TIM_ICInitStructure);TIM_SelectInputTrigger(Calc_PWM_Timer, TIM_TS_TI1FP1);TIM_SelectSlaveMode(Calc_PWM_Timer, TIM_SlaveMode_Reset);TIM_SelectMasterSlaveMode(Calc_PWM_Timer,TIM_MasterSlaveMode_Enable);//
// TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//选择定时器模式,TIM脉冲宽度调制模式2
// TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
// TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//输出比较极性低
// TIM_OC1Init(Calc_PWM_Timer, &TIM_OCInitStructure);//根据结构体信息进行初始化
// TIM_OC1PreloadConfig(Calc_PWM_Timer, TIM_OCPreload_Enable); //使能定时器TIM2在CCR2上的预装载值TIM_ClearITPendingBit(Calc_PWM_Timer,TIM_IT_Update);TIM_ITConfig(Calc_PWM_Timer, TIM_IT_CC1, ENABLE);TIM_ITConfig(Calc_PWM_Timer, TIM_IT_Update, ENABLE);TIM_Cmd(Calc_PWM_Timer, ENABLE);
// TIM_SetCompare1(Calc_PWM_Timer,Calc_PWM_TimerPeriod/3);//得到占空比为50%的pwm波形//TIM_CtrlPWMOutputs(TIM1, ENABLE); //pwm输出NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;//捕获中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;//更新中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}extern void Test_PA1_HighLow(void);
extern void Test_PA1_High(void);
extern void Test_PA1_Low(void);void TIM1_UP_IRQHandler(void)
{if(TIM_GetITStatus(Calc_PWM_Timer,TIM_IT_Update) != RESET){//Test_PA1_HighLow();TIM_ClearITPendingBit(Calc_PWM_Timer, TIM_IT_Update);PWM_OverFlow++;}}void TIM1_CC_IRQHandler(void)
{if (TIM_GetITStatus(Calc_PWM_Timer, TIM_IT_CC1) != RESET) {// Calc_PWM_Timer->SR = ~(TIM_IT_CC1);// if(Control_OccurFlag == 1)
// {
// if(IC1_High>14200)//
// {
// Calc_PWM_Timer->CNT = 0;
// }
// }Calc_PWM_Timer->CNT = 0;//if(TIM1->CCER & 0X0002)//判断下降沿{//TIM_OC1PolarityConfig(Calc_PWM_Timer,TIM_OCPolarity_High);IC1_High = Calc_PWM_Timer->CCR1;//TIM_GetCapture1(Calc_PWM_Timer);PWM_OverFlow_temp11 = PWM_OverFlow;PWM_OverFlow = 0;TIM1->CCER &= 0XFFFD;IC_OccurFlag = 1;}else{// TIM_OC1PolarityConfig(Calc_PWM_Timer,TIM_OCPolarity_Low);IC1_Low = Calc_PWM_Timer->CCR1;//TIM_GetCapture1(Calc_PWM_Timer);//Calc_PWM_Timer->CNT = 0;PWM_OverFlow_temp22 = PWM_OverFlow;PWM_OverFlow = 0;TIM1->CCER |= 0X0002;}TIM_ClearITPendingBit(Calc_PWM_Timer, TIM_IT_CC1|TIM_IT_Update);////Calc_PWM_Timer->CNT = 0;//加上这句,实际测试信号周期时间偏小;}
}
STM32 TIM1输入捕获测试输入信号的频率相关推荐
- STM32 输入捕获的脉冲宽度及频率计算
输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...
- stm32采集脉冲信号_STM32 输入捕获的脉冲宽度及频率计算
输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.以下是对脉冲宽度及频率的计算. 1.脉冲宽度 如下图所示,采集该高电平脉冲 ...
- STM32定时器输入捕获
5.STM32定时器输入捕获 前言: STM32定时器输入捕获简介 STM32的输入捕获可以用于捕获脉宽, 测量时间 . 例如超声波测距模块就是需要用输入捕获功能, 通过测量输入脉冲的高电平脉宽 , ...
- stm32 PWM输入捕获
普通的输入捕获,可使用定时器的四个通道,一路捕获占用一个捕获寄存器. PWM输入,只能使用两个通道,通道1和通道2. 一路PWM输入占用两个捕获寄存器,一个捕获周期,一个捕获占空比. 这里,用通用定时 ...
- STM32之输入捕获
今天来简单介绍一下STM32的输入捕获功能.输入捕获说的通俗一点就是用计数器(定时器)来记录某一个脉冲高电平的时间,或者我们只捕获脉冲的上升沿或者下降沿,这具体要根据具体事例进行分析. 它的基本工作过 ...
- stm32捕获占空比_「话说定时器系列」之六:STM32定时器输入捕获话题
STM32定时器是 ST MCU 内部最基础且常用的外设,实际应用尤为普遍.去年,电堂推出了<STM32 TIMER基础及常规应用介绍>,为大家梳理了 STM32 TIMER 的庞大内容, ...
- STM32处理器输入捕获分析
前言: 1.博文基于ARM Cortex-M3内核的STM32F103ZET6芯片和标准3.5.0库: 2.如有不足之处,还请多多指教: ** 一 基本知识 ** 输入捕获的功能:用来测量脉宽或者测量 ...
- 【STM32】输入捕获实验代码详解
文章目录 main.c timer.c timer.h main.c #include "led.h" #include "delay.h" #include ...
- 【STM32】输入捕获程序
00. 目录 文章目录 00. 目录 01. 概述 02. 硬件设计 03. 寄存器概述 04. 配置步骤 05. 程序示例 06. 附录 07. 声明 01. 概述 输入捕获模式可以用来测量脉冲宽度 ...
最新文章
- 批量提取文件创建时间_批量采集新浪微博用户内容
- leetcode1045. 买下所有产品的客户(SQL)
- odoo12 日历模块_日历-ODOO ERP界面布局与操作说明|ODOO 13教程
- 【STM32】【STM32CubeMX】STM32CubeMX的使用之一:工程建立之点亮你的LED
- 按键精灵打卡怎么写_[按键精灵教程]过新手引导的各种姿势
- git 修改tag 备注_【Git】第十二章:Git高级实战技巧
- 11th Iran Nationwide Internet Contest 解题报告
- python小波包分解_Matlab小波包分解后如何求各频带信号的能量值?
- 计算机重装操作系统的软件,重装系统后的装机必备软件电脑推荐
- 微信小程序在手机上预览时出现白屏
- java怎么实现复杂的考勤计算_考勤系统之计算工作小时数
- 电脑计算机怎么显示到桌面,怎么显示我的电脑到桌面
- 初识c语言加操作系统
- 笔记10.9:硬盘、计算机启动过程、缓冲缓存
- C#中Int64和UInt64之间的区别
- 表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)
- openlayers 3扩展,调用百度地图、高德地图、天地图服务
- Java日志框架-SLF4J入门
- 关于SNS概念的详细说明
- UBOOT学习1——UBOOT移植流程
热门文章
- 第一节项目整体管理学习笔记
- Revit机电翻模插件【管线编辑】跨系统分类
- iOS字体不清晰问题
- RocketMQ—苹果mac电脑os系统单节点安装下载RocketMQ步骤
- 如何用计算机打出我是你爸爸,单元格打字怎么,我们可以借助excel工具箱进行实现...
- 如何设计一张数据库表
- C++Win10终结者病毒
- 电脑和手机的软件推荐
- android 锁屏 广告,华为手机锁屏后总是出现广告该怎么办?-安卓手机屏幕解锁后总是有个广告...
- php upush 友盟 推送_react-native集成友盟推送