STM32:输入捕获模式测频率和占空比(内置1.实物图+2.代码部分/注释)

简介: STM32:输入捕获模式测频率和占空比(内置1.实物图+2.代码部分/注释)

1.实物图如下:


cc41b0c4ef3c4fa2a0e15de330c6a4fe.png

2.代码如下:

主函数代码如下:

 

0587171ad5194606a69970a6adb2fb12.png

fe7731f420e64036919b9f9e987b5723.png


IC.c( 输入捕获模式)代码部分如下:


f49f59101b90492eada3803bdec987d6.png


 bc809f26668941cbab916cc265707bc9.png

6515ae72842b43e09650f36178ec82ee.png

e7fd99acf6554a5c975a49314801bf37.png

8a7ae6a1c75549bab7d368621f5846ac.png

#include "stm32f10x.h"                  // Device header
//思路:参照输入捕获基本结构图
//1.RCC开启时钟,开启GPIO和TIM时钟
//2.GPIO初始化,配置GPIO为输入模式(上拉输入或浮空输入)
//3.配置时基单元,使CNT计数器在内部时钟驱动下自增
//4.配置输入捕获单元,是结构体,包括滤波器,极性,两个通道同时捕获同一个引脚,分频器
//5.配置TRGI的触发源为TI1FP1
//6.配置从模式为ReSet
//7.调用TIM_Cmd,开启定时器
void IC_Init(void)//输入捕获初始化
{
    //1~3开启时钟,配置GPIO,配置时基单元(直接抄写LED代码,修改通道和引脚,输入模式等即可)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启APB1时钟,TIM2是输出PWM,更改为TIM3(仍是APB1外设)
    //配置GPIO
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    //GPIO的时钟配置,查表得TIM3的通道1和2对应PA6和PA7(GPIOA);通道3和通道4对应PB0和PB1(GPIOB)
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//选择上拉输入模式
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//用的是PA6引脚
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //配置时基单元
    TIM_InternalClockConfig(TIM3);//选择内部时钟的定时器TIM3
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    //TIM_CKD_DIV1,1分频,不分配;TIM_CKD_DIV2,2分频;TIM_CKD_DIV4,4分频----要求不高时,随意选择
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
    //TIM_CounterMode_Up向上计数;TIM_CounterMode_Down向下计数;TIM_CounterMode_CenterAligned1等为中央对齐
    TIM_TimeBaseInitStructure.TIM_Period=65536-1;//自动重装器的值,取最大值,防止溢出---ARR的值   
    TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//预分频,对72M进行7200分频----PSC的值
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器用到,通用定时器选0
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//结构体
    //4.配置输入捕获单元(两个通道同时捕获同一个引脚,方式一:再次初始化  方式二:直接用库函数)
    TIM_ICInitTypeDef TIM_ICInitStructuer;
    TIM_ICInitStructuer.TIM_Channel=TIM_Channel_1;//指定选择通道几,通道1为TIM_Channel_1
    TIM_ICInitStructuer.TIM_ICFilter=0xF;//配置输入捕获的滤波器(有毛刺或噪声时增大滤波器参数)
                                      //参数解释:这个数可是是0x0~0xF之间的数.数越大,滤波效果越好
                                                                        //滤波器计次不会改变信号的原有频率,之后让波形更符合条件.
    TIM_ICInitStructuer.TIM_ICPolarity=TIM_ICPolarity_Rising;//选择极性----上升沿触发还是下降沿还是都触发
    TIM_ICInitStructuer.TIM_ICPrescaler=TIM_ICPSC_DIV1;//分频器,
                                                       //不分频就是每次触发都有效,2分频是每隔一次有效一次...
    TIM_ICInitStructuer.TIM_ICSelection=TIM_ICSelection_DirectTI;//选择直连通道
    TIM_ICInit(TIM3,&TIM_ICInitStructuer);
      //方式一:再次初始化
//        TIM_ICInitStructuer.TIM_Channel=TIM_Channel_2;//指定选择通道几,通道2为TIM_Channel_2
//    TIM_ICInitStructuer.TIM_ICFilter=0xF;//配置输入捕获的滤波器(有毛刺或噪声时增大滤波器参数)
//                                      //参数解释:这个数可是是0x0~0xF之间的数.数越大,滤波效果越好
//                                                                        //滤波器计次不会改变信号的原有频率,之后让波形更符合条件.
//    TIM_ICInitStructuer.TIM_ICPolarity=TIM_ICPolarity_Falling;//选择极性----上升沿触发还是下降沿还是都触发
//    TIM_ICInitStructuer.TIM_ICPrescaler=TIM_ICPSC_DIV1;//分频器,
//                                                       //不分频就是每次触发都有效,2分频是每隔一次有效一次...
//    TIM_ICInitStructuer.TIM_ICSelection=TIM_ICSelection_IndirectTI;//选择交叉通道
//    TIM_ICInit(TIM3,&TIM_ICInitStructuer);
    //方式二:直接用库函数
    TIM_PWMIConfig(TIM3,&TIM_ICInitStructuer);
    //5.配置TRGI的触发源为TI1FP1
    TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//第二个参数选择触发源TIM_TS_TI1FP1
    //6.配置从模式为ReSet
    TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
    //7.调用TIM_Cmd,开启定时器
    TIM_Cmd(TIM3,ENABLE);
}
//注:想要查看频率时,读取CCR,计算即可
//fx=fc/N
//fc=72M/(PSC+1)
//因为PSC=72,所以fc=1MHz,所以fx=1000000/N,(N就是CCR)
uint16_t IC_GetFreq(void)
{
    return 1000000/(TIM_GetCapture1(TIM3)+1);
}
//获取占空比的函数:
uint16_t IC_GetDuty(void)
{
    return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);//CCR2/CCR1就是占空比(结果是0~1,所以要*100)
}

IC.h(输入捕获模式)代码部分:

407e6870391a42738540c95e5f64e866.png

#ifndef  __IC_H
#define  __IC_H
uint16_t IC_GetFreq(void);
void IC_Init(void);
uint16_t IC_GetDuty(void);
#endif

注:此代码与测频率基本一致,只是主函数中多显示了一个占空比的相关指令,IC.c中多使用了占空比函数和配置输入捕获单元时的区别。均在代码图中标出


相关文章
|
7月前
【STM32】基于HAL库的360度编码器、摇杆代码编写
【STM32】基于HAL库的360度编码器、摇杆代码编写
113 0
|
6月前
|
移动开发
技术好文:stm32寄存器版学习笔记06输入捕获(ETR脉冲计数)
技术好文:stm32寄存器版学习笔记06输入捕获(ETR脉冲计数)
298 0
|
6月前
|
存储 数据安全/隐私保护 芯片
【STM32】详解嵌入式中FLASH闪存的特性和代码示例
【STM32】详解嵌入式中FLASH闪存的特性和代码示例
【STM32】详解独立看门狗的本质和使用步骤&代码
【STM32】详解独立看门狗的本质和使用步骤&代码
|
6月前
|
传感器 数据格式
【STM32】DHT11温湿度模块传感器详解&代码
【STM32】DHT11温湿度模块传感器详解&代码
|
7月前
|
缓存 网络协议 算法
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
|
7月前
|
传感器
STM32循迹小车原理介绍和代码示例
STM32循迹小车原理介绍和代码示例
|
6月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
484 2
|
5月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
811 0
|
6月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
539 4