当前位置:文档之家› stm32学习笔记

stm32学习笔记

stm32学习笔记
stm32学习笔记

目录

Stm32学习笔记—C语言基础部分 (2)

Stm32学习笔记—GPIO部分 (4)

Stm32学习笔记—RCC部分 (6)

Stm32学习笔记—AD部分 (7)

Stm32学习笔记—CAN部分 (8)

Stm32学习笔记—TIM部分 (8)

Stm32学习笔记—USART部分 (11)

Stm32学习笔记—超声波测距部分 (14)

Stm32学习笔记—程序调试部分 (20)

Stm32学习笔记—C语言基础部分1、C语言运算符优先级详细列表

2、数组:在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。

3、在C语言中,字符常量有以下特点:

1) 字符常量只能用单引号括起来,不能用双引号或者是括号

2) 字符常量只能是单个字符,不能是字符串。

3) 字符可以是字符集中任意字符。但数字被定义为字符之后就不能够参与运算。如'5'和5 是不同的。'5'是字符常量,不能参与运算。

Stm32学习笔记—GPIO部分

1、函数名GPIO_ReadInputDataBit 功能描述读取指定端口管脚的输入

2、对于GPIO的配置种类有8种之多:

(1)GPIO_Mode_AIN 模拟输入

(2)GPIO_Mode_IN_FLOATING 浮空输入

(3)GPIO_Mode_IPD 下拉输入

(4)GPIO_Mode_IPU 上拉输入

(5)GPIO_Mode_Out_OD 开漏输出

(6)GPIO_Mode_Out_PP 推挽输出

(7)GPIO_Mode_AF_OD 复用开漏输出

(8)GPIO_Mode_AF_PP 复用推挽输出

3、推挽输出:可以输出高,低电平,连接数字器件; 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源低定。推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。

4、如图所示,推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的电流则减小,二者的状态轮流转换。对负载而言,好像是一个“臂”在推,一个“臂”在拉,共同完成电流输出任务。当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。这样一来,输出高低电平时,VT3 一路和VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。

5、开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内).

开漏形式的电路有以下几个特点:

利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是

从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)

6、3. OPEN-DRAIN提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。

7、4. 可以将多个开漏输出的Pin,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。补充:什么是“线与”?:

8、在一个结点(线)上, 连接一个上拉电阻到电源VCC 或VDD 和n 个NPN 或NMOS 晶体管的集电极C 或漏极D, 这些晶体管的发射极E 或源极S 都接到地线上, 只要有

一个晶体管饱和, 这个结点(线)就被拉到地线电平上. 因为这些晶体管的基极注入电流(NPN)或栅极加上高电平(NMOS),晶体管就会饱和, 所以这些基极或栅极对这个结点(线)的关系是或非NOR 逻辑. 如果这个结点后面加一个反相器, 就是或OR 逻辑.

9、

10、其实可以简单的理解为:在所有引脚连在一起时,外接一上拉电阻,如果有一个引脚输出为逻辑0,相当于接地,与之并联的回路“相当于被一根导线短路”,所以外电路逻辑电平便为0,只有都为高电平时,与的结果才为逻辑1。

11、关于推挽输出和开漏输出,最后用一幅最简单的图形来概括:

12、该图中左边的便是推挽输出模式,其中比较器输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当比较器输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平。右边的则可以理解为开漏输出形式,需要接上拉。

13、

14、浮空输入:对于浮空输入,一直没找到很权威的解释,只好从以下图中去理解了

15、由于浮空输入一般多用于外部按键输入,结合图上的输入部分电路,我理解为浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的。

16、上拉输入/下拉输入/模拟输入:这几个概念很好理解,从字面便能轻易读懂。

17、复用开漏输出、复用推挽输出:可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)

18、最后总结下使用情况:

19、在STM32中选用IO模式

(1)浮空输入_IN_FLOATING ——浮空输入,可以做KEY识别,RX1

(2)带上拉输入_IPU——IO内部上拉电阻输入

(3)带下拉输入_IPD——IO内部下拉电阻输入

(4)模拟输入_AIN ——应用ADC模拟输入,或者低功耗下省电

(5)开漏输出_OUT_OD ——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能

(6)推挽输出_OUT_PP ——IO输出0-接GND,IO输出1 -接VCC,读输入值是未知的

(7)复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)

(8)复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS)

