STM32双定时器测频率源程序

发布者:dandan666最新更新时间:2020-07-12 来源: 51hei关键字:STM32  双定时器  测频率 手机看文章 扫描二维码
随时随地手机看文章

最近在准备八月份的全国大学生电子设计大赛,就做了几道往年的电赛真题,其中有一题是测频率,要求测量频率10Hz—2MHz,误差小于0.1%,当时也是一脸懵,就在论坛找资料,发现论坛中使用的基本都是输入捕获方法测频率,但是这种方法不能测高频,最多测几百千赫兹,达不到题目要求。经过和小伙伴们的一天讨论,最终创造了一种程序,它可以测量1Hz-22MHz,并且误差小于0.1%。下面是验证通过的程序,算是作为一种在论坛潜伏一年多对论坛的回报吧。


单片机源程序如下:

#include "led.h"

#include "delay.h"

#include "key.h"

#include "sys.h"

#include "usart.h"

#include "timer.h"



u32 count_s;

u32 count_ms;

extern u32 count_i;

extern u32 count_over;

int main(void)

{                                                                                 

                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                  //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

          uart_init(9600);         //串口初始化为9600


        TIM3_External_Clock_CountingMode();


        TIM4_timer_Init();


    while(1)

    {

                if(count_i>1000)

                {

                        count_ms = TIM3->CNT;

                        count_s = count_over*65536 + count_ms;

                        printf("%d rn ",count_s);        //打印数据

                        count_i=0;

                        count_over=0;

                        TIM3->CNT=0;

                }

    }

}


#include "timer.h"

#include "led.h"


//通用定时器3中断初始化

//这里时钟选择为APB1的2倍,而APB1为36M

//arr:自动重装值。

//psc:时钟预分频数

//这里使用的是定时器3!

void TIM3_External_Clock_CountingMode(void)

{         

          GPIO_InitTypeDef GPIO_InitStructure;

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

          NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

   

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOD, &GPIO_InitStructure);


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_DeInit(TIM3);

    TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

    TIM_TimeBaseStructure.TIM_Prescaler = 0;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;

          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);


        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM4中断

        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级

        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级

        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断


        TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);//2分频,上升沿有效


        TIM_SetCounter(TIM3, 0);   // 清零计数器CNT

        TIM_Cmd(TIM3,ENABLE);       

  

}

/***********************************************************************************************


************************************************************************************************/

void TIM4_timer_Init(void)

{

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

        NVIC_InitTypeDef NVIC_InitStructure;


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

       

        TIM_TimeBaseStructure.TIM_Period = 9;         //设置在下一个更新事件装入活动的自动重装载寄存器周期的值       

        TIM_TimeBaseStructure.TIM_Prescaler =7199;         //设置用来作为TIMx时钟频率除数的预分频值

        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim

        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位


        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断

        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级

        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级

        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断


        TIM_SetCounter(TIM4, 0);   // 清零计数器CNT

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

}

/***********************************************************************************************


************************************************************************************************/


u32 count_i = 0;


void TIM4_IRQHandler(void)

{

        if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  //检查TIM4更新中断发生与否

        {

                TIM_ClearITPendingBit(TIM4, TIM_IT_Update);                 //注意清除标志位

                count_i++;

        }

}


/***********************************************************************************************


************************************************************************************************/

u32 count_over = 0;

void TIM3_IRQHandler(void)

{

        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM4更新中断发生与否

        {

                TIM_ClearITPendingBit(TIM3, TIM_IT_Update);                 //注意清除标志位

                count_over++;

        }

}


关键字:STM32  双定时器  测频率 引用地址:STM32双定时器测频率源程序

上一篇:STM32控制步进电机源代码
下一篇:STM32+AD7606芯片源代码

推荐阅读最新更新时间:2024-11-11 21:55

