stm32库函数学习篇

最新更新时间:2022-05-31来源: eefocus关键字:stm32  库函数  交替闪烁 手机看文章 扫描二维码
随时随地手机看文章

两天学习了一下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;

[1] [2] [3]
关键字:stm32  库函数  交替闪烁 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic563158.html

上一篇:STM32的定时器有两种捕获模式
下一篇:STM32定时器输出比较模式

推荐阅读

STM32Cube.AI v7.2现可支持深度量化神经网络
意法半导体近期发布的 STM32Cube.AI v7.2 带来了对深度量化神经网络的支持功能,从而可以在现有微控制器上运行更准确的机器学习应用软件。STM32Cube.AI 于 2019 年推出,用于把神经网络转换为适合STM32 MCU 的代码。该解决方案依附于 STM32CubeMX,这是一个帮助开发人员初始化STM32芯片的图形界面软件。同时,STM32Cube.AI 还用到 X-CUBE-AI软件包,其中包含用于转换训练好的神经网络的程序库。开发人员可以参照我们的入门指南,从STM32CubeMX内部开始使用 X-CUBE-AI并体验新功能。 目前,新增加的深度量化神经网络支持已经出现在我们与施耐德电气合作开发的人数统计应用
发表于 2022-09-23
STM32Cube.AI v7.2现可支持深度量化神经网络
stm32 printf重定向 无法输出问题
我明明重定向了fputc 函数 但是无法在串口助手 输出内容最后发现 不只是需要重定向fputc 函数 还需要配置魔术棒需要勾选这个Use Micro LIB然后重新编译 下载进去串口助手就能正常显示我的数据了
发表于 2022-09-23
<font color='red'>stm32</font> printf重定向 无法输出问题
STM32如何新建工程+寄存器点亮LED灯
STM32新建工程跟51差不多的,但是32会多点东西,比如加载芯片支持包啦,启动文件啦。还有一个很重要的 你得有KEIL5 是吧哈哈 我这里就不写如何安装KEIL5了 网上挺多资源的,这里就主要写一下如何新建工程点亮一个LED灯。我这里用STM32F103C8T6我这里用STM32F103C8T6一: 如何新建工程1:下载芯片支持包Keil.STM32Fxxxx.pack文件1.进入KEIL5官网。找到自己的型号这样就下载了 芯片支持包了。2:打开KEIL5 加载Keil.STM32Fxxxx.pack文件.打开KEIL5把 下载的 Keil.STM32Fxxxx.pack文件 加载进去。3:添加编写代码文件main.c 以及 添加
发表于 2022-09-23
<font color='red'>STM32</font>如何新建工程+寄存器点亮LED灯
STM32F103标准库开发:Keil5新建STM32工程
新建STM32工程步骤一:创建工程模板文件新建一个文件夹 template在文件夹template里面新建四个文件(1)CMSIS: 存放内核驱动程序和启动引导文件(2)FWLIB:存放库函数文件(3)Project:存放工程文件(4)User: 存放用户程序(主函数)具体效果图如下:步骤二:导入stm32固件库STM32固件库的下载链接1. 打开STM32F10x固件库文件其中需要用到的两个文件:Libraries和Project。2. 导入文件到 CMSIS 文件(1)导入内核驱动程序STM32F10x_StdPeriph_Lib_V3.6.0LibrariesCMSISCM3CoreSupport 中的两个文件复制到CMSIS
发表于 2022-09-21
STM32F103标准库开发:Keil5新建<font color='red'>STM32</font>工程
MSP430F5529基于CCS库函数开发——软件安装与库函数配置
前言通过MSP430官方的函数库进行开发,开发工具使用CCS。主要步骤如下:1、下载并安装CCS2、下载函数库3、部署函数库1、下载并安装CCSCCS是由美国德州仪器公司(Texas Instrument,TI)出品的代码开发和调试套件,具体的可以自行去百度,直接到官网下载安装即可。下载完成后解压即可,右击以管理员身份运行其中的可执行文件。安装就是傻瓜式安装就不贴出来了。安装完成后首先选择自己的一个工作空间,可以理解为放代码的仓库地址。新建CCS项目选择芯片型号,填写工程名称,选择main模板这样就创建好了默认的工程文件2、下载函数库直接进入官网下载即可,同时可以下载一下指南解压后可以在其中找到MSP430F5529的函数库文件可以
发表于 2022-09-20
MSP430F5529基于CCS<font color='red'>库函数</font>开发——软件安装与<font color='red'>库函数</font>配置
STM32 上使用 printf 输出函数
如果要实现在串口 或者 LCD 上显示,必须重定义标准库函数里调用的与输出设备相关的函数。如果使用 printf 输出到串口,需要将 fputc 里面的输出指向串口,这一过程就叫重定向。那么如何让 STM32 使用 printf 函数呢?只需要将 fputc 里面的输 出指向 STM32 串口即可。int fputc(int ch,FILE *p) //函数默认的,在使用 printf 函数时自动调用{USART_SendData(USART1,(u8)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);return ch;}在将printf重定向之后,就可以使用
发表于 2022-09-19
<font color='red'>STM32</font> 上使用 printf 输出函数