20、STM32设置实例:

(1)模拟I2C使用开漏输出_OUT_OD,接上拉电阻,能够正确输出0和1;读值时先GPIO_SetBits(GPIOB, GPIO_Pin_0);拉高,然后可以读IO的值;使用

GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0);

(2)如果是无上拉电阻,IO默认是高电平;需要读取IO的值,可以使用带上拉输入_IPU 和浮空输入_IN_FLOATING和开漏输出_OUT_OD;

Stm32学习笔记—RCC部分

1、RCC有多种用途,包括时钟设置,外设复位和时钟管理。

2、RTC时钟:系统时钟:简单的说,就是芯片系统内部的时钟,程序运行的速度是由它来决定的。RTC:实时时钟,如果供电,它会按照自己的精确等级运行的,主要用来做日期时间的显示用。

3、时钟树

4、配置时钟树的方法:

(1)定义一个定义一个定义一个ErrorStatu 类型的变量HSEStartUpStatus

(2)将时钟树复位至默认设置

(3)开启HSE 晶振;

(4)等待HSE 晶振起振稳定,并将起结果保存HSEStartUpStatus 变量中;

(5)判断HSE 晶振是否起成功

(6)设置HCLKHCLK 时钟为时钟为SYSCL的分频

(7)设置PLCK2 时钟为时钟为SYSCLK的分频;

(8)设置PLCK1 时钟为时钟为SYSCLK的分频;

Stm32学习笔记—AD部分

1、采样保持器:计算机系统模拟量输入通道中的一种模拟量存储装置。它是连接采样器和模数转换器的中间环节。采样器是一种开关电路或装置,它在固定时间点上取出被处理信号的值。采样保持器则把这个信号值放大后存储起来,保持一段时间,以供模数转换器转换,直到下一个采样时间再取出一个模拟信号值来代替原来的值。在模数转换器工作期间采样保持器一直保持着转换开始时的输入值,因而能抑制由放大器干扰带来的转换噪声,降低模数转换器的孔径时间,提高模数转换器的精确度和消除转换时间的不准确性。一般生产过程控制计算机的模拟量输入可能是每秒几十点、几百点,对于大型系统甚至上千点,往往需要高速采样(如5000~10000点/秒)。为使这些模拟量信号逐个地送到模数转换器,而不至降低被测信号的真实性,必须采用采样保持器。在低速系统中一般可以省略这种装置。

原理采样保持电路由模拟开关、存储元件和缓冲放大器A组成。在采样时刻,加到模拟开关上的数字信号为低电平,此时模拟开关被接通,使存储元件(通常是电容器)两端的电压UB随被采样信号UA变化。当采样间隔终止时,D变为高电平,模拟开关断开,UB则保持在断开瞬间的值不变。缓冲放大器的作用是放大采样信号,它在电路中的连接方式有两种基本类型:一种是将信号先放大再存储,另一是先存储再放大。对理想的采样保持电路,要求开关没有偏移并能随控制信号快速动作,断开的阻抗要无限大,同时还要求存储元件的电压能无延迟地跟踪模拟信号的电压,并可在任意长的时间内保持数值不变。

2、采样频率英文名称:sampling frequency 定义:在模数转换器中采样时间间隔的倒数。

3、Ad转换器的分类

4、Ad转换器的技术指标:转换时间和转换速率分辨率量化误差转换精度

5、Ad位数的选择

6、Ad转换速率的确定

7、工作电压和基准电压

8、Ad的工作模式:

(1)独立模式:分为单通道单次转换模式、多通道(扫描)单次转换模式、单通道连续转换模式、多通道连续转换模式、注入转换模式

单次转换模式下,ADC只执行一次转换。

在连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。

扫描模式,此模式用来扫描一组模拟通道。

注入转换模式:当触发方式为软件出发或者外部出发方式时,可以使用此模式。

(2)双adc模式:分为同时为规则模式、快速交替模式、慢速交替模式、交替触发模式、混合同步注入及+交替模式

9、规则通道和注入通道的区别:

STM32的每个ADC模块通过内部的模拟多路开关,可以切换到不同的输入通道并进行转换。STM32特别地加入了多种成组转换的模式,可以由程序设置好之后,对多个模拟通道自动地进行逐个地采样转换。

