OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9984|回复: 10

STM32L4 HAL库实现TIM ETR计数测频率

[复制链接]

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7523
金钱
7523
注册时间
2016-11-30
在线时间
641 小时
发表于 2018-7-23 10:53:54 | 显示全部楼层 |阅读模式
10金钱
最近看了一篇高精度高频频率测量的文章,觉得写的很好,于是打算按照文章进行实现。
一开始的思路是用STM32L4的TIM2的ETR脚进行脉冲计数(前置电路已经把波形整理成方波),
TIM7进行定时1S钟去读取TIM2 CNT计数,这样CNT值就是测得的方波的频率。

代码实现的时候,用Debug模式查看寄存器值,也跟参考手册的寄存器进行了比较,确实没有什么问题。
TIM2使用PA0,PA5,PA15引脚都试过了,还是不行,真的不知道还能是什么原因,请各位大佬不吝赐教!

最后我是使用TIM1实现了我的方案,代码如下:
void TIM1_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        TIM_ClockConfigTypeDef sClockSourceConfig;


        HAL_TIM_Base_DeInit(&TIM1_Handler);
        TIM1_Handler.Instance = TIM1; //通用定时器 2
        TIM1_Handler.Init.Prescaler = 0; //分频系数,不分频72MHz
        TIM1_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数器
        TIM1_Handler.Init.Period=0xFFFF; //自动装载值
        TIM1_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; //时钟分频银子
        HAL_TIM_Base_Init(&TIM1_Handler);

        //设置位外部时钟2模式
        sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
        sClockSourceConfig.ClockPolarity = TIM_ETRPOLARITY_NONINVERTED;
        sClockSourceConfig.ClockPrescaler = TIM_ETRPRESCALER_DIV1;
        sClockSourceConfig.ClockFilter = 0x0;
        HAL_TIM_ConfigClockSource(&TIM1_Handler, &sClockSourceConfig);
        __HAL_TIM_SET_COUNTER(&TIM1_Handler,0);
        HAL_TIM_Base_Start(&TIM1_Handler);
       
}

void TIM7_Init(u16 arr,u16 psc)
{  
        TIM7_Handler.Instance= TIM7;                          //通用定时器7
        TIM7_Handler.Init.Prescaler=psc;                     //分频系数
        TIM7_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
        TIM7_Handler.Init.Period=arr;                        //自动装载值
        TIM7_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子
        HAL_TIM_Base_Init(&TIM7_Handler);

        HAL_TIM_Base_Start_IT(&TIM7_Handler); //使能定时器7和定时器7更新中断:TIM_IT_UPDATE   
        TIM7_Enable();
}


//定时器底册驱动,开启时钟,设置中断优先级
//此函数会被HAL_TIM_Base_Init()函数调用
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
        GPIO_InitTypeDef GPIO_InitStruct;
       
        if(htim->Instance==TIM1)
        {
                __HAL_RCC_TIM1_CLK_ENABLE(); //使能 TIM1 时钟
                __HAL_RCC_GPIOA_CLK_ENABLE();

                GPIO_InitStruct.Pin = GPIO_PIN_12;
                GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
                GPIO_InitStruct.Pull = GPIO_PULLDOWN;
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
                GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;//复用功能选择很重要,一定要对照数据手册修改
                HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
        }/**/

        if(htim->Instance==TIM2)
        {
        }/**/

        if(htim->Instance==TIM7)
        {
                __HAL_RCC_TIM7_CLK_ENABLE();            //使能TIM7时钟
               
                HAL_NVIC_SetPriority(TIM7_IRQn,1,2);    //设置中断优先级,抢占优先级1,子优先级3
                HAL_NVIC_EnableIRQ(TIM7_IRQn);          //开启ITM7中断   
        }

}

//定时器7中断服务函数
void TIM7_IRQHandler(void)
{
        HAL_TIM_IRQHandler(&TIM7_Handler);
}


