您的位置 首页 电路

stm32库函数学习篇通用定时器输入捕获功用

实现功能:PA8随意延时驱动led灯闪烁,并且将PA8用杜邦线连接到PA7口,PA7是通用定时器TIM3的2通道,在TIM3_CH2触发中断程序中取反连接到PD…

完成功用:PA8随意延时驱动led灯业绩,而且将PA8用杜邦线连接到PA7口,PA7是通用定时器TIM3的2通道,在TIM3_CH2触发中止程序中取反连接到PD2口的led灯,指示中止程序运转,而且每次进入中止后改动触发捕获的极性。完成两个led灯展替换业绩。

先有必要了解stm32定时器的输入触发模块,如下图:

需求留意的是,一眼望去一个定时器好像有8个通道,左面四个,右边四个,但其实左面和右边是共用相同的IO引脚,所以称号标示是如出一辙。也便是说,每个通用定时器都只需四个独立通道,当某一通道作为了输入触发功用那就不能再作为输出匹配功用。这一点咱们也能够从其他地方找到印证。比方TIM_ITConfig()函数中如下:

void TIM_ITConfig

(

TIM_TypeDef *

TIMx,

uint16_t

TIM_IT,

FunctionalState

NewState

)

Enables or disables the specified TIM interrupts.

Parameters:

TIMx,:

where x can be 1 to 17 to select the TIMx peripheral.

TIM_IT,:

specifies the TIM interrupts sources to be enabled or disabled. This parameter can be any combination of the following values:

TIM_IT_Update: TIM update Interrupt source TIM_IT_CC1: TIM Capture Compare 1 Interrupt source TIM_IT_CC2: TIM Capture Compare 2 Interrupt source TIM_IT_CC3: TIM Capture Compare 3 Interrupt source TIM_IT_CC4: TIM Capture Compare 4 Interrupt source TIM_IT_COM: TIM Commutation Interrupt source TIM_IT_Trigger: TIM Trigger Interrupt source TIM_IT_Break: TIM Break Interrupt source

咱们能够看到此函数TIM_IT参数的取值规模如下:

TIM_IT_Update: TIM update Interrupt source

TIM_IT_CC1: TIM Capture Compare 1 Interrupt source

TIM_IT_CC2: TIM Capture Compare 2 Interrupt source

TIM_IT_CC3: TIM Capture Compare 3 Interrupt source

TIM_IT_CC4: TIM Capture Compare 4 Interrupt source

TIM_IT_COM: TIM Commutation Interrupt source

TIM_IT_Trigger: TIM Trigger Interrupt source

TIM_IT_Break: TIM Break Interrupt source

也便是说每个通道的捕获和比较功用是共用一个中止标志。

stm32定时器输入触发功用其实挺简略的,与AVR单片机简直相同。便是单片机引脚上一旦呈现一个有用边缘(能够装备为上升、下降或许上升下降均触发),那么定时器计数器CNT晒干的值就会被相应的Capture/Compare X Register保存下来。这儿X能够是1,2,3,4任何一个。而且中止标志位被置位。可是此刻TIM的计数寄存器CNT却不论这一事情的发生,持续自己的计数。此功用能够用来丈量外部信号的脉宽或许是周期。

关于定时器的时基单元TIM_TimeBaseStructure就不作阐明晰,在我前面的文章有专门介绍。下面就要点解说输入触发单元TIM_ICInitStructure。

首先看次结构体原型的界说如下:




typedef struct
{

 uint16_t TIM_Channel; /*!< Specifies the TIM channel.
 This parameter can be a value of @ref TIM_Channel */
 uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
This parameter can be a value of @ref TIM_Input_Capture_Polarity */
 uint16_t TIM_ICSelection; /*!< Specifies the input.
 This parameter can be a value of @ref TIM_Input_Capture_Selection */

 uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */

 uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
This parameter can be a number between 0x0 and 0xF */
} TIM_ICInitTypeDef;

它一共有5个成员,5个成员详细效果,咱们只需看看3.5版别固件库的阐明就清楚了。

uint16_t TIM_ICInitTypeDef::TIM_Channel

Specifies the TIM channel. This parameter can be a value of TIM_Channel

其间TIM_Channel的取值规模如下:

TIM_Channel_1.

TIM_Channel_2

TIM_Channel_3

TIM_Channel_4

uint16_t TIM_ICInitTypeDef::TIM_ICFilter

Specifies the input capture filter. This parameter can be a number between 0x0 and 0xF

