历史上的今天
今天是:2024年10月09日(星期三)
2019年10月09日 | stm32 定时器5输入捕获
2019-10-09 来源:eefocus
timer.h
#ifndef _TIM5SANP_H
#define _TIM5SANP_H
#include "sys.h"
void TIM14_PWM_Init(u32 arr,u32 psc);
void TIM5_CH1_Cap_Init(u32 arr,u16 psc);
#endif
timer.c
#include "timer.h"
TIM_ICInitTypeDef TIM5_ICInitStructre;
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//TIM5时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//GPIOA时钟使能
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用tim5
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //配置输入分频,不分频
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure); //
//#define TIM_Channel_1 ((uint16_t)0x0000)
//
//#define TIM_ICSelection_DirectTI ((uint16_t)0x0001)
// TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively
//TIM5_CCMR1寄存器
//位 1:0 CC1S:捕获/比较 1 选择 (Capture/Compare 1 selection)
//此位域定义通道方向(输入/输出)以及所使用的输入。
//00: CC1 通道配置为输出。
//01: CC1 通道配置为输入, IC1 映射到 TI1 上。
//书本178页 或中文参考434页
TIM5_ICInitStructre.TIM_Channel=TIM_Channel_1; //选择输入端IC1映射到TI1
TIM5_ICInitStructre.TIM_ICPolarity=TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructre.TIM_ICSelection=TIM_ICSelection_DirectTI;//映射到TI1上
TIM5_ICInitStructre.TIM_ICPrescaler=TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_ICInitStructre.TIM_ICFilter=0x00; //配置输入滤波器不滤波
TIM_ICInit(TIM5,&TIM5_ICInitStructre); //初始化TIM5输入捕获参数
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE); //允许更新和捕获中断
TIM_Cmd(TIM5,ENABLE); //使能定时器5
NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//捕获状态
//[7]:0,没有成功的捕获,1,成功捕获到1次
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294s)
u8 TIM5CH1_CAPTURE_STA=0;//输入捕获状态
u32 TIM5CH1_CAPTURE_VAL; //输入捕获值(TIM2/TIM5是32位)
//定时器5中断服务程序
void TIM5_IRQHandler(void)
{
if((TIM5CH1_CAPTURE_STA & 0x80)==0) //还未成功捕获
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update) != RESET)//溢出
{
if(TIM5CH1_CAPTURE_STA & 0x40) //已经捕获到高电平了
{
if((TIM5CH1_CAPTURE_STA & 0X3F)==0X3F) //高电平太长了
{
TIM5CH1_CAPTURE_STA |= 0X80; //标记成功捕获了一次
TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;
}
else
TIM5CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM5,TIM_IT_CC1) != RESET) //捕获1发生捕获事件
{
if(TIM5CH1_CAPTURE_STA & 0x40) //捕获到一个下降下沿
{
TIM5CH1_CAPTURE_STA |= 0X80; //标记成功捕获了一次高电平脉宽
TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取当前的捕获值
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising);//设置上升沿捕获
}
else //还未开始,第一次捕获了上升沿
{
TIM5CH1_CAPTURE_STA=0; //清空
TIM5CH1_CAPTURE_VAL=0;
TIM5CH1_CAPTURE_STA |=0x40; //标记捕获了上升沿
TIM_Cmd(TIM5,ENABLE);
TIM_SetCounter(TIM5,0); //计数器清空
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //设置下降沿捕获
TIM_Cmd(TIM5,ENABLE); //使能定时器5
}
}
}
TIM_ClearITPendingBit(TIM5,TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}
/*
程序思路:
TIM5CH1_CAPTURE_STA:用来记录捕获状态
TIM5CH1_CAPTURE_STA=0x40 第7位为1说明捕获到高电平
TIM5CH1_CAPTURE_STA的bit7 第8位为1说明捕获完成了
TIM5CH1_CAPTURE_STA的[5:0]是记录溢出次数
第一次进入中断
开始时TIM5CH1_CAPTURE_STA=0;必然会进入这个if
if((TIM5CH1_CAPTURE_STA & 0x80)==0)
1.如果在捕获到高电平前溢出了,则溢出部份不处理
2.如果在捕获高电平之后TIM5CH1_CAPTURE_STA++;
如果捕获1发生捕获事件,计数器清0,TIM5CH1_CAPTURE_STA=0x40 (0100 0000),改成下降沿捕获
第N次进入中断
如果前面已经捕获了上升沿,
TIM5CH1_CAPTURE_STA |= 0X80; //标记成功捕获了一次高电平脉宽
TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取当前的捕获值
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising);//设置上升沿捕获
*/
main.c
#include "sys.h"
#include "delay.h"
#include "timer.h"
#include "usart.h"
extern u8 TIM5CH1_CAPTURE_STA;//输入捕获状态
extern u32 TIM5CH1_CAPTURE_VAL; //输入捕获值(TIM2/TIM5是32位)
int main(void)
{
//long long是属于int型, 一般来讲, 是long int型大小的两倍, int型的4倍.
long long temp=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1);
//84Mhz 84分频为1Mhz 一个周期是1us
//自动重装载值取到最大2的32次方-1 约4294.96秒才会溢出
while(1)
{
if(TIM5CH1_CAPTURE_STA & 0x80)
{
temp=TIM5CH1_CAPTURE_STA & 0x3f;//取到溢出次数通常为0因为很少有能超出4294.96秒
temp *=0XFFFFFFFF; //溢出一次时间加上0XFFFFFFFF us
temp +=TIM5CH1_CAPTURE_VAL; //得到总的高电平时间和 一次刚好是1us
printf("高电平的时间为:%lld us rn",temp);
TIM5CH1_CAPTURE_STA=0;//下一次捕获开启
}
}
}
上一篇:STM32 读写保护功能及设置
下一篇:stm32 time4 pwm
史海拾趣
|
用VS2005调试的wince应用程序,在开发板上运行的时候出现如下错误: 致命的应用程序错误 应用程序test.exe执行了一个非法操作,将被关闭。若问题持续出现,请与供应商联系。 程序:Test.exe 异常:0xc00000FD 地址:00011860 问题出现在哪呢 ...… 查看全部问答> |
|
大家好: 请大家帮帮我,我把2003的程序移到VS2005上,编译报一个错误(函数调用产生歧义的错误)如下: error C2668: \'ATL::TrackPopupMenu\' : ambiguous call to overloaded function C:\\Pro ...… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 13:32 编辑 今天,做了一个lm306的滞回比较电路,但是出波后每个方波下有一个下冲,请问是什么原因造成的 [ 本帖最后由 markzhao 于 2011-7-3 16:20 编辑 ] … 查看全部问答> |
|
嵌入式系统的发展促进 了智能设备的网络化, 针对家庭智能化 问题 , 提出了智能家居系统的应用模型, 设计了一种基于MS P 4 3 0 F 1 4 9单片机的具有网络接口的智能设备控制器, 分析其硬件接 口电路 、 软件层次结构和应用软件开发方法, 实现了 ...… 查看全部问答> |




