stm32学习经历

stm32学习经历
stm32学习经历

随便写写,关于stm32 最近在学习stm32,写点东西,虽然简单,但都是原创啊

开发板是前辈画的,好像是用来测试一个3G功能的,不过对于我来说太远;我要来了3个,自己焊了一个最小系统,好在公司资源还是不错的,器件芯片有,还可以问问前辈--对公司还是比较满意的,虽然工资少了点,但学东西第一位O(∩_∩)O~。

最开始当然是建工程了,这个真不太会,前前后后竟用了一周(时间真长,别见笑啊),上网查资料,问前辈,自己琢磨。。。总算搞定,然后从GPIO开始学,开始还真没什么头绪(虽然在大学学点51,但完全没有真正应用,顶多是跑马灯实验),开始纠结是从寄存器开始学还是从库函数开始学,后来看到一句“用库函数入门,用寄存器提高”于是下定决心用库,但当时没有库的概念,结果走了很多弯路,看了很多不必要的东西,当时竟没理解到只是调用库就OK了,别的不用管。最后潜心的在https://www.360docs.net/doc/8115512342.html,教程网看完一个例程后照猫画虎写了一个,经过了多次调试以后,灯终于亮了!那个兴奋啊。再次还要感谢

https://www.360docs.net/doc/8115512342.html,/mcu/1106.html 的作者他写的GPIO使用方法让我少走了很多弯路,接着学的EXTI,当时对中断的理解只是概念上的,也不知道中断程序要放在中断函数里(it.c),总之现在想想当时怎么那么不开窍啊。慢慢的中断也弄出来了,一会我会把程序贴出来,很简单的嘿。慢慢的有点感觉找到门了:先大致看一下要学习概要,找个例程,一个函数一个函数的看,重点理解配置的什么,参数,然后在头脑中形成一个大概的轮廓,虽然有时候不是特别清晰;接着学习TIMER(通用定时器),只是学习了最简单的溢出中断,其他捕获什么的都还没有看呢--想先对stm有个总体的学习,下一步准备每个模块细细“研读”。应用定时器溢出中断做了个闪灯小程序;接着顺便把学习过的GPIO,EXTI,TIMER混在一起做了一个优先级(NVIC)的程序,以来了解下优先级,二来对前面的学习是一个复习,虽然很简单,但没能一下子就调出来--其实每次都会在细节上出不少差错:时钟忘使能啦,GPIO没有配置全啦,名称写错啦(很低级,但这个有时候真的不好找),概念理解不对啦。。。。。。有时候憋的真是相当难受,但问题解决的那一刻真怎是一个“爽”字了得啊,当然前提是自己解决的;接下来学USART(串口),原来我也不知道有串口这么个东西,但弄单片机的要是不知道“串口”就好比开车的不知道轮胎一样了,开始完全没有概念,什么波特率啊,奇偶校验位啊,停止位啊,对着一堆名词看着都头大。慢慢的了解到串口是一种通讯传输方式,就和USB一样,只是串口比USB早出生好多年。这时候已经有点门了,看概念,抄例程,看函数,理解,根据自己的理解改参数,实现!学会了串口,以后就可以通过串口来观察数据了(我的实验板可是没有屏的);下一个是DMA,DMA可是个好东西,至于怎么好,百度一下,大家就知道了;下来ADC(模数转换),就是把模拟量转化成数字量,据说stm

之所以强大,ADC算一个重要条件,我只是简单了应用了一个测电压的功能(可以说是ADC 的最简单功能了),用串口显示探针(自己焊上去的)所测到的电压值,主要卡在了两个地方:1忘记配置串口的GPIO(所以一定要注意细节,一个细节能憋我1天) 2对通道的理解不够,原以为通道自己找串口(现在发现自己挺天真的),实际是每个通道对应自己的GPIO 口,或模块(如温度传感器),“一知半解”又让我卡了1天。解决这两个问题后,串口赫然出现数字啦,而且是探地是0,探电源是33xx(3.3V的),还真准呢啊;现在在学习I2C(刚刚开始看),还在看概念。。。

希望自己坚持下去,早日能写出一个属于自己的程序,完成一个说的过去的功能,下面把我的程序粘出来,和大家分享下,大虾看到了别见笑啊

注:1.有两个灯,PA4 B12,都是低电平点亮

2.有两个按键,PB8 和 PB9,按下是低电平