有2种划分转换组的方式:规则通道组和注入通道组。通常规则通道组中可以安排最多16个通道,而注入通道组可以安排最多4个通道。

在执行规则通道组扫描转换时,如有例外处理则可启用注入通道组的转换。一个不太恰当的比喻是:规则通道组的转换好比是程序的正常执行,而注入通道组的转换则好比是程序正常执行之外的一个中断处理程序。

从系统设计上,测量并显示室内温度的过程中断了测量并显示室外温度的过程,但程序

设计上可以在初始化阶段分别设置好不同的转换组,系统运行中不必再变更循环转换的配置,从而达到两个任务互不干扰和快速切换的结果。可以设想一下,如果没有规则组和注入组的划分,当你按下按钮后,需要从新配置AD循环扫描的通道,然后在施放按钮后需再次配置AD循环扫描的通道。

10、SRAM

SRAM是英文Static RAM的缩写,即静态随机存储器。它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据。

11、DMA原理:DMA(Direct Memory Access,直接内存存取) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依于CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU 对于其他的工作来说就无法使用。

Stm32学习笔记—CAN部分

1、bxCAN主要特点

支持CAN协议2.0A和2.0B主动模式

波特率最高可达1兆位/秒

支持时间触发通信功能

发送

3个发送邮箱,发送报文的优先级特性可软件配置,发送SOF时刻的时间戳

接收

3级深度的2个接收FIFO,14个位宽可变的过滤器组

标识符列表

FIFO溢出处理方式可配置,记录接收SOF时刻的时间戳,时间触发通信模式,禁止自动重传模式,16位自由运行定时器,可在最后2个数据字节发送时间戳

管理

中断可屏蔽,邮箱占用单独1块地址空间,便于提高软件效率

2、

Stm32学习笔记—TIM部分

1、通用定时器(TIM)

通用定时器是一个通过可编程预分频器驱动的16 位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入采集)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。定时器是完全独立的,而且没有互相共享任何资源。

2、SCB是MDK库文件里面定义的一个结构体,subsystem control block子系统管理模块

3、TIMER主要是由三部分组成:时基单元、输入捕获、输出比较,还有两种模式控制功能:从模式控制和主模式控制。

4、定时器的计数模式:

向上计数模式,

向下计数模式,在向下模式中,计数器从自动装入的值(TIMx_ARR计数器的值)开始向下计数到0,然后从自动装入的值重新开始并且产生一个计数器向下溢出事件。

每次计数器溢出时可以产生更新事件,在TIMx_EGR寄存器中设置UG位(通过软件方式或者使用从模式控制器)也同样可以产生一个更新事件。

设置TIMx_CR1寄存器的UDIS位可以禁止UEV事件。这样可以避免向预装载寄存器中写入新值时更新影子寄存器。因此UDIS位被清为0之前不会产生更新事件。然而,计数器仍会从当前自动加载值重新开始计数,同时预分频器的计数器重新从0开始(但预分频器的速率不能被修改)。

此外,如果设置了TIMx_CR1寄存器中的URS位(选择更新请求) ,设置UG位将产生一个更新事件UEV但不设置UIF标志(因此不产生中断和DMA请求),这是为了避免在发生捕获事件并清除计数器时,同时产生更新和捕获中断。

当发生更新事件时,所有的寄存器都被更新,并且(根据URS位的设置)更新标志位(TIMx_SR寄存器中的UIF位)也被设置。

中央对齐模式,

5、时基单元包含:

计数器寄存器(TIMx_CNT)

预分频器寄存器(TIMx_PSC),预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。

自动装载寄存器(TIMx_ARR),自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在TIMX_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器。

6.可设置时长的定时器的方法

设置计数器的时钟频率。

设置计数器的计数初值。

打开计数器开始计数。开启中断。

执行中断服务程序

7、通用定时器的时钟来源:

内部时钟(CK_INT)

外部时钟模式1:外部输入脚(TIx)

外部时钟模式2:外部触发输入(ETR)

内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

8、计数器时钟频率的计算方法

9、从库函数角度设置定时时间

(1)Timx时钟使能:通用定时器挂在APB1下,通过APB1总线的使能函数来使能,函数为RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,enable)

(2)初始化定时器参数:设置自动重装值、分频系数和计数方式等,函数原形为:TIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) 功能描述:根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位,输入参数1,TIMx:x可以是2,3或者4,来选择TIM外设;输入参数2TIM-TimeBase_InitStruct:指