推荐帖子

单片机通信Proteus仿真实验
本实验是设置八个按键在上位机按下,下位机接收到数据后执行。分别控制八个LED灯,内部有介绍一些关于ASCII可显示字符的使用。在低一个显示字符我改动原来是1=31的一个值。改成/=2F...很好理解的,自己多试试改别的也可以。 仿真原理图如下.单片机源程序如下: /******************************************************************** 函数功能:往串口发送一字节数据(可通过超级终端显示出来,超级终端波特率选为9600)。
Jacktang 微控制器 MCU
关于STK的疑问
这段时间要做STK相关的应用,之前没有什么经验,啃完了GSM11.14,还是有些疑问请教论坛的高手! ProactiveSIM会在一次APDU交互过程中以91**代替9000表示一次APDU交互的成功,同时也是告知ME,自己有命令要传送。ME收到91**的状态字符之后,就会在适当的时间发送FETCH命令取到SIM要发送下来的Command,并根据命令执行相关的操作,然后再发送TerminalResponse命令,告知SIM命令的处理结果! 以上是我对SIM一次主动命令执行的交互过程的理解
hzw9111 嵌入式系统
Zigbee模块如何连接第三方网关,如Philips Hue,Amazon alexa等。标准协议是什么?
本帖最后由Lin0000于2019-6-1916:49编辑 Zigbee模块如何连接第三方网关,如PhilipsHue,Amazonalexa等。标准协议是什么?例:A厂家的模块能否连接B厂家的网关,如果可以是否有一条标准协议?协议编号是什么?IEEE802.15.4标准跟网关方面有关系吗?请论坛里的大神帮忙解答谢谢! Zigbee模块如何连接第三方网关,如PhilipsHue,Amazonalexa等。标准协议是什么?
Lin0000 RF/无线
基于MSP430F6XXX的FFT变换,没有眉目
想用FFT来做信号处理,主控是MSP430F6xxx的,请问应该怎么弄?或者有没有做过相关项目的人?求指点,给个思路 基于MSP430F6XXX的FFT变换,没有眉目
suoma 微控制器 MCU
求助:两个机器互相ping的问题!
两个机器都是vxWorks。由于两个机器是网线直连,这就引入了一个问题。如果机器不开机则网卡没有激活,创建的socket会丢数据。所以甲机器写了一个ping程序,如果甲先开机则首先通过ping来判断乙是否已经开机,判断乙开机后才创建socket,从而保证通信质量。但现在发现一个非常奇怪的现象:甲相连其他的windows机器(不下5台),都可以实现上述意图。但就是连接乙,如果甲先开机,乙后开,则始终Ping不通。但如果乙先开机,后开甲,却能ping通并成功创建socket。请问各位大虾,这是什么原
fsadfsfsf 嵌入式系统
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2022 EEWORLD.com.cn, Inc. All rights reserved