3.程序开始后两个灯常亮,按下按键后熄灭,抬起后继续亮

main.c中

#include "stm32f10x.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_rcc.h"

#include "stm32f10x_exti.h"

void RCC_Configuration(void) //时钟配置函数

{

ErrorStatus HSEStartUpStatus;

//使能外部晶振

RCC_HSEConfig(RCC_HSE_ON);

//等待外部晶振稳定

HSEStartUpStatus = RCC_WaitForHSEStartUp();

//如果外部晶振启动成功,则进行下一步操作

if(HSEStartUpStatus==SUCCESS)

{

//设置HCLK(AHB时钟)=SYSCLK 将系统时钟进行分频后,作为AHB总线时钟

RCC_HCLKConfig(RCC_SYSCLK_Div1);

//PCLK1(APB1) = HCLK/2 将HCLK时钟2分频后给低速外部总线

RCC_PCLK1Config(RCC_HCLK_Div2);

//PCLK2(APB2) = HCLK HCLK时钟配置给高速外部总线

RCC_PCLK2Config(RCC_HCLK_Div1);

//外部高速时钟HSE 4倍频

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4);

//启动PLL

RCC_PLLCmd(ENABLE);

//等待PLL稳定

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

//系统时钟SYSCLK来自PLL输出

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//切换时钟后等待系统时钟稳定

while(RCC_GetSYSCLKSource()!=0x08);

}

// 下面这些都是外设总线上所挂的外部设备时钟的配置

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph _AFIO, ENABLE);

}

void GPIO_Configuration(void) //GPIO配置函数

{

//GPIO_DeInit(GPIOA);

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;

GPIO_Init(GPIOB,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;

GPIO_Init(GPIOB,&GPIO_InitStructure);

}

void EXTI_Config(void)

{

EXTI_InitTypeDef EXTI_InitStructure;

// 管脚选择

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9); // 清除 EXTI线路挂起位

EXTI_ClearITPendingBit(EXTI_Line8|EXTI_Line9);

//

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_Line = EXTI_Line8|EXTI_Line9;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

}

void NVIC_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; // 注意名称是“_IRQn”,不是“_IRQChannel”

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

int main(void)

{

RCC_Configuration();

GPIO_Configuration();

EXTI_Config();

NVIC_Config();

while(1)

{

GPIO_ResetBits(GPIOB,GPIO_Pin_12);

GPIO_ResetBits(GPIOA,GPIO_Pin_4);

}

}

中断文件 it.c中

void EXTI9_5_IRQHandler(void)

{

if ( EXTI_GetITStatus(EXTI_Line8) != RESET )

{

EXTI_ClearITPendingBit(EXTI_Line8);

GPIO_SetBits(GPIOA,GPIO_Pin_4);

while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)==0);

}

if ( EXTI_GetITStatus(EXTI_Line9) != RESET )

{

EXTI_ClearITPendingBit(EXTI_Line9);

GPIO_SetBits(GPIOB,GPIO_Pin_12);

while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9)==0);勤劳的蜜蜂有糖吃

}

}

05_STM32F4通用定时器详细讲解精编版