向结构TIM_TimeBaseInitTypeDef的指针,包含了TIMx时间基数单位的配置信息。TIM_TimeBaseInitTypeDef定义于文件“stm32f10x_tim.h”:

typedef struct

{

u16 TIM_Period;

u16 TIM_Prescaler;

u8 TIM_ClockDivision;

u16 TIM_CounterMode;

} TIM_TimeBaseInitTypeDef;

TIM_Period设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在0x0000和0xFFFF之间。

TIM_Prescaler

TIM_Prescaler设置了用来作为TIMx时钟频率除数的预分频值。它的取值必须在0x0000和0xFFFF之间。

TIM_ClockDivision

TIM_ClockDivision设置了时钟分割

(3)设置timx-dier允许更新中断:函数原形void TIM_ITConfig(TIM_TypeDef* TIMx, u16 TIM_IT, FunctionalState NewState)功能描述,使能或者失能指定的TIM中断,输入参数1TIMx:x可以是2,3或者4,来选择TIM外设;输入参数2,TIM_IT:待使能或者失能的TIM 中断源,输入参数3NewState:TIMx中断的新状态,这个参数可以取:ENABLE或者DISABLE 输入参数TIM_IT使能或者失能TIM的中断。可以取下表的一个或者多个取值的组合作为该参数的值。TIM_IT_Update TIM中断源,TIM_IT_CC1 TIM捕获/比较1中断源,TIM_IT_CC2 TIM捕获/比较2中断源,TIM_IT_CC3,TIM捕获/比较3中断源TIM_IT_CC4 TIM捕获/比较4中断源,TIM_IT_Trigger TIM触发中断源

(4)设置中断优先级,在nvic的寄存器中设置

(5)使能timx

(6)编写中断服务函数

10、TIM_ClearFlag 函数原形void TIM_ClearFlag(TIM_TypeDef* TIMx, u32 TIM_FLAG)

功能描述,清除TIMx的待处理标志位,输入参数1,TIMx:x可以是2,3或者4,来选择TIM 外设,输入参数2,TIM_FLAG:待清除的TIM标志位

TIM_FLAG值:

TIM_FLAG_Update TIM更新标志位

TIM_FLAG_CC1 TIM捕获/比较1标志位

TIM_FLAG_CC2 TIM捕获/比较2标志位

TIM_FLAG_CC3 TIM捕获/比较3标志位

TIM_FLAG_CC4 TIM捕获/比较4标志位

TIM_FLAG_Trigger TIM触发标志位

TIM_FLAG_CC1OF TIM捕获/比较1溢出标志位

TIM_FLAG_CC2OF TIM捕获/比较2溢出标志位

TIM_FLAG_CC3OF TIM捕获/比较3溢出标志位

TIM_FLAG_CC4OF TIM捕获/比较4溢出标志位

11、函数名:TIM_GetCounter

函数原形:u16 TIM_GetCounter(TIM_TypeDef* TIMx)

功能描述:获得TIMx计数器的值

输入参数:TIMx:x可以是2,3或者4,来选择TIM外设

12、函数名TIM_ GetITStatus

函数原形TIM_GetITStatus(TIM_TypeDef* TIMx, u16 TIM_IT)

功能描述检查指定的TIM中断发生与否

输入参数1TIMx:x可以是2,3或者4,来选择TIM外设

输入参数2TIM_IT:待检查的TIM中断源

13、函数名TIM_ITConfig

函数原形void TIM_ITConfig(TIM_TypeDef* TIMx, u16 TIM_IT, FunctionalState NewState) 功能描述使能或者失能指定的TIM中断

输入参数1TIMx:x可以是2,3或者4,来选择TIM外设

输入参数2TIM_IT:待使能或者失能的TIM中断源

输入参数3NewState:TIMx中断的新状态

这个参数可以取:ENABLE或者DISABLE

TIM_IT

TIM_IT_UpdateTIM中断源

TIM_IT_CC1TIM捕获/比较1中断源

TIM_IT_CC2TIM捕获/比较2中断源

TIM_IT_CC3TIM捕获/比较3中断源

TIM_IT_CC4TIM捕获/比较4中断源

TIM_IT_TriggerTIM触发中断源

14、函数名TIM_ ClearITPendingBit

