首页 > 其他分享 >输入捕获实验

输入捕获实验

时间:2023-12-22 10:24:27浏览次数:36  
标签:CAPTURE TIM5 捕获 TIM 实验 GPIO 输入 TIM5CH1

输入捕获

作用:捕获输入的脉宽

原理:在t1时刻检测到上升沿,计数器清零,在t2时刻,检测到下降沿,记录此时的计数器的值,那么,脉宽为N*ARR+CCRx2.所以我们要知道N和CCRx2的值。从定时器中断我们知道,每次溢出都会有更新事件,产生事件更新中断,我们可利用该中断检测到底溢出多少次。对于t2时刻的值,我们可以触发捕获中断,获取此刻的值。

 

 

输入捕获步骤:

 

滤波:IC1F【3:0】位决定。【1:0】决定每N个事件才能组成一个有效边沿

 

 在输入捕获通道初始化时我们要配置:

TIM5_ICInitStructure.TIM_Channel  通道

  TIM5_ICInitStructure.TIM_ICPolarity  上升沿捕获还是下降沿捕获

TIM5_ICInitStructure.TIM_ICSelection 映射关系,映射到Tx(通道一般是这样),映射到其他通道,映射到TRC(模式控制器)上

TIM5_ICInitStructure.TIM_ICPrescaler 配置输入分频

TIM5_ICInitStructure.TIM_ICFilter 配置输入滤波器

 

 

实验步骤:

还有一个函数:获取通道捕捉值:TIM_GetCapture1(TIMx);//对应的是通道一

 唯一新的地方在于⑤,初始化捕获通道,当然中断服务函数是整个程序中最复杂的,我们要讨论这个。

TIM5CH1_CAPTURE_STA=0;

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); //CC1P=0 设置为上升沿捕获8
}else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA=0; //清空
TIM5CH1_CAPTURE_VAL=0;
TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_Cmd(TIM5,DISABLE ); //关闭定时器5
TIM_SetCounter(TIM5,0);
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
TIM_Cmd(TIM5,ENABLE ); //使能定时器5
}
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}

整个程序分为两部分,计算溢出值和捕获值。TIM5CH1_CAPTURE_STA六位计数,第七位表示捕捉到高低电平,第八位表示成功捕获。

 

 

 

 

完整代码:


void TIM14_PWM_Init(u32 arr,u32 psc)
{
//此部分需手动修改IO口设置

GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟

GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用位定时器14

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOA9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF9

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(TIM14,&TIM_TimeBaseStructure);

//初始化TIM14 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse=0;
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2

TIM_OC2PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器

TIM_ARRPreloadConfig(TIM14,ENABLE);

TIM_Cmd(TIM14, ENABLE); //使能TIM14

}

TIM_ICInitTypeDef TIM5_ICInitStructure;

//定时器5通道1输入捕获配置
//arr:自动重装值(TIM2,TIM5是32位的!!)
//psc:时钟预分频数
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); //使能PORTA时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0

GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用位定时器5


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);

//初始化TIM5输入捕获参数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);

TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断

TIM_Cmd(TIM5,ENABLE ); //使能定时器5


NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、


}
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
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); //CC1P=0 设置为上升沿捕获8
}else //还未开始,第一次捕获上升沿
{
TIM5CH1_CAPTURE_STA=0; //清空
TIM5CH1_CAPTURE_VAL=0;
TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_Cmd(TIM5,DISABLE ); //关闭定时器5
TIM_SetCounter(TIM5,0);
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
TIM_Cmd(TIM5,ENABLE ); //使能定时器5
}
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}

 

标签:CAPTURE,TIM5,捕获,TIM,实验,GPIO,输入,TIM5CH1
From: https://www.cnblogs.com/panshoudeng/p/17920691.html

相关文章

  • 厦门大学数据库实验室简介_厦门大学数据库实验室
    实验室建设了国内高校首个也是目前唯一一个“中国高校大数据课程公共服务平台”(平台官网),为教师开展大数据教学和学生学习大数据课程提供全方位、一站式免费服务,包括讲义PPT、教学大纲、备课指南、学习指南、上机习题、授课视频、技术资料等。研究方向面向当前的海量数据应用,研......
  • 五笔输入法
    我的大学老师是会五笔打字的,他曾自豪地说“”wo16岁上大学,一直留校任教,本地第一批程序员五笔输入法,简称五笔,是一种汉字形码输入法,区别于拼音输入法,其核心基础是“王永民”先生于1983年发明的王码五笔,2013年已有三个核心定型版本:86版、98版、新世纪版(2008年发布),其它五笔,诸如万能五......
  • 实验7
    task1.1#define_CRT_SECURE_NO_WARNINGS//从文本文件data1.txt中读取图书信息,并打印输出到屏幕#include<stdio.h>#defineN80#defineM100typedefstruct{charname[N];//书名charauthor[N];//作者}Book;intmain(){Bookx[M];......
  • 实验7
    实验1.2有,原因是越界。实验41#include<stdio.h>2intmain()3{4charch;5intcount=0;6FILE*fp;7fp=fopen("\\data4.txt","r");8if(fp==NULL)9{10printf("failtoopenfile......
  • 实验7 文件应用编程
    实验任务41#include<stdio.h>2intmain(){3FILE*fp;4inti;5charch;6fp=fopen("data4.txt","r");7if(fp==NULL){8printf("failtoopenfile\n");9return1;10}1......
  • 实验7
    task4#include<stdio.h>#include<stdlib.h>intmain(){FILE*fp;charch;intcnt=0;fp=fopen("data4.txt","r");if(fp==NULL){printf("fail\n");exit(0);}while(......
  • 无涯教程-Haskell - 输入&输出
    到目前为止,我们讨论的所有示例本质上都是静态的,在本章中,我们将学习与用户动态交流,我们将学习Haskell中使用的不同输入和输出技术。文件和流到目前为止,我们已经对程序本身中的所有输入进行了硬编码,我们一直在从静态变量获取输入,现在,让我们学习如何从外部文件读取和写入。让我们......
  • 实验7
     ......
  • 实验七
    #include<stdio.h>#include<stdlib.h>#include<time.h>typedefstruct{longid;charname[20];charban[40];}xx;intmain(){xxa[5],x[80];inti,n;FILE*fp,*fps;fp=fopen("d:\\data\\......
  • 实验七
    #include<stdio.h>#defineN2intmain(){char*x[N]={"0123456789-0123456789","nuist2023-nuist2024"};inti;FILE*fp;fp=fopen("data4.txt","w");if(fp==......