STM32F4系列共有14个定时器,功能很强大。14个定时器分别为: 2个高级定时器:Timer1和Timer8 10个通用定时器:Timer2~timer5 和 timer9~timer14 2个基本定时器: timer6和timer7 本篇欲以通用定时器timer3为例,详细介绍定时器的各个方面,并对其PWM 功能做彻底的探讨。 Timer3是一个16位的定时器,有四个独立通道,分别对应着PA6 PA7 PB0 PB1 主要功能是:1输入捕获——测量脉冲长度。 2 输出波形——PWM 输出和单脉冲输出。 Timer3有4个时钟源: 1:内部时钟(CK_INT ),来自RCC 的TIMxCLK 2:外部时钟模式1:外部输入TI1FP1与TI2FP2 3:外部时钟模式2:外部触发输入TIMx_ETR ,仅适用于TIM2、TIM3、TIM4,TIM3,对应 着PD2引脚 4:内部触发输入:一个定时器触发另一个定时器。 时钟源可以通过TIMx_SMCR 相关位进行设置。这里我们使用内部时钟。 定时器挂在高速外设时钟APB1或低速外设时钟APB2上,时钟不超过内部高速时钟HCLK ,故当APBx_Prescaler 不为1时,定时器时钟为其2倍,当为1时,为了不超过HCLK ,定时器时钟等于HCLK 。 例如:我们一般配置系统时钟SYSCLK 为168MHz ,内部高速时钟 AHB=168Mhz ,APB1欲分频为4,(因为APB1最高时钟为42Mhz ),那么挂在APB1总线上的timer3时钟为84Mhz 。 《STM32F4xx 中文参考手册》的424~443页列出与通用定时器相关的寄存器一共20个, 以下列出与Timer3相关的寄存器及重要寄存器的简单介绍。 1 TIM3 控制寄存器 1 (TIM3_CR1) SYSCLK(最高 AHB_Prescaler APBx_Prescaler

STM32输入捕获简介

STM32输入捕获简介 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等. 例如:我们用到TIM5_CH1来捕获高电平脉宽,也就是要先设置输入捕获为上升沿检测,记录发生上升沿的时候TIM5_CNT的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的TIM5_CNT值。这样,前后两次TIM5_CNT之差,就是高电平的脉宽,同时TIM5的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。 首先TIMx_ARR和TIMx_PSC,这两个寄存器用来设自动重装载值和TIMx的时钟分频。 再来看看捕获/比较模式寄存器1:TIMx_CCMR1,这个寄存器在输入捕获的时候,非常有用;TIMx_CCMR1明显是针对2个通道的配置,低八位[7:0]用于捕获/比较通道1的控制,而高八位[15:8]则用于捕获/比较通道2的控制,因为TIMx还有CCMR2这个寄存器,所以可以知道CCMR2是用来控制通道3和通道4(详见《STM32参考手册》290页,14.4.8节)。 这里用到TIM5的捕获/比较通道1,我们重点介绍TIMx_CMMR1的[7:0]位(其实高8位配置类似)。 再来看看捕获/比较使能寄存器:TIMx_CCER; 接下来我们再看看DMA/中断使能寄存器:TIMx_DIER,我们需要用到中断来处理捕获数据,所以必须开启通道1的捕获比较中断,即CC1IE设置为1。 控制寄存器:TIMx_CR1,我们只用到了它的最低位,也就是用来使能定时器的; 最后再来看看捕获/比较寄存器1:TIMx_CCR1,该寄存器用来存储捕获发生时,TIMx_CNT的值,我们从TIMx_CCR1就可以读出通道1捕获发生时刻的TIMx_CNT值,通过两次捕获(一次上升沿捕获,一次下降沿捕获)的差值,就可以计算出高电平脉冲的宽度。 使能捕获和更新中断(设置TIM5的DIER寄存器) 因为我们要捕获的是高电平信号的脉宽,所以,第一次捕获是上升沿,第二次捕获时下降沿,必须在捕获上升沿之后,设置捕获边沿为下降沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢出必须做处理,否则结果就不准了。这两件事,我们都在中断里面做,所以必须开启捕获中断和更新中断。 1void init_tim2_cam(u16 psc, u16 arr, u8 way, u8 dir) 2 { 3 RCC->APB1ENR |= 1<<0; //使能定时器2时钟 4 RCC->APB2ENR |= 1<<2; //使能PortA 5 6switch (way) 7 { 8case1: 9 GPIOA->CRL &= 0xfffffff0; 10 GPIOA->CRL |= 0x00000008; 11break; 12case2:

stm32的定时器输入捕获与输出比较

stm32的定时器输入捕获与输出比较 (2015-09-28 09:26:24) 转载▼ 分类:stm32 标签: it 明确一点对比AD的构造,stm32有3个AD,每个AD有很多通道,使用哪个通道就配置成哪个通道,这里定时器也如此,有很多定时器TIMx,每个定时器有很多CHx(通道),可以配置为输入捕捉-------测量频率用,也可以配置为输出比较--------输出PWM使用 输入捕捉:可以用来捕获外部事件,并为其赋予时间标记以说明此事件的发生时刻。 外部事件发生的触发信号由单片机中对应的引脚输入(具体可以参考单片机的datasheet),也可以通过模拟比较器单元来实现。 时间标记可用来计算频率,占空比及信号的其他特征,以及为事件创建日志,主要是用来测量外部信号的频率。 输出比较:定时器中计数寄存器在初始化完后会自动的计数。从bottom计数到top。并且有不同的工作模式。 另外还有个比较寄存器。一旦计数寄存器在从bottom到top计数过程中与比较寄存器匹配则会产生比较中断(比较中断使能的情况下)。 然后根据不同的工作模式计数寄存器将清零或者计数到top值。

1、朋友,可以解释一下输入捕获的工作原理不? 计数寄存器的初值,是自己写进去的吗? 我如果捕获上升沿,两个值相减,代表的时两个上升沿中间那段电平的时间。对不? timer1有五个通道(对应五个IO引脚),在同一时刻,只能捕获一个引脚的值,对不? 那输出比较的原理你可以帮我介绍一下不?

比较单元的值是人为设进去的吧? 上面这个总看不懂,好像不不止你说的那几种情况:“匹配了是io电平取反、变低、还是变高,就会产生不同的波形了” 设置输出就是置1,清除输出就是置0,切换输出就是将原来的电平取反,对不? 011:计数器向上计数达到最大值时将引脚置1,达到0时,引脚电平置0,,对不?

STM32的捕获模式应用

STM32捕获模式应用。。。。。 1、stm32脉冲方波捕获 脉冲方波长度捕获 a)目的:基础PWM输入也叫捕获,以及中断配合应用。使用前一章的输出管脚P B1(19脚),直接使用跳线连接输入的PA3(13脚),配置为TIM2_CH4,进行实验。 b)对于简单的PWM输入应用,暂时无需考虑TIM1的高级功能之区别,按照目前我的应用目标其实只需要采集高电平宽度,而不必知道周期,所以并不采用PWM 输入模式,而是普通脉宽捕获模式。 c)初始化函数定义: void TIM_Configuration(void); //定义TIM初始化函数 d)初始化函数调用: TIM_Configuration(); //TIM初始化函数调用 e)初始化函数,不同于前面模块,TIM的CAP初始化分为三部分——计时器基本初始化、通道初始化和时钟启动初始化: void TIM_Configuration(void)//TIM2的CAP初始化函数 { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定时器初始化结构 TIM_ICInitTypeDef TIM_ICInitStructure; //通道输入初始化结构 //TIM2输出初始化 TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //周期0~FFFF TIM_TimeBaseStructure.TIM_Prescaler = 5; //时钟分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式

