STM32通用定时器基本定时功能与PWM
stm32定时器

STM32定时器定时器功能简介区别于SysTick一般只用于系统时钟的计时,STM32的定时器外设功能非常强大。
STM32一共有8个都为16位的定时器。
其中TIM6、TIM7是基本定时器;TIM 2、TIM3、TIM4、TIM5是通用定时器;TIM1和TIM8是高级定时器。
这些定时器使STM32具有定时、信号的频率测量、信号的PWM测量、PWM输出、三相6步电机控制及编码器接口等功能,都是专门为工控领域量身定做的。
定时器工作分析基本定时器基本定时器TIM6和TIM7只具备最基本的定时功能,就是累加的时钟脉冲数超过预定值时,能触发中断或触发DMA请求。
这两个基本定时器使用的时钟源都是TIMxCLK,时钟源经过PSC预分频器输入至脉冲计数器TIMx_CNT,基本定时器只能工作在向上计数模式,在重载寄存器TIMx_ARR中保存的是定时器的溢出值。
工作时,脉冲计数器TIMx_CNT由时钟触发进行计数,当TIMx_CNT的计数值X等于重载寄存器TIMx_ARR中保存的数值N时,产生溢出事件,可触发中断或DMA请求。
然后TIMx_CNT的值重新被置为0,重新向上计数。
通用定时器相比之下,通用定时器TIM2~TIM5就比基本定时器复杂得多了。
除了基本的定时,它主要用在测量输入脉冲的频率、脉冲宽与输出PWM脉冲的场合,还具有编码器的接口。
通用定时器的基本计时功能与基本定时器的工作方式是一样的,同样把时钟源经过预分频器输出到脉冲计数器TIMx_CNT累加,溢出时就产生中断或DMA请求。
而通用定时器比基本定时器多出的强大功能,就是因为通用定时器多出了一种寄存器----捕获/比较寄存器TIMx_CRR(capture/compareregister)它在输入时被用于捕获(存储)输入脉冲在电平发生翻转时脉冲计数器TI Mx_CNT的当前计数值,从而实现脉冲的频率测量;在输出时被用来存储一个脉冲数值,把这个数值用于与脉冲计数器TIMx_CNT的当前计数值进行比较,根据比较结果进行不同的电平输出定时器的时钟源从时钟源方面来说,通用定时器比基本定时器多了一个选择,它可以使用外部脉冲作为定时器的时钟源。
STM32++定时器与+PWM+快速使用入门