//回调函数,定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

        if(htim==(&TIM7_Handler))
        {
                //printf("TIM7\r\n");
                fq= __HAL_TIM_GET_COUNTER(&TIM1_Handler);    //读取1s内计数器计的CNT值即是脉冲的频率
                __HAL_TIM_SET_COUNTER(&TIM1_Handler,0);
        }

       
        /*if(htim==(&LPTIM1_Handler))
        {
                IWDG_Feed();
                printf("TIM7\r\n");
        }*/
}


int main(void)
{
        HAL_Init();
        SystemClock_Config();
        MX_GPIO_Init();
        MX_USART2_UART_Init();
        delay_init(72);                     //延时函数初始化          
        TIM1_Init();
        TIM7_Init((10000-1),7199);//定时器初始化10Khz 的计数频率7199
        printf("SystemCoreClock = %d\r\n",SystemCoreClock);

        while(1)
        {

                printf("fq = %d\r\n",fq);       
                LED_TOGGLE;
                delay_ms(1000);

        }/**/
}


最后用示波器产生的1KHz的标准方波进行采集测量,fq=1000,证明程序实现了功能。

TIM2与TIM1的区别是TIM2是32位的CNT,而TIM是16位的CNT,也就是说此种方法TIM1最大测频是60KHz左右,
有点遗憾,不过功能基本实现了。也没有60KHz左右的标准波进行测试,准备用IO口产生一个标准波形试一下。
如果想要再测更高频率,可以修改sClockSourceConfig.ClockPrescaler = TIM_ETRPRESCALER_DIV1;
进行分频,这样可以把测量范围提高几倍,
还可以把TIM7的定时时间缩短到100ms,这样测频范围也会扩大10倍,只是理论分析,没有实测,不知道精度如何。



用STM32触发捕捉实现高速高精度测频.pdf

667.81 KB, 下载次数: 328

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7523
金钱
7523
注册时间
2016-11-30
在线时间
641 小时
 楼主| 发表于 2018-7-23 11:32:50 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2018-7-24 02:12:22 | 显示全部楼层
帮顶
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7523
金钱
7523
注册时间
2016-11-30
在线时间
641 小时
 楼主| 发表于 2018-7-24 09:22:53 | 显示全部楼层
用定时器翻转IO口产生1个50KHz的波,接到TIM1 ETR脚上进行测量,测量值正好是fq=50000,说明此种方法的测量精度还是比较高的。
1S钟1次中断还是可以接受的。如果觉得中断太频繁可以用PDF里的方法进行实现。
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7523
金钱
7523
注册时间
2016-11-30
在线时间
641 小时
 楼主| 发表于 2018-7-27 10:19:04 | 显示全部楼层

为什么TIM2不行啊,原子哥
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165508
金钱
165508
注册时间
2010-12-1
在线时间
2115 小时
发表于 2018-7-30 02:07:16 | 显示全部楼层
lvkanger 发表于 2018-7-27 10:19
为什么TIM2不行啊,原子哥

肯定可以,你的代码有问题
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2019-7-2
在线时间
0 小时
发表于 2019-7-2 16:41:02 | 显示全部楼层
请问,TIM1_Handler这个变量是自己定义的吗?我在keil里直接使用,发现找不到这个变量。
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7523
金钱
7523
注册时间
2016-11-30
在线时间
641 小时
 楼主| 发表于 2019-7-3 09:27:37 | 显示全部楼层
liwenyao24 发表于 2019-7-2 16:41
请问,TIM1_Handler这个变量是自己定义的吗?我在keil里直接使用,发现找不到这个变量。

是自己定义的
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2019-12-8
在线时间
2 小时
发表于 2020-8-13 14:33:50 | 显示全部楼层
我的TIM2也不行
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2019-12-8
在线时间
2 小时
发表于 2020-8-13 14:36:47 | 显示全部楼层
就离谱
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2019-12-8
在线时间
2 小时
发表于 2020-8-13 14:44:46 | 显示全部楼层
用TIM1,TIM2的误差一毛一样
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-17 14:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表