STM32通用定时器

STM32通用定时器 一、定时器的基础知识 三种STM32定时器区别 通用定时器功能特点描述: STM3 的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能特点包括: 位于低速的APB1总线上(APB1) 16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为: ①输入捕获 ②输出比较 ③ PWM 生成(边缘或中间对齐模式) ④单脉冲模式输出 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。 如下事件发生时产生中断/DMA(6个独立的IRQ/DMA请求生成器): ①更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ②触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ③输入捕获 ④输出比较 ⑤支持针对定位的增量(正交)编码器和霍尔传感器电路 ⑥触发输入作为外部时钟或者按周期的电流管理 STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。 定时器框图:

倍频得到),外部时钟引脚,可以通过查看数据手册。也可以是TIMx_CHn,此时主要是实现捕获功能; 框图中间的时基单元 框图下面左右两部分分别是捕获输入模式和比较输出模式的框图,两者用的是同一引脚,不能同时使用。

STM32通用定时器学习

STM32通用定时器 STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册…}才搞明白的!所以接下来我以手册的顺序为主线,增加一些自己的理解,并通过11个例程对TIMER做个剖析。实验环境是STM103V100的实验板,MDK3.2 +Library2.东西都不怎么新,凑合用…… TIMER主要是由三部分组成: 1、时基单元。 2、输入捕获。 3、输出比较。 还有两种模式控制功能:从模式控制和主模式控制。 一、框图 让我们看下手册,一开始是定时器的框图,这里面几乎包含了所有定时器的信息,您要是能看明白,那么接下来就不用再看别的了… 为了方便的看图,我对里面出现的名词和符号做个注解: TIMx_ETR:TIMER外部触发引脚 ETR:外部触发输入 ETRP:分频后的外部触发输入 ETRF:滤波后的外部触发输入 ITRx:内部触发x(由另外的定时器触发) TI1F_ED:TI1的边沿检测器。 TI1FP1/2:滤波后定时器1/2的输入 TRGI:触发输入 TRGO:触发输出 CK_PSC:应该叫分频器时钟输入 CK_CNT:定时器时钟。(定时周期的计算就靠它) TIMx_CHx:TIMER的输入脚 TIx:应该叫做定时器输入信号x ICx:输入比较x ICxPS:分频后的ICx OCx:输出捕获x OCxREF:输出参考信号 关于框图还有以下几点要注意: 1、影子寄存器。 有阴影的寄存器,表示在物理上这个寄存器对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预 装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的 寄存器,称为shadow register(影子寄存器);(详细请参考版主博客 https://www.360docs.net/doc/8115512342.html,/STM32/401461/message.aspx) 2、输入滤波机制 在ETR何TIx输入端有个输入滤波器,它的作用是以采样频率 Fdts来采样N次进行滤波的。(具体也请参考版主博客 https://www.360docs.net/doc/8115512342.html,/STM32/263170/message.aspx) 3、输入引脚和输出引脚是相同的。 二、时基单元 时基单元有三个部分:CNT、PSC、ARR。CNT的计数方式分三种:向上、

stm32f407通用定时器输入捕获

通用定时器输入捕获 通用定时器作为输入捕获的使用。我们用TIM5的通道1(PA0)来做输入捕获,捕获PA0上高电平的脉宽(用KEY_UP按键输入高电平),通过串口来打印高电平脉宽时间。 输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量脉宽为例,用一个简图来说明输入捕获的原理: 如图所示,就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,图中t1~t2时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道x为上升沿捕获,这样,t1时刻,就会捕获到当前的CNT值,然后立即清零CNT,并设置通道x为下降沿捕获,这样到t2时刻,又会发生捕获事件,得到此时的CNT值,记为CCRx2。这样,根据定时器的计数频率,我们就可以算出t1~t2的时间,从而得到高电平脉宽。在t1~t2之间,可能产生N次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。如图所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以CNT的计数周期,即可得到t2-t1的时间长度,即高电平持续时间。 STM32F4的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。STM32F4的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA等。这里我们用TIM5_CH1来捕获高电平脉宽。 ============================================================== ===================== 捕获/比较通道(例如:通道1 输入阶段) ============================================================== ===================== 接下来介绍我们需要用到的一些寄存器配置,需要用到的寄存器:TIMx_ARR、TIMx_PSC、

浅谈STM32定时器的输入捕获功能

浅谈STM32定时器的输入捕获功能 STM32系列是ST公司基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核的32位单片机。按内核架构分为不同产品:其中STM32F 系列有:STM32F103增强型系列、STM32F101基本型系列、STM32F105、STM32F107互联型系列增强型系列时钟频率达到72MHz,是同类产品中性能最高的产品;基本型时钟频率为36MHz,以16位产品的价格得到比16位产品大幅提升的性能,是32位产品用户的最佳选择。 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。STM32的输入捕获,简单的说就是通过检测TIMx_CHx 上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。 例如:我们用到TIM5_CH1来捕获高电平脉宽,也就是要先设置输入捕获为上升沿检测,记录发生上升沿的时候TIM5_CNT的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的TIM5_CNT值。这样,前后两次TIM5_CNT之差,就是高电平的脉宽,同时TIM5的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。 首先TIMx_ARR和TIMx_PSC,这两个寄存器用来设自动重装载值和TIMx的时钟分频。再来看看捕获/比较模式寄存器1:TIMx_CCMR1,这个寄存器在输入捕获的时候,非常有用;TIMx_CCMR1明显是针对2个通道的配置,低八位[7:0]用于捕获/比较通道1的控制,而高八位[15:8]则用于捕获/比较通道2的控制,因为TIMx还有CCMR2这个寄存器,所以可以知道CCMR2是用来控制通道3和通道4(详见《STM32参考手册》290页,14.4.8节)。 这里用到TIM5的捕获/比较通道1,我们重点介绍TIMx_CMMR1的[7:0]位(其实高8位配置类似)。

STM32高级定时器、通用定时器TIMx、基本定时器TIM6和TIM7的区别

STM32高级定时器、通用定时器TIMx、基本定时器 TIM6和TIM7的区别 TIM1 和TIM8 定时器的功能包括:●16 位向上、向下、向上/下自动装载计数器●16 位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535 之间的任意数值●多达4 个独立通道:─输入捕获─输出比较─PWM 生成(边缘或中间对齐模式) ─单脉冲模式输出●死区时间可编程的互补输出●使用外部信号控制定时器和定时器互联的同步电路●允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器●刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态●如下事件发生时产生中断/DMA:─更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─输入捕获─输出比较─刹车信号输入●支持针对定位的增量(正交)编码器和霍尔传感器电路●触发输入作为外部时钟或者按周期的电流管理TIMx 主要功能通用TIMx (TIM2、TIM3、TIM4 和TIM5)定时器功能包括:●16 位向上、向下、向上/向下自动装载计数器●16 位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536 之间的任意数值●4 个独立通道:─输入捕获─输出比较─PWM 生成(边缘或中间对齐模式) ─单脉冲模式输出●使用外部信号控制定时器和定时器互连的同步电路●如下事件发生时产生中断/DMA:─更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─输入捕获─输出比较●支持针对定位的增量(正交)编码器和霍尔传感器电路●触发输入作为外部时钟或者按周期的电流管理TIM6 和TIM7 定时器的主要功能包括:

stm32脉冲方波捕获

1、stm32脉冲方波捕获 脉冲方波长度捕获 a)目的:基础PWM输入也叫捕获,以及中断配合应用。使用前一章的输出管脚P B1(19脚),直接使用跳线连接输入的PA3(13脚),配置为TIM2_CH4,进行实验。 b)对于简单的PWM输入应用,暂时无需考虑TIM1的高级功能之区别,按照目前我的应用目标其实只需要采集高电平宽度,而不必知道周期,所以并不采用PWM 输入模式,而是普通脉宽捕获模式。 c)初始化函数定义: void TIM_Configuration(void); //定义TIM初始化函数 d)初始化函数调用: TIM_Configuration(); //TIM初始化函数调用 e)初始化函数,不同于前面模块,TIM的CAP初始化分为三部分——计时器基本初始化、通道初始化和时钟启动初始化: void TIM_Configuration(void)//TIM2的CAP初始化函数 { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定时器初始化结构 TIM_ICInitTypeDef TIM_ICInitStructure; //通道输入初始化结构 //TIM2输出初始化 TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //周期0~F FFF TIM_TimeBaseStructure.TIM_Prescaler = 5; //时钟分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//基本初始化 //TIM2通道的捕捉初始化 TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;//通道选择 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;//下降沿 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;/ /管脚与寄存器对应关系 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频器 TIM_ICInitStructure.TIM_ICFilter = 0x4; //滤波设置,经历几个周期跳变认定波形稳定0x0~0xF TIM_ICInit(TIM2, &TIM_ICInitStructure); //初始化 TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2); //选择时钟触发源 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);//触发方式 TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发 TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE); //打开中断 TIM_Cmd(TIM2, ENABL E); //启动TIM2 }