STM32 定时器与 PWM 快速使用入门要求:在万利的开发板 EK-STM32F 上产生周期为1秒,占空比分别为 50% 10%的 PWM 并且点亮板上的 LD1,LD2 灯闪烁。
做法很简单。
STM32的PWM是由定时器来产生的。
可以看出。
定时器3的通道1至4在GPIO端口的映像。
如果是完全映射。
各通道的连接引脚如下:CH1=PC6, CH2=PC7, CH3=PC8, CH4=PC9这样,刚好与板上的LD1,LD2灯符合,因为LD1连接到PC7,LD2连接到PC6引脚。
关于PWM一些知识.STM32的TIMx 是 TIMx_ARR 寄存器确定频率(周期)、由TIMx_CCRx 寄存器确定占空比的信号。
使用定时器3。
而TIM2、3、4的时钟源是 APB1 即是 PCLK1 ( APB1 对应 PCLK1 )PCLK1 = APB1 = HCLK/2 = SYSCLK/2 = 36MHZ (36,000,000 HZ)但是注意:倍频器会自动倍2,即是【72MHZ】!代码如下:voidSTM32_PWM_GPIO_Configuration(void){// 11:完全映像STM32_Afio_Regs->mapr.bit.TIM3_REMAP=3;// LD1 =P7 LD2=PC6/*GPIOA Configuration: ( PC6 PC7 ) TIM3 channel 1 and 2 as alternate function push -pull */STM32_Gpioc_Regs-&F6=Output_Af_push_pull; // PC.06 复用功能推挽输出模式STM32_Gpioc_Regs->crl.bit.MODE6=Output_Mode_50mhz; // PC.06 输出模式,最大速度50MHzSTM32_Gpioc_Regs-&F7=Output_Af_push_pull; // PC.07 复用功能推挽输出模式STM32_Gpioc_Regs->crl.bit.MODE7=Output_Mode_50mhz; // PC.07 输出模式,最大速度50MHz}//end subvoidSTM32_TIM3_Configuration(void){// TIM_DeInit( TIM3);//复位TIM3定时器STM32_Rcc_Regs->apb1rstr.all |= RCC_TIM3RST;STM32_Rcc_Regs->apb1rstr.all &= ~RCC_TIM3RST;//时钟使能STM32_Rcc_Regs->apb1enr.all |=RCC_TIM3EN;/* TIM3 base configuration *///TIM_TimeBaseStructure.TIM_Period = 9999;//TIM_TimeBaseStructure.TIM_Prescaler = 7200;//TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;//TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);STM32_Tim3_Regs->arr.all=9999; // 定时周期,PWM频率! 10毫秒*100=1秒STM32_Tim3_Regs->psc.all=720; // 7200分频 72MHZ/72,00 72,000,000/72,00=10,000STM32_Tim3_Regs->cr1.bit.CKD=0; // 时钟分频因子STM32_Tim3_Regs->cr1.bit.DIR=0; // 0:计数器向上计数/* Clear TIM3 update pending flag[清除TIM3溢出中断标志] *///TIM_ClearFlag(TIM3, TIM_FLAG_Update);STM32_Tim3_Regs->sr.bit.UIF=0; //更新中断标记由软件清0 ,例如当上溢或下溢时,软件对CNT重新初始化/* PWM1 Mode configuration: Channel1 Channel2 *///TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//TIM_OCInitStructure.TIM_Pulse = CCR1_Val;//TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OC1Init(TIM3, &TIM_OCInitStructure);// timer3 的通道1 是 PC6 引脚, AFIO完全映射STM32_Tim3_Regs-&1P=0; // 输入/捕获1输出极性 0:OC1高电平有效 1:OC1低电平有效STM32_Tim3_Regs-&1E=1; // 输入/捕获1输出使能 1:开启- OC1信号输出到对应的输出引脚。
关于STM32的 一个TIM1 的PWM程序和PWM简单使用

TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//先不管
TIM_OC1Init(TIM1,TIM_OCInitStructure); //数初始化外设TIMx通道1这里2.0库为TIM_OCInit
中止PB12。
如果输出与互补输出极性相同的话就刚好输出高互补低至于PWM模式1与模式2的区别
在下图:
这个是模式1的了绿为输出黄为互补
*************************************************************************************************
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*配置TIM1*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
voidTim1_Configuration(void)
TIM_OCInitStructure.TIM_Pulse = 40; //占空时间144中有40的时间为高,互补的输出正好相反
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //互补端的极性
stm32定时器的区别

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

STM32定时器定时时间配置总结STM32系列微控制器内置了多个定时器模块,它们可以用于各种定时功能,如延时、周期性触发、脉冲计数等。
在使用STM32定时器之前,我们需要进行定时时间配置,本文将总结一下STM32定时器定时时间配置的相关知识,包括定时器工作模式、定时器时钟源选择、定时器时钟分频、定时器计数器重载值以及定时器中断配置等内容。
首先,我们需要选择定时器的工作模式。
STM32定时器支持多种工作模式,包括基本定时器模式、高级定时器模式、输入捕获模式和输出比较模式等。
基本定时器模式适用于简单的定时和延时操作,输入捕获模式适用于捕获外部事件的时间参数,输出比较模式适用于产生精确的PWM波形。
根据具体的应用需求,选择合适的工作模式。
其次,我们需要选择定时器的时钟源。
STM32定时器的时钟源可以选择内部时钟源(如系统时钟、HCLK等)或外部时钟源(如外部晶体)。
内部时钟源的稳定性较差,适用于简单的定时操作,而外部时钟源的稳定性较好,适用于要求较高的定时操作。
然后,我们需要选择定时器的时钟分频系数。
定时器的时钟分频系数决定了定时器的时钟频率,从而影响了定时器的计数速度。
我们可以通过改变时钟分频系数来调整定时器的计数速度,从而实现不同的定时时间。
时钟分频系数的选择需要考虑定时器的最大计数周期和所需的定时精度。
接着,我们需要配置定时器的计数器重载值。
定时器的计数器从0开始计数,当计数器达到重载值时,定时器将重新开始计数。
通过改变计数器重载值,可以实现不同的定时时间。
计数器重载值的选择需要考虑定时器的时钟频率和所需的定时时间。
最后,我们需要配置定时器的中断。
定时器中断可以在定时器计数达到重载值时触发,用于通知CPU定时器已经计数完成。
在定时器中断中,我们可以执行相应的中断服务程序,比如改变一些IO口的状态,实现定时操作。
通过配置定时器的中断使能和中断优先级,可以实现不同的中断操作。
需要注意的是,不同型号的STM32微控制器的定时器模块可能略有不同,具体的配置方法和寄存器设置也可能不同,请参考相应的数据手册和参考手册进行具体操作。
STM32之PWM波形输出配置复习总结.doc

STM32之PWM波形输出配置总结1. TIMER 分类STM32中一共有11个定时器,其中TIM6、TIM7是基本定时器;TIM2、TIM3、TIM4、TIM5是通用定时器;TIM1和TIM8是高级定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。
其中系统嘀嗒定时器是前文中所描述的SysTick o其中TIM1和TIM8是能够产生3对PWM互补输出,常用于三相电机的驱动, 时钟由APB2的输岀产生oTIM2-TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。
2. PWM波形产生的原理通用定时器可以利用GPI0引脚进行脉冲输岀,在配置为比较输岀、PWM输出功能时,捕获/比较寄存器TIMx_CCR被用作比较功能,下面把它简称为比较寄存器。
举例说明定时器的PWM输出工作过程:若配置脉冲计数器TIMx_CNT为向上计数,而重载等存器TI Mx_ARR被配置为N,即TI Mx_CNT的当前计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0重新计数。
而在TIMxCNT计数的同时,TIMxCNT的计数值X会与比较寄存器TIMx_CCR 预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较等存器TIMx_CCR 的值A时,输岀高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输岀低电平(或高电平)。
如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1) 乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为A/(N+1) o3. STM32产生PWM的配置方法1)配置GPIO 口不是每一个I0引脚都可以直接使用于PWM输出,下面是定时器的引脚重映像,其实就是引脚的复用功能选择:表定时器的引脚复用功能映像表定时器的引脚复用功能映像表3-4 定时器4的引脚复用功能映像根据以上重映像表,我们使用定时器3的通道2作为PWM的输出引脚,所以需要对PB5引脚进行配置,对10 口操作代码:2)初始化定时器3)设置TIM3_CH2的PWM模式.使能TIM3的CH2输出4)使能定时器3经过以上的操作,定时器3的第二通道已经可以正常工作并输出PWM波了,只是其占空比和频率都是固定的,我们可以通过改变TIM3_CCR2,则可以控制它的占空比。
stm32中定时器产生不同PWM的基本思路