STM32的uart1、uart2、uart3重定向函数(标准库版)
标准库 //uart1 int fputc(int ch,FILE *f) { while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); USART_SendData(USART1,(unsigned char)ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET); return (ch); } //uart2 int fputc(int ch,FILE *f) { while(USART_GetFlagStatus(USART2,USART_FLAG
[单片机]
STM32开发 -- 复位类型判断
复位类型的情况有多种,会导致MCU重启。 因此我们有必要确认一下是何种复位导致的。 一、复位类型 想要查看复位类型可以看一下RCC_GetFlagStatus函数说明 / ** * @brief检查是否设置了指定的RCC标志。 * @param RCC_FLAG:指定要检查的标志。 * *对于@b STM32_Connectivity_line_devices,此参数可以是其中之一 *以下值: * @arg RCC_FLAG_HSIRDY:HSI振荡器时钟就绪 * @arg RCC_FLAG_HSERDY:准备好HSE振荡器时钟 * @arg RCC_FLAG_PLLRDY:PLL时钟就绪 * @arg
[单片机]
STM32笔记之八:来跟PC打个招呼,基本串口通讯
a) 目的:在基础实验成功的基础上,对串口的调试方法进行实践。硬件代码顺利完成之后,对日后调试需要用到的printf重定义进行调试,固定在自己的库函数中。 b) 初始化函数定义: void USART_Configuration(void); //定义串口初始化函数 c) 初始化函数调用: void UART_Configuration(void); //串口初始化函数调用 初始化代码: void USART_Configuration(void) //串口初始化函数 { //串口参数初始化 US
[单片机]
STM32单片机简易定时器PWM输出
由于RCC- CFGR时钟配置寄存器中 APB1设置为2分频,所以TIM3就是其倍频==72M 上次我发表的STM32单片机自带PWM输出实验大家可以参考学习: http://www.51hei.com/mcu/2123.html ,这次是用定时器产生的pwm. //----------------------------------定时器-----------time.c----------- #include time.h void time_init(u16 arr,u16 psc) { RCC- APB1ENR|=1 1; //TIM2定时器时钟使能 TIM3- ARR=arr; //设置重装
[单片机]
<font color='red'>STM32</font>单片机简易<font color='red'>定时器</font>PWM输出
STM32中映射 C库函数printf
一、MDK设置 在工程的 Target中MicroLib 二、main函数之前添加如下编译代码: #define COM USART1 //串口选择初始化,USART1为串口1,USART2为串口2 #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { USART_SendData(COM, (uint8_t) ch); //此处用到了 COM宏定义为了 USART1
[单片机]
<font color='red'>STM32</font>中映射 C库函数printf
STM32_固件库操作LED灯
流水灯,几乎是每种开发板第一个接触的实验,简单而又不可少。 今天,小编简要说明一下如何使用固件库操作LED灯。 硬件连接: 软件设计: void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 1,使能GPIO对应引脚时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOG ,ENABLE); // 2,定义GPIO引脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GP
[单片机]
STM32_固件库操作LED灯
如何使用STM32通用Bootloader让OTA更加Easy
随着物联网时代到来,越来越多的智能设备拥有了在线升级的能力,无论是系统更新,产品功能迭代还是漏洞修复都能在第一时间抵达用户手中的智能设备。 在线升级功能需要使用 OTA (Over-the-Air) 技术 ,OTA 技术简单地说就是通过网络来升级手中的智能设备,进而使用设备最新版本的功能。而 OTA 技术中必不可少的一环就是通过 Bootloader 来管理、升级设备固件。 由于 OTA 功能由多种复杂技术组成,因此添加 OTA 功能有一定的技术门槛。很多开发者遇到莫名其妙的问题,进而导致 OTA 升级失败,常见问题如下: 升级过程缺少专业的安全机制 APP 无法正常启动 程序莫名跑飞,出现 hardfault 固件搬运失
[单片机]
如何使用<font color='red'>STM32</font>通用Bootloader让OTA更加Easy
STM32—IWDG独立看门狗的使用
STM32---IWDG独立看门狗的使用 独立看门狗(IWDG)由专用的40kHz的低速时钟驱动, 即使主时钟发生故障它也仍然有效。 窗口看门狗由从APB1时钟分频后得到的时钟驱动, 通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。 IWDG最适合应用于那些需要看门狗作为一个在主程序之外, 能够完全独立工作,并且对时间精度要求较低的场合。 WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序。 IWDG主要性能 ●自由运行的递减计数器 ●时钟由独立的RC振荡器提供(可在停止和待机模式下工作) ●看门狗被激活后,则在计数器计数至0x000时产生复位 在键寄存器(IWDG_KR)中写入0xCC
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved