单片机学习小组
登录
直播中
恐龙之家
8年用户
839经验值
私信
关注
如何对通用定时器的输入捕获进行测试呢
开启该帖子的消息推送
通用定时器
定时器
输入捕获模式有何作用?
通用定时器的输入捕获过程是怎样的?
如何对通用定时器的输入捕获进行测试呢?
回帖
(1)
何元
2022-2-24 11:12:41
通用定时器的输入捕获实验
1、作用
输入捕获模式可以用来测量脉冲宽度或者测量频率。
2、过程
STM32的输入捕获,简单的说就是通过检测TIMx_CHx(定时器X的通道X)上的边沿信号,在边沿信号发生跳变(上升沿/下降沿)的时候,将定时器的值(TIMx_CNT)存放到对应通道的捕获/比较寄存器(TIMX_CCRx)里面,完成一次捕获,同时可以配置捕获时是否触发中断/DMA。
3、图解
以CH1为例,定时器通过TIMx_CH1脚产生TI1,TI1经过滤波器后,将信号传输给边沿检测器,边沿检测器检测到准确的边沿信号之后,产生TI1FP1和TI1FP2信号(这两个信号其实是一样的,只是输出的路径不一样),TI1FP1信号提供给IC1,IC1经过预分频器之后,产生捕获信号,这时定时器计数器的当前值被锁存到捕获/比较寄存器中,而且TIMx_SR状态寄存器的CC1IF标志位置1,如果使能了通道1输入捕获的中断功能,就会产生中断。
4、测试方法
1、本次测试实验选择TIM2的CH1,也就是引脚PA0,需要外部输入一个PWM波给PA0,可以采用以下几种方法:
通过函数信号发生器输入。
通过STM32的其他定时器生成一个PWM波。
通过延时函数和GPIO生成一个PWM波。
通过PC串口助手和USB转TTL模块发送一个0x55给引脚。
2、配置流程
打开定时器和通道GPIO的时钟,将通道配置为复用输入。
设置定时器的计数频率,当产生捕获时,用于计时,需要注意定时器溢出的问题,当定时器溢出后,会清除定时器计数器的值(TIMx_CNT),在计算捕获时间的时候,如果有溢出,需要加上溢出的时间。
配置捕获/比较模式寄存器(TIMx_CCMRx)的通道模式为输入,映射关系选择ICx的输入源,配置滤波器和预分频器(一般选择不滤波不分频)。
配置捕获/比较使能寄存器(TIMx_CCER)捕获的边沿信号(上升沿/下降沿触发),在使用输入捕获功能时需要先使能。
配置DMA/中断使能寄存器(TIMx_DIER)打开对应通道的中断或者DMA。
配置控制寄存器(TIMx_CR1)使能定时器,开启计数。
3、本次测试的方案是通过捕获上升沿来获取计数器的值,再根据计数频率得出两个上升沿之间的时间。
4、需要注意的是,如果采用串口助手发送,需要从低位开始读上升沿。
5、代码
#include "stm32f10x.h"
uint16_t flag, val;
void TIM2_CH1_GPIO_Init(void)
{
RCC->APB2ENR|=1<<2; //使能GPIOA时钟
GPIOA->CRL&=0xFFFFFFF0; //清除A0
GPIOA->CRL|=0x00000004; //模拟输入
}
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
u32 temp,temp1;
temp1=(~NVIC_Group)&0x07; //取后三位
temp1<<=8;
temp=SCB->AIRCR; //读取先前的设置
temp&=0X0000F8FF; //清空先前分组
temp|=0X05FA0000; //写入钥匙
temp|=temp1;
SCB->AIRCR=temp; //设置分组
}
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
{
u32 temp;
MY_NVIC_PriorityGroupConfig(NVIC_Group); //设置分组
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf; //取低四位
NVIC->ISER[NVIC_Channel/32]|=(1<
NVIC->IP[NVIC_Channel]|=temp<<4; //设置响应优先级和抢断优先级
}
void TIM2_Init(uint16_t arr, uint16_t psc)
{
RCC->APB1ENR|=1<<0; //使能定时器2时钟
//初始化TIM2
TIM2->ARR = arr; //ARR 自动重装载值
TIM2->PSC = psc; //PSC 预分频系数
TIM2->CR1&=~(1<<4); //DIR 向上计数
TIM2->CR1&=~(3<<8); //CKD[1:0] 时钟分频因子 tDTS=tCK_INT
//初始化TIM1输入捕获参数
TIM2->CCMR1|=1<<0; //CC1S[1:0] CC1通道被配置为输入,IC1映射在TI1上
TIM2->CCMR1&=~(3<<2); //IC1PSC[1:0] 输入/捕获预分频 不分频
TIM2->CCMR1&=~(0xF<<4); //IC1F[3:0] 不滤波
TIM2->CCER|=1<<0; //输入捕获1使能
TIM2->CCER&=~(1<<1); //CC1P 捕获发生在IC1的上升沿,不反向
TIM2->SMCR|=5<<4; //TS[2:0] 触发选择 滤波后的定时器输入1(TI1FP1)
//开启中断
TIM2->DIER|=1<<1; //CC1IE 允许捕获比较1中断
TIM2->DIER|=1<<0; //UIE 允许更新中断
//使能定时器
TIM2->CR1|=1<<0; //CEN 使能定时器
}
void testcase()
{
TIM2_CH1_GPIO_Init(); //使能TIM2 CH1的引脚PA0 模拟输入
TIM2_Init(1000-1, 72-1); //计数频率1MHz 定时1ms
MY_NVIC_Init(1,3,TIM2_IRQn,2); //抢占1,子优先级3,组2 输入捕获中断
while(1)
{
if(flag&0X80) //捕获到第二个上升沿
{
flag = 0;
printf("time = %dus", val);
}
}
}
void TIM2_IRQHandler(void)
{
uint16_t tsr;
static uint16_t i, count;
tsr=TIM2->SR;
if((flag&0X80)==0) //还未成功捕获第二次上升沿
{
if((tsr&0X01)&&(flag&0x40)) //溢出并且捕获到第一个上升沿
{
count++;
}
if(tsr&0x02) //发生捕获事件
{
i++;
if(i==1) //第一次捕获到上升沿
{
flag|=0x40; //标记成功捕获到第一次上升沿
TIM2->CNT = 0; //计数器清零
}
if(i == 2) //第二次捕获到上升沿
{
i = 0;
flag|=0X80; //标记成功捕获到第二次上升沿
val=count*1000 + TIM2->CCR1; //获取当前的捕获值
}
}
}
TIM2->SR=0;//清除中断标志位
}
通用定时器的输入捕获实验
1、作用
输入捕获模式可以用来测量脉冲宽度或者测量频率。
2、过程
STM32的输入捕获,简单的说就是通过检测TIMx_CHx(定时器X的通道X)上的边沿信号,在边沿信号发生跳变(上升沿/下降沿)的时候,将定时器的值(TIMx_CNT)存放到对应通道的捕获/比较寄存器(TIMX_CCRx)里面,完成一次捕获,同时可以配置捕获时是否触发中断/DMA。
3、图解
以CH1为例,定时器通过TIMx_CH1脚产生TI1,TI1经过滤波器后,将信号传输给边沿检测器,边沿检测器检测到准确的边沿信号之后,产生TI1FP1和TI1FP2信号(这两个信号其实是一样的,只是输出的路径不一样),TI1FP1信号提供给IC1,IC1经过预分频器之后,产生捕获信号,这时定时器计数器的当前值被锁存到捕获/比较寄存器中,而且TIMx_SR状态寄存器的CC1IF标志位置1,如果使能了通道1输入捕获的中断功能,就会产生中断。
4、测试方法
1、本次测试实验选择TIM2的CH1,也就是引脚PA0,需要外部输入一个PWM波给PA0,可以采用以下几种方法:
通过函数信号发生器输入。
通过STM32的其他定时器生成一个PWM波。
通过延时函数和GPIO生成一个PWM波。
通过PC串口助手和USB转TTL模块发送一个0x55给引脚。
2、配置流程
打开定时器和通道GPIO的时钟,将通道配置为复用输入。
设置定时器的计数频率,当产生捕获时,用于计时,需要注意定时器溢出的问题,当定时器溢出后,会清除定时器计数器的值(TIMx_CNT),在计算捕获时间的时候,如果有溢出,需要加上溢出的时间。
配置捕获/比较模式寄存器(TIMx_CCMRx)的通道模式为输入,映射关系选择ICx的输入源,配置滤波器和预分频器(一般选择不滤波不分频)。
配置捕获/比较使能寄存器(TIMx_CCER)捕获的边沿信号(上升沿/下降沿触发),在使用输入捕获功能时需要先使能。
配置DMA/中断使能寄存器(TIMx_DIER)打开对应通道的中断或者DMA。
配置控制寄存器(TIMx_CR1)使能定时器,开启计数。
3、本次测试的方案是通过捕获上升沿来获取计数器的值,再根据计数频率得出两个上升沿之间的时间。
4、需要注意的是,如果采用串口助手发送,需要从低位开始读上升沿。
5、代码
#include "stm32f10x.h"
uint16_t flag, val;
void TIM2_CH1_GPIO_Init(void)
{
RCC->APB2ENR|=1<<2; //使能GPIOA时钟
GPIOA->CRL&=0xFFFFFFF0; //清除A0
GPIOA->CRL|=0x00000004; //模拟输入
}
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
u32 temp,temp1;
temp1=(~NVIC_Group)&0x07; //取后三位
temp1<<=8;
temp=SCB->AIRCR; //读取先前的设置
temp&=0X0000F8FF; //清空先前分组
temp|=0X05FA0000; //写入钥匙
temp|=temp1;
SCB->AIRCR=temp; //设置分组
}
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
{
u32 temp;
MY_NVIC_PriorityGroupConfig(NVIC_Group); //设置分组
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf; //取低四位
NVIC->ISER[NVIC_Channel/32]|=(1<
NVIC->IP[NVIC_Channel]|=temp<<4; //设置响应优先级和抢断优先级
}
void TIM2_Init(uint16_t arr, uint16_t psc)
{
RCC->APB1ENR|=1<<0; //使能定时器2时钟
//初始化TIM2
TIM2->ARR = arr; //ARR 自动重装载值
TIM2->PSC = psc; //PSC 预分频系数
TIM2->CR1&=~(1<<4); //DIR 向上计数
TIM2->CR1&=~(3<<8); //CKD[1:0] 时钟分频因子 tDTS=tCK_INT
//初始化TIM1输入捕获参数
TIM2->CCMR1|=1<<0; //CC1S[1:0] CC1通道被配置为输入,IC1映射在TI1上
TIM2->CCMR1&=~(3<<2); //IC1PSC[1:0] 输入/捕获预分频 不分频
TIM2->CCMR1&=~(0xF<<4); //IC1F[3:0] 不滤波
TIM2->CCER|=1<<0; //输入捕获1使能
TIM2->CCER&=~(1<<1); //CC1P 捕获发生在IC1的上升沿,不反向
TIM2->SMCR|=5<<4; //TS[2:0] 触发选择 滤波后的定时器输入1(TI1FP1)
//开启中断
TIM2->DIER|=1<<1; //CC1IE 允许捕获比较1中断
TIM2->DIER|=1<<0; //UIE 允许更新中断
//使能定时器
TIM2->CR1|=1<<0; //CEN 使能定时器
}
void testcase()
{
TIM2_CH1_GPIO_Init(); //使能TIM2 CH1的引脚PA0 模拟输入
TIM2_Init(1000-1, 72-1); //计数频率1MHz 定时1ms
MY_NVIC_Init(1,3,TIM2_IRQn,2); //抢占1,子优先级3,组2 输入捕获中断
while(1)
{
if(flag&0X80) //捕获到第二个上升沿
{
flag = 0;
printf("time = %dus", val);
}
}
}
void TIM2_IRQHandler(void)
{
uint16_t tsr;
static uint16_t i, count;
tsr=TIM2->SR;
if((flag&0X80)==0) //还未成功捕获第二次上升沿
{
if((tsr&0X01)&&(flag&0x40)) //溢出并且捕获到第一个上升沿
{
count++;
}
if(tsr&0x02) //发生捕获事件
{
i++;
if(i==1) //第一次捕获到上升沿
{
flag|=0x40; //标记成功捕获到第一次上升沿
TIM2->CNT = 0; //计数器清零
}
if(i == 2) //第二次捕获到上升沿
{
i = 0;
flag|=0X80; //标记成功捕获到第二次上升沿
val=count*1000 + TIM2->CCR1; //获取当前的捕获值
}
}
}
TIM2->SR=0;//清除中断标志位
}
举报
更多回帖
rotate(-90deg);
回复
相关问答
通用定时器
定时器
通用
定时器
输入
捕获
如何实现
捕获
低电平时间?
2019-03-11
3758
STM32
通用
定时器
输入
捕获
功能是什么?
2021-11-24
1003
怎样去使用STM32F4
通用
定时器
的
输入
捕获
呢
2021-11-18
824
能不能对一个
定时器
进行
四路的
输入
捕获
呢
2022-01-17
841
STM32的
通用
定时器
是怎样
进行
工作的
2021-11-23
980
怎样去采用外部中断测频和
定时器
输入
捕获
去测占空比
呢
2021-11-19
1020
STM32F10x
通用
定时器
是怎样
进行
工作的
2021-11-24
816
为什么STM32单片机的
定时器
PWM
输入
捕获
模式无法读取编码
器
呢
2022-01-21
1643
为什么STM32
定时器
输入
捕获
脉宽会不准
呢
2021-11-23
2157
STM32高级
定时器
、
通用
定时器
和基本
定时器
有何区别
呢
2021-11-24
2386
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分