STM32输入捕获例程

刚刚开始做定时器输入捕获的时候在这个论坛上找了好久,都没有人分享,也有很多人问,无奈自己动手写了。花了一天的时间,这个东西真的不好写了,对比了库的例子,仿真,等。可以说付出了很多。现在完成了和大家分享。希望大家多多支持。这个程序是在定时器输入捕获的基础上看手册完成的, 程序说明:1、程序中定时器4的PB6用于输出频率为1K,占空比为50%的PWM信号。 2、定时器2的PA0用于输入捕获,当程序下到板子上,只有两个脚连在一起才会发生捕获。 3、串口用于发送捕获的值到PC机上。 4、定时器2的CCR1存PWM信号的频率,CCR2存高电平时间。 这里声明一下,如果你要捕获的PWM信号不在ARR,PSC计算的范围内,请自己先计算再使用本程序。 #include "stm32f10x_lib.h" #include "sys.h" #include "delay.h" //延时子函数 #include "usart.h" u16 IC1Value; u16 IC2Value; u16 DutyCycle; u16 Frequency; void PWM_Init(u16 arr,u16 psc); void Capture_Init(u16 arr,u16 psc); int main(void) { Stm32_Clock_Init(9); //系统时钟设置 delay_init(72);//延时函数初始化 uart_init(72,9600); PWM_Init(1000,72-1); //不分频。PWM频率=72000/1440=5Khz Capture_Init(2000,72-1); while(1) { Frequency = 1000000/IC1Value; DutyCycle = (IC2Value*100)/IC1Value;//占空比=(IC2Value/IC1Value)*100; printf("Frequency = %d\r\n",Frequency); printf("DutyCycle = %d\r\n",DutyCycle); printf("suqingxiao\r\n"); } }