函数原形void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, u16 TIM_IT)

功能描述清除TIMx的中断待处理位

输入参数1TIMx:x可以是2,3或者4,来选择TIM外设

输入参数2TIM_IT:待检查的TIM中断待处理位

15、STM32中有多达8个定时器,其中TIM1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动,它们的时钟由APB2的输出产生。其它6个为普通定时器,时钟由APB1的输出产生。

Stm32学习笔记—USART部分

1、简单的define定义

#define MAXTIME 1000

一个简单的MAXTIME就定义好了,它代表1000,如果在程序里面写

if(i

编译器在处理这个代码之前会对MAXTIME进行处理替换为1000。

这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为define的定义更像是简单的文本替换,而不是作为一个量来使用,这个问题在下面反映的尤为突出。

2、常见的头文件

#include //定义输入/输出函数

#include //定义杂项函数及内存分配函数

#include //字符串处理

#include //定义关于时间的函数

#include //定义输入/输出函数

#include //字符处理

#include //中断优先级分组

#include数学函数库包含一些数学计算的公式

3、UART:universal asynchronous receiver and transmitter通用异步收发器

USART:universal synchronous asynchronous receiver and transmitter通用同步异步收发器

都是指单片机的串口通讯,工作方式不一样而已!

4、USART主要特性

●全双工的,异步通信

●NRZ标准格式

●分数波特率发生器系统─发送和接收共用的可编程波特率,最高达4.5Mbits/s

●可编程数据字长度(8位或9位)

●可配置的停止位-支持1或2个停止位

●可配置的使用DMA的多缓冲器通信

─在SRAM里利用集中式DMA缓冲接收/发送字节

●单独的发送器和接收器使能位

●检测标志─接收缓冲器满─发送缓冲器空─传输结束标志

●校验控制─发送校验位─对接收数据进行校验

5、异步串行通信协议需要定义以下5个内容:

起始位、数据位、奇偶校捡位、停止位、波特率设置

6、应用场合:芯片之间近距离,与PC机之间的通信和模块之间远距离通信

7、串口通信(Serial Communication),是指外设和计算机间,通过数据信号线、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。

8、PC的串口就是COM口,TxD和RxD和GND就是包括在COM口中。接口通过三个引脚与其他设备连接在一起(见图236)。任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。

9、函数USART_SendData,,函数原形void USART_SendData(USART_TypeDef* USARTx, u8 Data),功能描述通过外设USARTx发送单个数据,USARTx:x可以是1,2或者3,来选择USART外设,输入参数2,Data: 待发送的数据

10、函数USART_ReceiveData,函数原形u8 USART_ReceiveData(USART_TypeDef* USARTx),功能描述,返回USARTx最近接收到的数据输入参数,USARTx:x可以是1,2或者3,来选择USART外设

11、USART_GetFlagStatus,函数原形FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, u16 USART_FLAG) ,功能描述,检查指定的USART标志位设置与否,输入参数1 USARTx:x可以是1,2或者3,来选择USART外设,输入参数2 ,USART_FLAG:待检查的USART标志位

12、USART_FLAG值

USART_FLAG_CTS CTS标志位

USART_FLAG_LBD LIN中断检测标志位

USART_FLAG_TXE 发送数据寄存器空标志位

USART_FLAG_TC 发送完成标志位

USART_FLAG_RXNE 接收数据寄存器非空标志位

USART_FLAG_IDLE 空闲总线标志位

USART_FLAG_ORE 溢出错误标志位

USART_FLAG_NE 噪声错误标志位

USART_FLAG_FE 帧错误标志位

USART_FLAG_PE 奇偶错误标志位

13、USART_ ClearFlag函数原形void USART_ClearFlag(USART_TypeDef* USARTx, u16 USART_FLAG)功能描述,清除USARTx的待处理标志位,输入参数1,USARTx:x可以是1,2或者3,来选择USART外设,输入参数2,USART_FLAG:待清除的USART标志位。

14、USART_ITConfig,函数名函数原形void USART_ITConfig(USART_TypeDef* USARTx, u16 USART_IT, FunctionalState NewState)功能描述,使能或者失能指定的USART中断,输入参数1,USARTx:x可以是1,2或者3,来选择USART外设,输入参数2,USART_IT:待使能或者失能的USART中断源,输入参数3,NewState:USARTx中断的新状态,这个参数可以取:ENABLE或者DISABLE

