你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

请教版主和大神们,使用一个定时器作为另一个的预分器

[复制链接]
ypldz23 提问时间:2015-6-18 16:12 /
最近在研究用2个计数器串联计外部脉冲,采用主从模式,主计数器计(TIM1)低16位,从计数器(TIM2)计高16位,大概的配置如下:
        时钟、GPIO配置略
        //定时器TIM1初始化
        TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;         //自动重装载计数值
        TIM_TimeBaseInitStruct.TIM_Prescaler =0x0000;        //预分频系数0+1,不分频
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down; //向下计数        
        TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);               
        //CH2通道输入TI1,上升沿计数,无滤波器
        TIM_TIxExternalClockConfig(TIM1,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Rising,0x0);        
        TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
        //010:更新 – 更新事件被选为触发输入(TRGO)。
        //例如,一个主定时器的时钟可以被用作一个从定时器的预分频器。
        TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);        

        //定时器TIM2初始化
        TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;         //自动重装载计数值
        TIM_TimeBaseInitStruct.TIM_Prescaler =0x0000;        //预分频系数0+1,不分频
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down; //向下计数
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);        

        //连接定时器1的TRGO1输出至定时器2,设置TIM2_SMCR寄存器的TS=’000’,
        //配置定时器2为使用ITR1作为内部触发的从模式。
        TIM_SelectInputTrigger(TIM2,TIM_TS_ITR0);
        //然后把从模式控制器置于外部时钟模式1(TIM2_SMCR寄存器的SMS=111);
        //这样定时器2即可由定时器1周期性的上升沿(即定时器1的计数器溢出)信号驱动。
        TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_External1);
        TIM_Cmd(TIM1,ENABLE); //使能TIM1
        TIM_Cmd(TIM2,ENABLE); //使能TIM2

        大致的思路是外部脉冲接TIM1的CH1(PA8),当向下计数溢出时产生更新事件,输出TRGO至TIM2的ITR1,这个TIM1每溢出一次,TIM2计数器减1,在1s中断处理,用前1秒计数减去当前计数,可得出每秒计数即频率值。
       调试的时候,频率不对,然后分别输出TIM1和TIM2的计数器,发现TIM2计数值不对,比如我输入超过65535H在的频率,让TIM1每秒都溢出,但是结果是TIM2的计数值要过几秒以后才减1,感觉像是TIM2没计到似的,怀疑是不是配置有问题,然后各种看参考手册寄存器库函数,也没发现问题,后来想难道是TIM1没有产生更新中断,所以导致TIM2没计到?在TIM1加入更新中断配置,如下:
        //允许更新中断
        TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);        
        //中断优先级NVIC设置
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//0位抢占优先级,4位相应优先级        
        NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;         //
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//
        NVIC_Init(&NVIC_InitStructure);//

        在中断函数里清标志位,结果居然好使了!!!
       接着调试看看是哪的问题,只要我编译上面带//的红色代码的任意一行,都可以,即使没有中断函数。难道是加延迟?加延迟语句也是不行。不知道版主和大神们调没调过“使用一个定时器作为另一个的预分频器”,加一条语句就好使,这也太奇怪了!
收藏 2 评论16 发布时间:2015-6-18 16:12

举报

16个回答
回答时间:2015-6-18 16:32:25
NVIC在哪儿配置的?建议先配置NVIC,再开启中断。如果能把工程上传一下更好。
ypldz23 回答时间:2015-6-19 09:21:28
安 发表于 2015-6-18 16:32
NVIC在哪儿配置的?建议先配置NVIC,再开启中断。如果能把工程上传一下更好。 ...

#include "tim1clktim2.h"
#include "misc.h"
#include "stm32f10x_tim.h"
#define  TIM_TRGOSource_Update   ((uint16_t)0x0020)
#define  TIM_SlaveMode_External1   ((uint16_t)0x0007)
void TIM1clkTIM2_Int_Init(void)
{
        //定义定时器初始化结构体变量
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
        GPIO_InitTypeDef GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);       
       
        //TIM1 CH1(PA8)外部时钟1输入引脚配置
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        //定时器TIM1初始化
        TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;         //自动重装载计数值
        TIM_TimeBaseInitStruct.TIM_Prescaler =0x0000;        //预分频系数0+1,不分频
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//定义在定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分//频比例。,00:tDTS = tCK_INT,不分频
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down; //向下计数
       
        //初始化TIM1
        TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct);       
       
        //CH2通道输入TI1,上升沿计数,无滤波器
        TIM_TIxExternalClockConfig(TIM1,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Rising,0x0);       
        TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
        //010:更新 – 更新事件被选为触发输入(TRGO)。
        //例如,一个主定时器的时钟可以被用作一个从定时器的预分频器。
        TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);
               
//        TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);        //允许更新中断
        //中断优先级NVIC设置
//        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//0位抢占优先级,4位相应优先级       
//        NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;         //-_-
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//-_-
//        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//-_-
//        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//-_-
//        NVIC_Init(&NVIC_InitStructure);//-_-       
          

        //定时器TIM2初始化
        TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;         //自动重装载计数值
        TIM_TimeBaseInitStruct.TIM_Prescaler =0x0000;        //预分频系数0+1,不分频
        TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//定义在定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例。,00:tDTS = tCK_INT,不分频
        TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Down; //向下计数

        //初始化TIM2
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);       
        //连接定时器1的TRGO1输出至定时器2,设置TIM2_SMCR寄存器的TS=’000’,
        //配置定时器2为使用ITR1作为内部触发的从模式。
        TIM_SelectInputTrigger(TIM2,TIM_TS_ITR0);
        //然后把从模式控制器置于外部时钟模式1(TIM2_SMCR寄存器的SMS=111);
        //这样定时器2即可由定时器1周期性的上升沿(即定时器1的计数器溢出)信号驱动。
        TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_External1);

        TIM_Cmd(TIM1,ENABLE); //使能TIM1
        TIM_Cmd(TIM2,ENABLE); //使能TIM2
}
红色代码部分,只要编译其中任意一行,例如第2行,即使在没有开启更新中断的情况下,计数都正常
另外请问版主,输入26MHz,显示25997218Hz,输入27MHz,误差就很大了,难道这是外部输入脉冲的上限?

回答时间:2015-6-19 10:03:56
按照手册写两个定时器的时钟频率都是由预分频器对CK_INT除以3(fCK_CNT=fCK_INT/3)。这样TIM1应是24M,TIM2应该是12M。我没有用过这种触发方式,希望和楼主一块探讨一下。我再找个板子一块测试一下。
为什么是EEFOCUS小白 回答时间:2015-6-19 11:09:17
谢谢分享
ypldz23 回答时间:2015-6-23 09:05:29
安 发表于 2015-6-19 10:03
按照手册写两个定时器的时钟频率都是由预分频器对CK_INT除以3(fCK_CNT=fCK_INT/3)。这样TIM1应是24M,TIM2 ...

版主,试验了没?
stary666 回答时间:2015-6-23 10:01:36
位置不重要的
逍遥李 回答时间:2015-6-23 10:09:21
独特的想法
回答时间:2015-6-23 10:49:41
ypldz23 发表于 2015-6-23 09:05
版主,试验了没?

不好意思,放假有事。我这有107的板子,你最好把工程上传一下。
ypldz23 回答时间:2015-6-23 14:02:43
安 发表于 2015-6-23 10:49
不好意思,放假有事。我这有107的板子,你最好把工程上传一下。

麻烦版主啦

定时器读脉冲计数.rar

下载

4.7 MB, 下载次数: 241, 下载积分: ST金币 -1

12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版