理解STM32定时器中的输入捕获滤波器

理解STM32定时器中的输入捕获滤波器 关于STM32定时器中的输入捕获滤波器的功能描述,在中文参考手册中描述如下: 我不理解官方的说明,在网上搜了老半天,基本都是下面这几句话: 1)当滤波器连续采样到N次个有效电平时,认为一次有效的输入电平。 2)该数字滤波器实际上是个事件计数器,它记录到N个事件后会产生一个输出的跳变。例如:当f(CK_INT) = 72MHz, CKD[1:0] = 01时,选择f(DTS) = f(CK_INT)/2 = 36MHz; 而ETF[3:0] = 0100,则采样频率f(SAMPLING) = f(DTS) / 2 = 18MHz, N = 6,此时高于3MHz 的信号 将被这个滤波器滤除,这样就有效地屏蔽了高于3MHz的干扰。 看了这些说法,我还是不理解这个数字滤波器到底是如何工作的,问题如下: 问题1:当滤波器连续采样到N次个有效电平时,是输出这个电平?还是输出一个跳变?问题2:当滤波器没有连续采样到N次个有效电平时,输出是的什么? 带着这两个问题,我们来分析一下,下面以TIM3为例: 首先可以肯定输入捕获过程如下:详细信息见参考手册中的14.2节,通用定时器框图 TIM3_CH1(PA.6) ----> TI1(外部信号) -------> 输入滤波器IC1F[3:0] -----> IC1(滤波器输出信号) -------> 输入捕获预分频器IC1PSC[1:0] ----> 捕获/比较1寄存器CCR1 从上面的过程可以知道, 1)发生输入捕获所需要的跳变沿是由滤波器输出产生的。 2)滤波器和预分频器可软件编程,如果IC1F[3:0] = 0x0,则滤波器全通,即TI1 和IC1是同一个信号。 借助这两点分析,我假设的滤波器的工作原理是: 问题1猜测答案:当滤波器连续采样到N次个有效电平时,就输出这个有效电平。 问题2猜测答案:当滤波器没有连续采样到N次个有效电平时,再从0开始计数,输出一

