STM32之输入捕获以及小小应用(库)
五一之际,先祝大家五一快乐、其实快乐很简单,工作的人有假放,学习的人也有假放,像我,有假放才有更多的时间学自己想学的东西、51假期学51,可惜没有32假期呀、好了、、言归正传,大家听过吸星大法吧、、在这里、智商和情商比我高的人估计又知道我要说什么了、、没错了、、今天我们来了解“葵花宝典”第STM32篇之输入捕获,也就是上文所讲的“吸星大法”,
那输入捕获可以用来干嘛呢??这个问题问的好,输入捕获可以用来测量脉冲宽度或者测量频率,假如要捕获一个脉冲的高电平脉宽,我们要怎么做呢??别急哈、、接下来我们从头慢慢的分析到脚、、
据老夫所知:STM32的输入捕获,就是通过检测通道上的边沿信号,在边沿信号发生跳变(比如说突然来个上升沿或者下降沿),计数器就把此刻的计数值存放到对应通道的捕获比较寄存器,就这样、、就捕捉到了“美女”、话是这么说、、可操作起来不仅仅是几句话、因为初始化和对捕获的处理是不一样的、所以,为了做好迎接捕获的准备,我们来介绍下几个比较陌生的位:
对于定时器的一些寄存器,在之前的博客都有涉及到,如
TIMx_CR1,
捕获/比较模式寄存器1(TIMx_CCMR1),
捕获/比较使能寄存器(TIMx_CCER),
计数器(TIMx_CNT)
预分频器(TIMx_PSC)
自动重装载寄存器(TIMx_ARR)
捕获/比较寄存器1(TIMx_CCR1)
我们再来看看捕获/比较模式寄存器1(TIMx_CCMR1),由于我们是用TIM5_CH1,所以该寄存器中
CC1S[1:0]:捕获/比较1选择 (Capture/Compare 1 selection)我们选择01:CC1通道被配置为输入,IC1映射在TI1上;这个知道为啥是TI1吗??请看我那销魂美丽的涂鸦:
这里我们检测高电平的宽度,所以我们检测的时候只要遇到上升沿就触发捕获一次,但是我们要怎么设置呢,请看这几位:
IC1PSC[1:0]:输入/捕获1预分频器 (Input capture 1 prescaler)00:无预分频器,捕获输入口上检测到的每一个边沿都触发一次捕获;
神奇吧,好了,IC1F[3:0]:输入捕获1滤波器 (Input capture 1 filter)(这个就是上图中的输入滤波器,在这里我们不做滤波处理,为什么,请看以下解释)
在这里解释下:数字滤波器由一个事件计数器组成,它记录到N个事件后会产生一个输出的跳变:这个N可以取值具体参考中文手册,意思是说:我采样高电平,只有连续采样到N个电平是高电平的话我才认为是有效的高电平,低于N个我就认为是无效的、在这篇博客里,我们只要是采样到高电平就行,所以这里就不采用数字滤波。
我们来看看这个寄存器 捕获/比较使能寄存器(TIMx_CCER),要使捕获使能,我们就需要设置使能位
CC1E:输入/捕获1输出使能 (Capture/Compare 1 output enable)为0;
对于我们输入捕获后要处理的我们交给我们的中断,所以在这里我们要开启中断使能位
DMA/中断使能寄存器(TIMx_DIER) CC1IE:允许捕获/比较1中断 (Capture/Compare 1 interrupt enable)为1;
介绍了以上几位大神,接下来,我们要怎么个思路呢??==当我们捕获到上升沿时,我们把此时的CNT中的值读出来,然后等待下降沿的到来,这时候要分为两种情况:
第一:下降沿来了,我们就记录此刻CNT的值,(捕获值)然后重复以上动作
第二:下降沿没来,可是这时候定时器的计数值已经到了,也就是要溢出了,这时候要特殊处理下,也就是直接把计数值返回
(注:在这里,要注意捕获值跟计数值的差别,他们是不一样的、)至于为什么不一样,大家可以思考思考、、
所以我们将两次捕获的值相减,(下降沿的值减去上升沿的值)就可以得到高电平的脉宽了、、而这些事,我们都在中断服务函数里处理(中断喔、、想起没??要做什么知道吧、、注意,这时候有两个中断触发:更新中断和捕获中断,更新中断用来处理定时器计数溢出,捕获中断用来处理捕获事件)
接下来,我们看看我们具体的实现步骤
1:开启挂载在ABP1的TIM5时钟,开启挂载在ABP2的GPIOA的时钟,并初始化TIM5和GPIOA,由于这两个初始化前几篇博客有涉及到,故直接贴出代码:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); KEY_Init(); //IO我已在按键的函数里初始化了 TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM5, & TIM_TimeBaseStructure);
2、设置TIM_CH1的输入捕获功能,打开“stm3210x.tim.h”我们可以看到
typedef struct
{ uint16_t TIM_Channel; /*!< Specifies the TIM channel.设置通道
This parameter can be a value of @ref TIM_Channel */ uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.设置输入信号的有效捕获极性
This parameter can be a value of @ref TIM_Input_Capture_Polarity */ uint16_t TIM_ICSelection; /*!< Specifies the input. 设置映射关系
This parameter can be a value of @ref TIM_Input_Capture_Selection */ uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler. 设置捕获的分配系数
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ uint16_t TIM_ICFilter; /*!< Specifies the input capture filter. 设置数字滤波器的长度
This parameter can be a number between 0x0 and 0xF */
} TIM_ICInitTypeDef;
根据我们以上的了解,我们设置,请看以下代码:
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //通道1
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //不分频
TIM_ICInitStructure.TIM_ICFilter = 0x0; //不滤波
TIM_ICInit(TIM5, &TIM_ICInitStructure);
3、设置中断优先级、在这里比较简单,直接看代码:
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
4.使能中断并开启定时器
TIM_ITConfig(TIM5, TIM_IT_Update | TIM_IT_CC1, ENABLE ); TIM_Cmd(TIM5, ENABLE);
5、编写中断服务函数
u8 TM5_CH1_CAPTURE_STA = ;//8位0x00~0x80
u16 TM5_CH1_CAPTURE_VAL; //捕获高电平后定时器溢出的次数 void TIM5_IRQHandler(void)
{
if((TM5_CH1_CAPTURE_STA & 0x80) == ) //未成功捕获,0x80捕获完成
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) == SET) //数据更新中断产生
{
if(TM5_CH1_CAPTURE_STA & 0x40) //已经捕获到高电平
{
if((TM5_CH1_CAPTURE_STA & 0x3f)==0x3f) //溢出
{
TM5_CH1_CAPTURE_STA |= 0x80; //强制捕获成功
TM5_CH1_CAPTURE_VAL = 0xffff; //此时的计数值
}
else
{
TM5_CH1_CAPTURE_STA++;
} }
}
if(TIM_GetITStatus(TIM5, TIM_IT_CC1) == SET)//发生捕获
{
if(TM5_CH1_CAPTURE_STA & 0x40) //成功捕获到一次下降沿,但不是第一次捕获
{
TM5_CH1_CAPTURE_STA |= 0x80; //捕获成功
TM5_CH1_CAPTURE_VAL = TIM_GetCapture1(TIM5);//获取捕获值
TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Rising);//要设置为上升沿,等待下降沿的来临
}
else //第一次捕获
{
TM5_CH1_CAPTURE_STA = ;
TM5_CH1_CAPTURE_VAL = ;
TIM_SetCounter(TIM5, 0); //还没等到下降沿来时把所有的都清零
TM5_CH1_CAPTURE_STA |= 0x40;
TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Falling);//要设置成下降沿,等到上升沿的来临
} }
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1 | TIM_IT_Update); }
6、注意红色标注部分,好好理解刚开始说的计数值和捕获值的区别、还有
TIM_SetCounter(TIM5, 0); //设置计数器寄存器值
TIM_OC1PolarityConfig(TIM5, TIM_ICPolarity_Falling);//设置通道1输入捕获极性
这两个函数是库函数为我们提高的可以单独对通道进行操作的函数,非常方便
7、到这里,我们需要在主函数里稍微写下:
if(TM5_CH1_CAPTURE_STA & 0x80)
{
temp = (TM5_CH1_CAPTURE_VAL & 0x3f);
temp *= ; //计数器为0~65535,也就是65536一次
temp += TM5_CH1_CAPTURE_VAL;
printf("HIGH is %d\r\n",temp);
TM5_CH1_CAPTURE_STA = ;//这里因为我们在之前的捕获时,若捕获成功则为1,并没有清0,所以要进行下一次捕获的话,要在这里进行清零
}
8、好了,至于我标题说的小应用,也就是把我们上次PWM的输出给这次的输入捕获,大家通过串口就可以看到高电平的脉宽了。当然,在这篇博客的程序里也需要保留上次PWM输出的程序方可、、
9、大家肚子饿了吧、、吃饭去吧、、
今天五一,还是宅在宿舍学32,也很开心,因为学到了东西、、有假放开心、、有学到知识也开心,即使在学的过程中可能会被烦恼到、、其实快乐也很简单、只是看你怎么把握、、五月的开始、、将继续学stm32、、还有英语六级、、加油、、在这里、有错的地方希望能指教、、我也虚心的向您学习、、
STM32之输入捕获以及小小应用(库)的更多相关文章
- STM32使用定时器实现输入捕获
输入捕获简介输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能. STM32的输入捕获,简单地说就是通过检测TIMx_CHx上的边沿信 ...
- STM32之定时器输入捕获
1.输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能.STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿 ...
- stm32 输入捕获学习(一)
输入捕获模式可以用来测量脉冲宽度或者测量频率.STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能.STM32 的输入捕获,简单地说就是通过检测 TIMx_CHx 上的边沿信 ...
- STM32——输入捕获实验原理及配置步骤
输入捕获实验原理及配置步骤 一.输入捕获概念 STM32的输入捕获,简单的说就是通过检测 TIMx_CHx (定时器X的通道X)上的 边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定 ...
- STM32 HAL库学习系列第7篇---定时器TIM 输入捕获功能
测量脉冲宽度或者测量频率 基本方法 1.设置TIM2 CH1为输入捕获功能: 2.设置上升沿捕获: 3.使能TIM2 CH1捕获功能: 4.捕获到上升沿后,存入capture_buf[0], ...
- STM32 HAL库学习系列---定时器TIM 输入捕获功能
基本方法 1.设置TIM2 CH1为输入捕获功能: 2.设置上升沿捕获: 3.使能TIM2 CH1捕获功能: 4.捕获到上升沿后,存入capture_buf[0],改为捕获下降沿: 5.捕获到下降沿后 ...
- STM32输入捕获模式设置并用DMA接收数据
参考: STM32的PWM输入模式设置并用DMA接收数据 Input capture mode The input stage samples the corresponding TIx input ...
- STM32 输入捕获配置
在STM32 的定时器,除了 TIM6 和 TIM7,就是通过检测 TIMx_CHx 上的 边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候, 将当时定时器 的值(TIMx_CNT) 存放到对 ...
- stm32寄存器版学习笔记06 输入捕获(ETR脉冲计数)
STM32外部脉冲ETR引脚:TIM1-->PA12;TIMER2-->PA0:TIMER3-->PD2;TIMER4-->PE0… 1.TIM2 PA0计数 配置步骤 ①开启 ...
随机推荐
- Ninject学习(一) - Dependency Injection By Hand
大体上是把官网上的翻译下而已. http://www.ninject.90iogjkdcrorg/wiki.html Dependency Injection By Hand So what's Ni ...
- js_apply与call
在ECAMScript3给Function的原型定义了两个方法,它们是Function.prototype.call和Function.prototype.apply. 本文详细介绍了apply与ca ...
- Reverse Core 第二部分 - 14&15章 - 运行时压缩&调试UPX压缩的notepad
@date: 2016/11/29 @author: dlive 0x00 前言 周六周日两天在打HCTF2016线上赛,没时间看书,打完比赛接着看~~ 0x01 运行时压缩 对比upx压缩前后的no ...
- c模拟c++ const 转换
#include <stdio.h> int main(){ const int constant = 21; const int* const_p = &constant; in ...
- c++ 陷阱
.c89 c90 gnu90 c99 c11 c++98( default ) c++03 c++11 gnu++11 boolC 标准 does not support the boolean da ...
- ajax提交form表单
1. ajax提交form表单和不同的form表单的提交主要区别在于,ajax提交表单是异步提交的,而普通的是同步提交的表单. 2. from视图部分 <form id="loginF ...
- useradd与adduser的区别
useradd与adduser都是创建新的用户 在CentOs下useradd与adduser是没有区别的都是在创建用户,在home下自动创建目录,没有设置密码,需要使用passwd命令修改密码. 而 ...
- javase-->基础知识(三)
1.方法 普通方法:4个必要,1个可选 1):必须有返回值类型,没有返回值用void表示 2):必须有名字 3):必须有()和形参 4):必须有{}方法体 5):可选static,表示静态的方法,可以 ...
- 何为HDFS?
该文来自百度百科,自我收藏. Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有很多共同点.但同时, ...
- 10.Pattern 和 Matcher
Pattern:正则表达式的模式类 获取对象的函数Pattern pattern=Pattern.compiler(regex); 功能函数: 1.pattern.split(String targe ...