打印

STM32脉冲计数该怎么计算脉宽呢

[复制链接]
1775|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
myidear|  楼主 | 2016-4-25 09:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
dongbaohui| | 2016-4-26 15:23 | 只看该作者
可以使用stm32定时器的输入捕捉模式,设置成向上或者向下计数,以该脉冲的上升沿或者下降沿触发

使用特权

评论回复
板凳
cnb12345| | 2016-4-26 16:41 | 只看该作者

使用特权

评论回复
地板
l科科1987| | 2016-4-26 17:28 | 只看该作者
STM32精确计数有点难,脉冲过滤器还差不多。就是把符合一定宽度的脉冲过滤出来。

使用特权

评论回复
5
Dennis-Zhou| | 2016-4-26 19:49 | 只看该作者
///////////////////////////////////////////////////////////////////////////////////
//     函数:   TIM2_GPIO_Configuration(void)
//     功能:    配置定时器的引脚为模拟输入
//     输入:     无
//     输出:    无
//     接口:PA0,TIM3的接口
////////////////////////////////////////////////////////////////////////////////

  void TIM2_GPIO_Configuration(void)
  {
         GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* PA0,PA12-> 左右脉冲输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIOA, &GPIO_InitStructure);

可以看看这段代码

使用特权

评论回复
6
playergatsby| | 2016-4-27 15:43 | 只看该作者
有个小经验可以分享给楼主:我们的CCRx寄存器是一个16bit的寄存器计数范围为0~0xffff,即0~65535,可是当测量的矩形波周期太长,脉冲宽度太宽,二我们的计数又太快,很容易出现CCRx溢出现象,所以,我们在测量低频信号时,一定要对TIM的时钟进行分频,这样我们的计数就不会那么快了,也不会产生溢出现象,当我们计数计完了,再把分频所导致的结果进行倍频就OK了。   

使用特权

评论回复
7
whtwhtw| | 2016-4-28 14:53 | 只看该作者
pwm输入捕获
溢出中断中记录溢出次数就可以获取超过16bit及时的限制无限扩展,不过要设置一个限值。

使用特权

评论回复
8
cnb12345| | 2016-4-29 10:23 | 只看该作者

使用特权

评论回复
9
喵喵小星人| | 2016-4-29 18:24 | 只看该作者
//////////////////////////////////////////////////////////////////////
//函数:  TIM2_Configuration(void)
// 功能: 配置定时器为计数器,时钟模式为外部时钟模式
// 输入: 无
// 输出: 无
/////////////////////////////////////////////////////////////////////

  void TIM2_Configuration(void) //只用一个外部脉冲端口
{

TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure ;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE) ;
  //配置TIMER2作为计数器

  TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF ;
TIM_TimeBaseStructure.TIM_Prescaler = 0x00 ;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // Time base configuration

//TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ETRF); //我测试中一直不能用的原因是缺少外部时钟模式
//TIM_TIxExternalClockConfig(TIM2, TIM_TS_TI1FP1,TIM_ICPolarity_Rising, 0);//设置TIMx触发为外部时钟
TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);//该参数取值在0x0和0xF之间。
//TIM_ExtTRGPolarity_NonInverted//TIM外部触发极性非翻转:高电平或上升沿有效
TIM_SetCounter(TIM2, 0);     //TIM_ExtTRGPSC_OFFTIM; ETRP 预分频 OFF
TIM_Cmd(TIM2, ENABLE);
}

////////////////////////////////////////////////////////////////////////////////////////////
//////    函数名: TIM4_Init
///////// 函数功能:配置定时器4
////////////函数输入:无
///////////函数输出: 无
//////////////////////////////////////////////////////////////////////////////////////////
void TIM4_Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能

TIM_TimeBaseStructure.TIM_Period =5000; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值    计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =7199; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_ITConfig(  //使能或者失能指定的TIM中断
TIM4, //TIM2
TIM_IT_Update  |  //TIM 中断源
TIM_IT_Trigger,   //TIM 触发中断源
ENABLE  //使能
);

TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在ARR上的预装载寄存器

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel =TIM4_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

TIM_Cmd(TIM4, ENABLE);  //使能TIMx外设

}
   ///////////////////////////////////////////////
   ////////////函数名:TIM4_IRQHandler
   ////////////功能: 定时器中断处理函数
   /////////////////////////////////////

void TIM4_IRQHandler(void)   //TIM3中断
{
     TIM_Cmd(TIM2, DISABLE);
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{

TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
counter=TIM_GetCounter(TIM2);
printf(\"%d\",counter);
printf(\"\n\");
TIM_SetCounter(TIM2,0);

}
TIM_Cmd(TIM2, ENABLE);
}



void Pluse_Get_init(void)
{
    TIM2_GPIO_Configuration();
TIM2_Configuration();
TIM4_Init();

}
可以试试这个代码

使用特权

评论回复
10
cnb12345| | 2016-4-29 18:42 | 只看该作者

使用特权

评论回复
11
mdk55555| | 2016-4-30 22:23 | 只看该作者
网上关于输入捕获的介绍,希望对你有帮助。 "输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等.
例如:我们用到TIM5_CH1来捕获高电平脉宽,也就是要先设置输入捕获为上升沿检测,记录发生上升沿的时候TIM5_CNT的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的TIM5_CNT值。这样,前后两次TIM5_CNT之差,就是高电平的脉宽,同时TIM5的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。

使用特权

评论回复
12
whtwhtw| | 2016-5-6 16:09 | 只看该作者
STM32的PWM捕获其实是一个输入脚接入芯片里的2个输入捕获通道,1个通道上升沿捕获,1个通道下降沿捕获,获取这2个捕获值就知道捕获信号的频率和占空比了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

249

帖子

0

粉丝