USART_IT值

USART_IT_PE 奇偶错误中断

USART_IT_TXE 发送中断

USART_IT_TC 传输完成中断

USART_IT_RXNE 接收中断

USART_IT_IDLE 空闲总线中断

USART_IT_LBD LIN中断检测中断

USART_IT_CTS CTS中断

USART_IT_ERR 错误中断

15、USART1重映像

STM32上有很多I/O口,也有很多的内置外设想I2C,ADC,ISP,USART等,为了节省引出管脚,这些内置外设基本上是与I/O口共用管脚的,也就是I/O管脚的复用功能。但是STM32还有一特别之处就是:很多复用内置的外设的I/O引脚可以通过重映射功能,从不同的I/O管脚引出,即复用功能的引脚是可通过程序改变的.读到这里相信大家都应该了解了端口重映射的一些概念了

16、串口是需要使用IO口来进行发送和接收的。

17函数名USART_ SendData

函数原形void USART_SendData(USART_TypeDef* USARTx, u8 Data)

功能描述通过外设USARTx发送单个数据

输入参数1 USARTx:x可以是1,2或者3,来选择USART外设

输入参数2 Data: 待发送的数据

Stm32学习笔记—超声波测距部分

1、程序目的:使用STM32控制超声波模块并使用USART显示

#include "stm32f10x.h"

#include "math.h"

#include "stdio.h"

#include "time.h"

void Tim2_Init(void);

void GPIO_Configuration(void);

void RCC_Configuration(void);

void USART_Configuration(void);

u16 Sensor_using(void);

void delay(void);

main()

{

u16 result=0;

u8 i;

FlagStatus Status;

/*system clock init*/

RCC_Configuration();

/*I\O init*/

GPIO_Configuration();

/*TIM初始化*/

USART_Configuration();

Tim2_Init();

while(1)

{

u16 m;

result=Sensor_using();

i=((u8)((result&0xff00)>>8)); // 输出高八位//

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

USART_SendData(USART1,i);

i=((u8)result&0x00ff); //输出低八位//

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET);

USART_SendData(USART1,i);

for(m=800;m>0;m--)

{

delay();

}

}

}

void RCC_Configuration(void)

{

ErrorStatus HSEStartUpStatus;

RCC_DeInit(); //时钟控制寄存器全部恢复默认值

RCC_HSEConfig(RCC_HSE_ON); //外部高速时钟源开启(8M晶振)HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部时钟就绪

if(HSEStartUpStatus == SUCCESS) //如果时钟启动成功

{

RCC_HCLKConfig(RCC_SYSCLK_Div1); //定义AHB设备时钟为系统时钟1分频

RCC_PCLK2Config(RCC_HCLK_Div1); //定义APB2设备时钟为HCLK时钟1分频

RCC_PCLK1Config(RCC_HCLK_Div2); //定义APB1设备时钟为HCLK时钟2分频

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟为外部高速时钟的9倍频,8MHz * 9 = 72 MHz

RCC_PLLCmd(ENABLE); //使能PLL时钟

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟设置完成准备就绪

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //使用PLL时钟作为系统时钟源

while(RCC_GetSYSCLKSource() != 0x08) //返回系统所用时钟源确认为外部高速晶振,8M晶振。

{

}

}

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE , ENABLE);

}

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB, ENABLE);

/*Echo pin define*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOE, &GPIO_InitStructure);

/*Trigle pin define*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOE, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

}

void USART_Configuration(void) //串口配置程序

{

USART_InitTypeDef USART_InitStructure;

USART_https://www.doczj.com/doc/d315051273.html,ART_BaudRate =115200; //设置串口波特率USART_https://www.doczj.com/doc/d315051273.html,ART_WordLength = USART_WordLength_8b; //设置数据长度为8位

USART_https://www.doczj.com/doc/d315051273.html,ART_StopBits = USART_StopBits_1; //设置一个停止位USART_https://www.doczj.com/doc/d315051273.html,ART_Parity = USART_Parity_No ; //无校验位

USART_https://www.doczj.com/doc/d315051273.html,ART_HardwareFlowControl =

USART_HardwareFlowControl_None; //禁止硬件流控制模式USART_https://www.doczj.com/doc/d315051273.html,ART_Mode =USART_Mode_Rx|USART_Mode_Tx; //打开串口的发送功能

USART_Init(USART1, &USART_InitStructure); //用以上参数初始化USART1 USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //打开接收中断USART_Cmd(USART1, ENABLE); //打开串口1

}

void Tim2_Init(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

TIM_DeInit(TIM2);//复位TIM2定时器

TIM_TimeBaseStructure.TIM_Period=0xffff;

TIM_TimeBaseStructure.TIM_Prescaler=0;

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_PrescalerConfig(TIM2,359,TIM_PSCReloadMode_Immediate);//时钟频率为

72MHz/(359+1)=200000

TIM_ARRPreloadConfig(TIM2, DISABLE);

TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE);

}

/*返回值为毫米级*/