STM32定时器的输入滤波机制

STM32定时器的输入滤波机制 STM32的定时器输入通道都有一个滤波单元,分别位于每个输入通路上(下图中的黄色框)和外部触发输入通路上(下图中的兰色框),它们的作用是滤除输入信号上的高频干扰。 具体操作原理如下: 在TIMx_CR1中的CKD[1:0]可以由用户设置对输入信号的采样频率基准,有三种选择: 1)采样频率基准f DTS =定时器输入频率f CK_INT 2)采样频率基准f DTS =定时器输入频率f CK_INT /2 3)采样频率基准f DTS =定时器输入频率f CK_INT /4

然后使用上述频率作为基准对输入信号进行采样,当连续采样到N次个有效电平时,认为一次有效的输入电平。 实际的采样频率和采样次数可以由用户程序根据需要选择; 外部触发输入通道的滤波参数在从模式控制寄存器(TIMx_SMCR)的ETF[3:0]中设置; 每个输入通道的滤波参数在捕获/比较模式寄存器1(TIMx_CCMR1)或捕获/比较模式寄存器2(TIMx_CCMR2)的IC1F[3:0]、 IC2F[3:0]、IC3F[3:0]和IC4F[3:0]中设置。 例如:当f CK_INT =72MHz时,选择f DTS =f CK_INT /2=36MHz,采样频率f SAMPLING =f DTS /2=18MHz 且N=6,则频率高于3MHz的信号将被这个滤波器滤除,有效地屏蔽了高于3MHz 的干扰。 比如,结合输入捕获的中断,可以轻松地实现按键的去抖动功能,而不需要软件的干预;这可是由硬件实现的去抖动功能,大大节省了软件的开销和程序代码的长度。

每个定时器最多可以实现4个按键的输入,这个方法也可以用于键盘矩阵的扫描,而且因为是通过中断实现,软件不需频繁的进行扫描动作。

stm32 定时器捕获