在stm32中利用定时器TIM调制PWM的几种方法:说说我的学习经历:从开始接触到现在有好几个月了,但是学习还是比较的费劲,而且速度也比较的缓慢,当然相比之前还是有很大的进步,记得刚刚学习的时候,建工程都是大四学长手把手教的。
废话不多说先来讲讲定时器的配置:STM32F10系列最少3个、做多有8个定时器,都是16位定时器,且相互之间是独立的,计数范围为0x0000-0xffff,最大计数值为65535.可以用于测量输入信号的脉冲长度或者产生输出波形(输出比较和PWM)分为通用定时器,高级定时器,以及看门狗定时器下面主要讲通用定时器的配置问题:以定时器TIM1为例:先进行函数的配置void timer1_config(){TIM_TimeBaseInitTypDef TIM_TimeBaseStructure;//开定时器1外设时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM1,ENABLE);//计时50000次时间为50000/10M=500msTIM_TimeBaseStructure.TIM_Period=50000 ;TIM_TimeBaseStructure.TIM_Prescaler = 720-1;//720分频TIM_TimeBaseStructure.TIM_ClockDivision =0;//时钟分割为0;//计数模式向上计数TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure)//初始化TIM1TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);//开启定时器中断TIM_Cmd(TIM1,ENABLE); //使能定时器}关于时间的计算问题:外设系统时钟的频率为72M,进行720分频以后,频率f=72M/720=100khz. 如果要定时0.1s则计数值为10000,计算公式为:时间(t)=计数值(n)/频率(f).注意计数值n介于0到65535之间有定时器则一定会有中断发生,所以要配置中断优先级,对于中断优先级函数配置如下:V oid nvic_config(){NVIC_InitTypDef NVIC_InitStructure;//抢占优先级为1位,从优先级为3位NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1) ;NVIC_InitStructure.NVIC_IRQChannel=TIM1_IRQn; //定义定时器1为请求通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占式优先级为0NVIC_InitStructure.NVIC_IRQChannelSubPriority=2; //从优先级为2NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断优先级NVIC_Init(&NVIC_InitStructure); //初始化中断}对于优先级中的抢占式和从优先级做如下解释:抢占式优先级:是可以抢占的中断,比如正在执行的优先级为10的中断,突然来了一个优先级为5的中断,此时cpu会转向优先级为5的中断;从优先级:从优先级不会抢占正在执行的中断程序,但是如果两个事件同时发生,那么cpu 会执行优先级高的事件,但是已经执行就不会再更改了,即使优先级比正在执行的高,这正好和抢占式优先级不同,抢占式优先级不论程序是否在执行,只要现在发生的中断优先级比正在执行的要高,就会更改。
STM32F4通用定时器详细讲解

15 TIM3捕获/比较寄存器3 (TIM3_CCR3)
16 TIM3捕获/比较寄存器4 (TIM3_CCR4)
1 Timer3用来做定时中断
与之相关的时基单元寄存器有
10 TIM3计数器(TIM3_CNT)
11 TIM3预分频器(TIM3_PSC)
1TIM3控制寄存器1 (TIM3_CR1)
ቤተ መጻሕፍቲ ባይዱ作用:1使能自动重载TIM3_ARR
2定时器的计数器递增或递减计数。
3事件更新。
4计数器使能
2TIM3控制寄存器2 (TIM3_CR2)
3TIM3从模式控制寄存器(TIM3_SMCR)
4TIM3DMA/中断使能寄存器(TIM3_DIER)
作用:1:使能事件更新中断
定时器时钟上文已经讲了,由于Timer3挂在APB1总线上
故Timer3进入中断的周期为(CK_PSC+1)*(TIM3_ARR+1)/84000000秒
频率为84000000/[(CK_PSC+1)*(TIM3_ARR+1)] Hz
利用官方库函数实现每500ms进入中断,改变LED灯的电平,程序如下
3:外部时钟模式2:外部触发输入TIMx_ETR,仅适用于TIM2、TIM3、TIM4,TIM3,对应着PD2引脚
4:内部触发输入:一个定时器触发另一个定时器。
时钟源可以通过TIMx_SMCR相关位进行设置。这里我们使用内部时钟。
定时器挂在高速外设时钟APB1或低速外设时钟APB2上,时钟不超过内部高速时钟HCLK,故当APBx_Prescaler不为1时,定时器时钟为其2倍,当为1时,为了不超过HCLK,定时器时钟等于HCLK。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.STM32的Timer简介STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。
其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。
今天主要是研究剩下的8个定时器。
其中TIM1和TIM8是能够产生3对PWM互补输出的高级登时其,常用于三相电机的驱动,时钟由APB2的输出产生。
TIM2-TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。
由于STM32的TIMER功能太复杂了,所以只能一点一点的学习。
因此今天就从最简单的开始学习起,也就是TIM2-TIM5普通定时器的定时功能。
2.普通定时器TIM2-TIM52.1时钟来源计数器时钟可以由下列时钟源提供:·内部时钟(CK_INT)·外部时钟模式1:外部输入脚(TIx)·外部时钟模式2:外部触发输入(ETR)·内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。
由于今天的学习是最基本的定时功能,所以采用内部时钟。
TIM2-TIM5的时钟不是直接来自于APB1,而是来自于输入为APB1的一个倍频器。
这个倍频器的作用是:当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其他数值时(即预分频系数为2、4、8或16),这个倍频器起作用,定时器的时钟频率等于APB1的频率的2倍。
APB1的分频在STM32_SYSTICK的学习笔记中有详细描述。
通过倍频器给定时器时钟的好处是:APB1不但要给TIM2-TIM5提供时钟,还要为其他的外设提供时钟;设置这个倍频器可以保证在其他外设使用较低时钟频率时,TIM2-TIM5仍然可以得到较高的时钟频率。
2.2计数器模式TIM2-TIM5可以由向上计数、向下计数、向上向下双向计数。
向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器内容),然后重新从0开始计数并且产生一个计数器溢出事件。
在向下模式中,计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
而中央对齐模式(向上/向下计数)是计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
2.3编程步骤1.配置系统时钟;2.配置NVIC;3.配置GPIO;4.配置TIMER;其中,前3项在前面的笔记中已经给出,在此就不再赘述了。
第4项配置TIMER有如下配置:(1)利用TIM_DeInit()函数将Timer设置为默认缺省值;(2)TIM_InternalClockConfig()选择TIMx来设置内部时钟源;(3)TIM_Perscaler来设置预分频系数;(4)TIM_ClockDivision来设置时钟分割;(5)TIM_CounterMode来设置计数器模式;(6)TIM_Period来设置自动装入的值(7)TIM_ARRPerloadConfig()来设置是否使用预装载缓冲器(8)TIM_ITConfig()来开启TIMx的中断其中(3)-(6)步骤中的参数由TIM_TimerBaseInitTypeDef结构体给出。
步骤(3)中的预分频系数用来确定TIMx所使用的时钟频率,具体计算方法为:CK_INT/(TIM_Perscaler+1)。
CK_INT是内部时钟源的频率,是根据2.1中所描述的APB1的倍频器送出的时钟,TIM_Perscaler是用户设定的预分频系数,其值范围是从0 – 65535。
步骤(4)中的时钟分割定义的是在定时器时钟频率(CK_INT)与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例。
TIM_ClockDivision的参数如下表:数字滤波器(ETR,TIx)是为了将ETR进来的分频后的信号滤波,保证通过信号频率不超过某个限定。
步骤(7)中需要禁止使用预装载缓冲器。
当预装载缓冲器被禁止时,写入自动装入的值(TIMx_ARR)的数值会直接传送到对应的影子寄存器;如果使能预加载寄存器,则写入ARR的数值会在更新事件时,才会从预加载寄存器传送到对应的影子寄存器。
ARM中,有的逻辑寄存器在物理上对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadow register(影子寄存器);设计preload register和shadow register的好处是,所有真正需要起作用的寄存器(shadow register)可以在同一个时间(发生更新事件时)被更新为所对应的preload register的内容,这样可以保证多个通道的操作能够准确地同步。
如果没有shadow register,或者preload register和shadow register 是直通的,即软件更新preload register时,同时更新了shadow register,因为软件不可能在一个相同的时刻同时更新多个寄存器,结果造成多个通道的时序不能同步,如果再加上其它因素(例如中断),多个通道的时序关系有可能是不可预知的。
3.程序源代码本例实现的是通过TIM2的定时功能,使得LED灯按照1s的时间间隔来闪烁#include "stm32f10x_lib.h"void RCC_cfg();void TIMER_cfg();void NVIC_cfg();void GPIO_cfg();int main(){RCC_cfg();NVIC_cfg();GPIO_cfg();TIMER_cfg();//开启定时器2TIM_Cmd(TIM2,ENABLE);while(1);}void RCC_cfg(){//定义错误状态变量ErrorStatus HSEStartUpStatus;//将RCC寄存器重新设置为默认值RCC_DeInit();//打开外部高速时钟晶振RCC_HSEConfig(RCC_HSE_ON);//等待外部高速时钟晶振工作HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){//设置AHB时钟(HCLK)为系统时钟RCC_HCLKConfig(RCC_SYSCLK_Div1);//设置高速AHB时钟(APB2)为HCLK时钟RCC_PCLK2Config(RCC_HCLK_Div1);//设置低速AHB时钟(APB1)为HCLK的2分频RCC_PCLK1Config(RCC_HCLK_Div2);//设置FLASH代码延时FLASH_SetLatency(FLASH_Latency_2);//使能预取指缓存FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//设置PLL时钟,为HSE的9倍频8MHz * 9 = 72MHzRCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);//使能PLLRCC_PLLCmd(ENABLE);//等待PLL准备就绪while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//设置PLL为系统时钟源RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//判断PLL是否是系统时钟while(RCC_GetSYSCLKSource() != 0x08);}//允许TIM2的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//允许GPIO的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);}void TIMER_cfg(){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//重新将Timer设置为缺省值TIM_DeInit(TIM2);//采用内部时钟给TIM2提供时钟源TIM_InternalClockConfig(TIM2);//预分频系数为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(TIM2,&TIM_TimeBaseStructure);//清除溢出中断标志TIM_ClearFlag(TIM2, TIM_FLAG_Update);//禁止ARR预装载缓冲器TIM_ARRPreloadConfig(TIM2, DISABLE);//开启TIM2的中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);}void NVIC_cfg(){NVIC_InitTypeDef NVIC_InitStructure;//选择中断分组1NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择TIM2的中断通道NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;//抢占式中断优先级设置为0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//响应式中断优先级设置为0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//使能中断NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}void GPIO_cfg(){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //选择引脚5GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率最大50MHz GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //带上拉电阻输出GPIO_Init(GPIOB,&GPIO_InitStructure);}在stm32f10x_it.c中,我们找到函数TIM2_IRQHandler(),并向其中添加代码void TIM2_IRQHandler(void){u8 ReadValue;//检测是否发生溢出更新事件if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){//清除TIM2的中断待处理位TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update);//将PB.5管脚输出数值写入ReadValueReadValue = GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5);if(ReadValue == 0){GPIO_SetBits(GPIOB,GPIO_Pin_5);}else{GPIO_ResetBits(GPIOB,GPIO_Pin_5);}}}STM32学习笔记(5):通用定时器PWM输出1.TIMER输出PWM基本概念脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。