u16 Sensor_using(void)

{

u16 TIM;

GPIO_SetBits(GPIOE,GPIO_Pin_10);

delay();

GPIO_ResetBits(GPIOE,GPIO_Pin_10);

TIM2->CNT=0; //计数器清0//

while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_9)==0); //等待ECHO脚高电平// TIM_Cmd(TIM2, ENABLE);

while((GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_9)==1));

TIM=TIM_GetCounter(TIM2);//ECHO脚低电平后读取计数器的值,从而算出往返时间TIM_Cmd(TIM2, DISABLE);

return(TIM);

}

void delay(void)

{

u32 i;

i=10000;

while(i--);

}

51超声波测距程序如

下:

//Trig = P2^0

//Echo = P3^2

#include

#define uchar unsigned char

#define uint unsigned int//

void delay(uint z)

{

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

//

void delay_20us()

{

uchar a ;

for(a=0;a<100;a++);

}

//*************************************************************** //显示数据转换程序

void display(uint temp)

{

uchar ge,shi,bai;

bai=temp/100;

shi=(temp%100)/10;

ge=temp%10;

wela=1;

P0=0xf7;

wela=0;

dula=1;

P0=table[bai];

dula=0;

delay(1);

dula=1;

P0=0x00; //关位码

dula=0;

wela=1;

P0=0xef;

wela=0;

dula=1;

P0=table[shi];

dula=0;

delay(1);

dula=1;

P0=0x00; //关位码

dula=0;

dula=1;

P0=table[ge];

dula=0;

wela=1;

P0=0xdf;

delay(1);

dula=1;

P0=0x00; //关位码

dula=0;

}

//*************************************************************** void main()

{

uint distance;

test =0;

Trig=0; //首先拉低脉冲输入引脚

EA=1; //打开总中断0

TMOD=0x10; //定时器1,16位工作方式

while(1)

{

EA=0; //关总中断

Trig=1; //超声波输入端

delay_20us(); //延时20us

Trig=0; //产生一个20us的脉冲

while(Echo==0); //等待Echo回波引脚变高电平

succeed_flag=0; //清测量成功标志

EA=1;

EX0=1; //打开外部中断0

TH1=0; //定时器1清零

TL1=0; //定时器1清零

TF1=0; //计数溢出标志

TR1=1; //启动定时器1

delay(20); //等待测量的结果

TR1=0; //关闭定时器1

EX0=0; //关闭外部中断0

if(succeed_flag==1)

{

time=timeH*256+timeL;

distance=time*0.172; //厘米

display(distance);

}

if(succeed_flag==0)

{

distance=0; //没有回波则清零

test = !test; //测试灯变化

}

}

}

//*************************************************************** //外部中断0,用做判断回波电平

void exter() interrupt 0 // 外部中断0是0号

{

timeH =TH1; //取出定时器的值

timeL =TL1; //取出定时器的值

succeed_flag=1;//至成功测量的标志

EX0=0; //关闭外部中断

}

//**************************************************************** //定时器1中断,用做超声波测距计时

void timer1() interrupt 3 //

{

TH1=0;

TL1=0;

}

Stm32学习笔记—程序调试部分

1、关掉无关中断

2、Usart发送不了16位的数

3、注意GPIO几种输入和输出方式的区别

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.doczj.com/doc/d315051273.html,/STM32/401461/message.aspx) 2、输入滤波机制 在ETR何TIx输入端有个输入滤波器,它的作用是以采样频率 Fdts来采样N次进行滤波的。(具体也请参考版主博客 https://www.doczj.com/doc/d315051273.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;

相关主题
文本预览
相关文档 最新文档