//Tim3.h #ifndef __TIM3_H #define __TIM3_H void TIM3_RCC_Configuration(void); void TIM3_GPIO_Configuration(void); void TIM3_NVIC_Configuration(void); void TIM3_Configuration(void); #endif //TIM3.h #include "stm32f10x.h" #include "TIM3.h" /** * @brief Configures the different system clocks. * @param None * @retval None */ /*---Values-------------------------------------------*/ TIM_ICInitTypeDef TIM3_TIM_ICInitStructure; /*-----Functions--------------------------------------*/ void TIM3_Configuration(void) { /* System Clocks Configuration */ TIM3_RCC_Configuration(); /* NVIC configuration */ TIM3_NVIC_Configuration(); /* Configure the GPIO ports */ TIM3_GPIO_Configuration(); /* TIM3 configuration: Input Capture mode --------------------- The external signal is connected to TIM3 CH2 pin (PA.07) The Rising edge is used as active edge, The TIM3 CCR2 is used to compute the frequency value ------------------------------------------------------------ */ TIM3_TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

STM32 定时器触发DMA采集捕获输入值

int main( void ) { // //系统初始化 // system_init( ); //时钟初始化 drv_rcc_init( 0, 0, 64, APB1_PRESC_2, APB2_PRESC_1, 0x08000000 ); hal_timer_init( 5000 ); //TIM1配置为编码器模式DMA触发请求为外部其他定时的触发输出 //TIM4 配置为触发输出用于定时器给一个触发信号到TIM1 //输入通道引脚初始化 drv_rcc_ahb1_clk_enable( RCC_AHBENR_GPIOEEN ); drv_gpio_alternate_function_init( GPIOE, GPIO_PIN_9, GPIO_PUPD_PULL, GPIO_OTYPE_OD, GPIO_SPEED_MID ); drv_gpio_alternate_function_init( GPIOE, GPIO_PIN_11, GPIO_PUPD_PULL, GPIO_OTYPE_OD, GPIO_SPEED_MID ); drv_gpio_alternate_function_connect( GPIOE, GPIO_PINSOURCE9, GPIO_AF2_TIM1 ); drv_gpio_alternate_function_connect( GPIOE, GPIO_PINSOURCE11, GPIO_AF2_TIM1 ); //TIM1初始化 drv_rcc_apb2_clk_enable( RCC_APB2ENR_TIM1EN ); drv_timer_base_init( TIM1, 0, 0xFFFF, TIM_EDGE_CNT_MODE_UP ); drv_timer_select_input_trigger( TIM1, TIM_TS_ITR3 ); drv_timer_select_slave_mode( TIM1, TIM_SLAVE_MODE_EQEP_3 ); // TIM_SLAVE_MODE_TRIGGER //输入通道配置 drv_timer_ic1_init( TIM1, TIM_IC_POLARITY_RISING, TIM_IC_PSC_DIV_1, TIM_IC_SELECTION_1, Filter_NO ); drv_timer_ic2_init( TIM1, TIM_IC_POLARITY_RISING, TIM_IC_PSC_DIV_1, TIM_IC_SELECTION_1, Filter_NO ); drv_timer_ic1_enable( TIM1 ); drv_timer_ic2_enable( TIM1 ); //TIM定时器配置 TIM1->DIER.bit.TDE = 1; //使能触发DMA请求 TIM1->DCR.bit.DBL = 0; //传输个数 TIM1->DCR.bit.DBA = 9; //基地址为TIM1->CNT //TIM1 DMA初始化DMA1 CHANNEL4 :TIM1_TRIG drv_rcc_ahb1_clk_enable( RCC_AHBENR_DMA1EN ); drv_dma_stream_deinit( DMA1_Channel4 ); drv_dma_stream_init( DMA1_Channel4, (UINT32)g_TimerCntBuffer,

stm32定时器捕捉高低电平计时长代码分析

stm32定时器捕捉高低电平计时长代码分析 定时器是stm32 的一大利器,现在的项目中可以说没有一个不会用到定时 器的,所以掌握理解运用定时器才会做出好的产品来。本章内容说一说关于 stm32 的定时器TIM_GetCounter(TIMx)的运用。之前的项目中曾经用这个来获 取高低电平的时长,在超声波测距,红外遥控解码中运用过。Stm32 的定时器 除了1 和8 其他都是通用定时器。如何用这句函数来捕捉电平时长呢?首先看 一下初始化内容,以TIM4 为例 void Timer4_CFG() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO , ENABLE); GPIO_InitStructure.GPIO_Pin = IR_LED_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(IR_LED_PORT, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Prescaler = 3599; //TIM_CKD_DIV1 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // TIM_TimeBaseStructure.TIM_Period = 200; // ARR TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

相关主题
相关文档
最新文档