说实话这个成员详细效果我没有深化了解,仅仅知道是作为对输入信号的滤波效果,估量是让用户设定用多少个采样时钟来确认终究输入信号,起到滤波效果,防止高频信号搅扰,横竖不论它了。

uint16_t TIM_ICInitTypeDef::TIM_ICPolarity

Specifies the active edge of the input signal. This parameter can be a value of TIM_Input_Capture_Polarity

这个便是触发边缘的极性挑选了,取值规模如下:

TIM_ICPolarity_BothEdge

TIM_ICPolarity_Rising

TIM_ICPolarity_Falling

uint16_t TIM_ICInitTypeDef::TIM_ICPrescaler

Specifies the Input Capture Prescaler. This parameter can be a value of TIM_Input_Capture_Prescaler

这个成员是对外部信号进行分频,也便是设置上图中的Prescaler,能够设置为1/2/4/8分频。

uint16_t TIM_ICInitTypeDef::TIM_ICSelection

Specifies the input. This parameter can be a value of TIM_Input_Capture_Selection

这个成员的效果就必须要对照上面的示意图才干理解。细心看上面的图,能够发现定时器的4个通道并不是彻底独立的,而是1、2一组,3、4一组,同组之间的通道是有联络的。也便是能够呈现穿插触发。而TIM_ICSelection便是挑选要不要运用穿插来触发,假如不理解能够看固件库的阐明文档,如下是此结构体成员的取值规模:

#define TIM_ICSelection_DirectTI((uint16_t)0x0001)

TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively

#define TIM_ICSelection_IndirectTI((uint16_t)0x0002)

TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively.

#define TIM_ICSelection_TRC((uint16_t)0x0003)

TIM Input 1, 2, 3 or 4 is selected to be connected to TRC.

也便是说,依据不同的取值,能够讲外部引脚的触发信号连到内部不同的单元,这样就使得单片机愈加灵活了。

下面是main.c文件

#include "stm32f10x.h"

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_ICInitTypeDef TIM_ICInitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

void delay()

{

u32 i,j;

for(i=0;i<1000;i++)

for(j=0;j<5000;j++)

;

}

void rcc_cfg()

{

;

}

void gpio_cfg()

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //随意延时led取反,且将PA8作为触发定时器电平

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //触发中止时,取反PD2

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure);

/* TIM3 channel 2 pin (PA.07) configuration */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

void nvic_cfg()

{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

/* Enable the TIM3 global Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = TIM3_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寄存器

}

void tim3_cfg()

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

TIM_DeInit(TIM3);

TIM_InternalClockConfig(TIM3);

//预分频系数为36000-1,这样计数器时钟为72MHz/36000 = 2kHz

TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;

//设置时钟切割

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

//设置计数器形式为向上计数模

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

//设置计数溢出巨细,每计2000个数就发生一个更新事情

TIM_TimeBaseStructure.TIM_Period = 2000 - 1;

//将装备应用到TIM2中

TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

//制止ARR预装载缓冲器

TIM_ARRPreloadConfig(TIM3, DISABLE);

//下面是对TIM_ICInitStructure的装备

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x0; /*挑选输入比较滤波器,滤波设置,阅历几个周期跳变确定波形安稳0x0~0xF*/

TIM_ICInit(TIM3, &TIM_ICInitStructure);

//舱位TIM2的中止

TIM_ClearFlag(TIM3, TIM_IT_CC2);

TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);

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

}

/

* @brief Main program.

* @param None

* @retval None

*/

int main(void)

{

rcc_cfg();

gpio_cfg();

nvic_cfg();

tim3_cfg();

while (1)

{

/* Set PA8 */

GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);

delay();

/* Reset PA8 */

GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);

delay();

}

}

留意定时器3通道2引脚设置为浮空输入。

下面是stm32f10x_it.c文件

#include "stm32f10x_it.h"

u8 flag=0;

extern TIM_ICInitTypeDef TIM_ICInitStructure;

void TIM3_IRQHandler(void)

{

if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)

{

/* Clear TIM3 Capture compare interrupt pending bit */

TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

//每次进入中止就改动捕获触发方法,且翻转PD2的电平

if(flag==0)

{

flag=1;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

TIM_ICInit(TIM3, &TIM_ICInitStructure);

GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_RESET);

}

else

{

flag=0;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

TIM_ICInit(TIM3, &TIM_%&&&&&%InitStructure);

GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_SET);

}

}

}

程序运转后,能够看到板子上两个led灯替换业绩。

我并没有对捕获值作任何处理,由于我仅仅测验程序是否能顺畅进入捕获中止。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/dianlu/265835.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部