两天学习了一下stm32通用定时器的输入捕获功能。在网上看到很多网友说触发中断程序进不了,于是自己也测试了个小程序,还好能够进入中断。呵呵~
实现功能: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()
{undefined
u32 i,j;
for(i=0;i<1000;i++)
for(j=0;j<5000;j++)
;
}
void rcc_cfg()
{undefined
;
}
void gpio_cfg()
{undefined
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()
{undefined
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()
{undefined
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)
{undefined
rcc_cfg();
gpio_cfg();
nvic_cfg();
tim3_cfg();
while (1)
{undefined
/* 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;
上一篇:STM32的定时器有两种捕获模式
下一篇:STM32定时器输出比较模式
推荐阅读最新更新时间:2024-11-16 20:03
推荐帖子
- DS1302做的LCD1602时钟晶振不起振
- 我用万用板做了个DS1302和1602显示的时钟,1602能显示时间但是时间不走。。。。DS1302的32.768KHZ的晶振两脚有电压但很少。。。请问是什么原因啊????谢谢DS1302做的LCD1602时钟晶振不起振你的补偿电容是多呢。??、一般用的是15P的。。你可以在示波器上观察一下。。。或者并一个电阻来加速起振。,30P的有两个问题,1、是否仅仅是1302的问题呢?如果是,你用示波器看看晶振,是否起振2、如果不是,你看看是否是其他问题,我觉得你的
- leijiayou 51单片机
- 不知道有没有用过ADS1247芯片的?
- 最近调试ADS1247,用dSPIC33Fj做主控芯片,I/O模拟SPI时序。在试着读ADS1247内部寄存器的值时,但是每次读出来的值都不一样,不知道SPI通信是否正确?不知道有没有用过ADS1247芯片的?我最近在调试ADS1246,调试了挺久的没调通,楼主能不能给发一下你的源程序?谢谢啦!541195483@qq.com我调试过ADS1146,是16位的,ADS1247是24位的;输入管脚要加一个共模电压,否则读写寄存器不正确,不知道你是不是这个问题。墨眉发表于201
- fx-sg TI技术论坛
- [Micropython]TPYBoard v10x VS183B红外遥控器控制开发板
- 本文只是简单的红外遥控器控制TPYBoardv102开发板资料。可以做的拓展非常多,VS1838固件见附件。1.实验目的:•学习使用红外接收头VS1838的使用2.所需原器件:•TPYBoardv10X开发板1块•红外接收头VS1838一个•microUSB数据线1条•杜邦线若干•红外遥控器一个3.实验原
- loktar MicroPython开源版块
- 触摸感应式应用设计指南
- 刚刚看了个不错的资料,分享给大家,正在边喝茶边看呢。触摸感应式应用设计指南
- gaoyang9992006 stm32/stm8
- DC/DC 24V转5V
- 有个项目24V转5V打算用Ti的TPS54331但是客户要求这个模块要耐3kvAC,请教这一点如何才能做的到。DC/DC24V转5V更正一下是这个电源模块的隔离电压3KV回复楼主rhoda_yao的帖子改了用Top414的方案了回复沙发rhoda_yao的帖子
- rhoda_yao 电源技术
- 【2024 DigiKey 创意大赛】物料开箱--跑通所有官方例程
- ESP32S3_EV_BOARD开箱最后时刻搭上来年度创意大赛的末班车,拿下来心心念念的ESP32S3_EV_BOARD。鉴于上一年的翻车事件,今年低调很多,再也不敢开那些天马行空的题目了,低调的做一些物联网项目,目标是力保不翻车。虽然迟到了一个月,基础学习不能少。EV_BOARD开发板上乐鑫官方推出为S3性能背书的产品,展示了S3在物联网、人机交互、视频语音方面的潜力。这些相关的Demo在官方网站上可以轻松获取,但全部正常跑通的人不多,原因是Espress
- genvex DigiKey得捷技术专区
设计资源 培训 开发板 精华推荐
- 使用 ON Semiconductor 的 STK350-010 的参考设计
- 【显示类】 8*8LED点阵屏
- 当 LTC2377CDE-16 中启用数字增益压缩时,使用 LT6350 的典型应用被配置为接受 ±10V 输入信号,同时运行一个 5.5V 单电源
- 使用 Analog Devices 的 LTM8003-3.3IY 的参考设计
- DER-243 - 65W 适配器
- 使用 Infineon Technologies AG 的 OMR7805ST 的参考设计
- 使用 56F8357 混合控制器的 PMSM 伺服系统设计电路
- AM1G-4815DZ ±15V 1 瓦 DC-DC 转换器的典型应用
- 【广西师大校赛】任意波形发生器
- LT1933 微型电路从最低 4.5V 电源产生 3.3V 和 5V
- 大联大品佳集团推出以复旦微和ams OSRAM产品为主的汽车氛围灯方案
- 为啥车载操作系统(Vehicle OS)越来越重要了呢?
- 车载传感器 — 一文详解激光雷达
- 汽车(超声波、毫米波、激光)雷达之间的简单区别
- 汽车电路相关知识大全
- Bourns 推出两款厚膜电阻系列,具备高功率耗散能力, 采用紧凑型 TO-220 和 DPAK 封装设计
- SABIC进一步深化与博鳌亚洲论坛的战略合作伙伴关系
- 使用 3.3V CAN 收发器在工业系统中实现可靠的数据传输
- 凌华智能推出AmITX Mini-ITX 主板,助力边缘人工智能和物联网创新
- 英飞凌携手马瑞利采用AURIX™ TC4x MCU系列推动区域控制单元创新