stm32高级定时器使用教程
- 格式:doc
- 大小:332.50 KB
- 文档页数:8
STM32定时器配置(TIM1、TIM2、TIM3、TIM4、TIM5、TIM8)⾼级定时。
⽂章结构:——> ⼀、定时器基本介绍——> ⼆、普通定时器详细介绍TIM2-TIM5——> 三、定时器代码实例⼀、定时器基本介绍之前有⽤过野⽕的学习板上⾯讲解很详细,所以直接上野⽕官⽅的资料吧,作为学习参考笔记发出来⼆、普通定时器详细介绍TIM2-TIM52.1 时钟来源计数器时钟可以由下列时钟源提供:·内部时钟(CK_INT)·外部时钟模式1:外部输⼊脚(TIx)·外部时钟模式2:外部触发输⼊(ETR)·内部触发输⼊(ITRx):使⽤⼀个定时器作为另⼀个定时器的预分频器,如可以配置⼀个定时器Timer1⽽作为另⼀个定时器Timer2的预分频器。
由于今天的学习是最基本的定时功能,所以采⽤内部时钟。
TIM2-TIM5的时钟不是直接来⾃于APB1,⽽是来⾃于输⼊为APB1的⼀个倍频器。
这个倍频器的作⽤是:当APB1的预分频系数为1时,这个倍频器不起作⽤,定时器的时钟频率等于APB1的频率(36MHZ);当APB1的预分频系数为其他数值时(即预分频系数为2、4、8或16),这个倍频器起作⽤,定时器的时钟频率等于APB1的频率的2倍。
{假如APB1预分频为2(变成36MHZ),则定时器TIM2-5的时钟倍频器起作⽤,将变成2倍的APB1(2x36MHZ)将为72MHZ给定时器提供时钟脉冲。
⼀般APB1和APB2的RCC时钟配置放在初始化函数中例如下⾯的void RCC_Configuration(void)配置函数所⽰,将APB1进⾏2分频,导致TIM2时钟变为72MHZ输⼊。
如果是1分频则会是36MHZ输⼊,如果4分频:CKINT=72MHZ/4x2=36MHZ; 8分频:CKINT=72MHZ/8x2=18MHZ;16分频:CKINT=72MHZ/16x2=9MHZ}1//系统时钟初始化配置2void RCC_Configuration(void)3 {4//定义错误状态变量5 ErrorStatus HSEStartUpStatus;6//将RCC寄存器重新设置为默认值7 RCC_DeInit();8//打开外部⾼速时钟晶振9 RCC_HSEConfig(RCC_HSE_ON);10//等待外部⾼速时钟晶振⼯作11 HSEStartUpStatus = RCC_WaitForHSEStartUp();12if(HSEStartUpStatus == SUCCESS)13 {14//设置AHB时钟(HCLK)为系统时钟15 RCC_HCLKConfig(RCC_SYSCLK_Div1);16//设置⾼速AHB时钟(APB2)为HCLK时钟17 RCC_PCLK2Config(RCC_HCLK_Div1);18 //设置低速AHB时钟(APB1)为HCLK的2分频(TIM2-TIM5输⼊TIMxCLK频率将为72MHZ/2x2=72MHZ输⼊)19 RCC_PCLK1Config(RCC_HCLK_Div2);20//设置FLASH代码延时21 FLASH_SetLatency(FLASH_Latency_2);22//使能预取指缓存23 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);24//设置PLL时钟,为HSE的9倍频 8MHz * 9 = 72MHz25 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);26//使能PLL27 RCC_PLLCmd(ENABLE);28//等待PLL准备就绪29while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);30//设置PLL为系统时钟源31 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);32//判断PLL是否是系统时钟33while(RCC_GetSYSCLKSource() != 0x08);34 }35//允许TIM2的时钟36 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);37//允许GPIO的时钟38 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);39 }APB1的分频在STM32_SYSTICK的学习笔记中有详细描述。
stm32 timer 用法摘要:1.引言2.STM32定时器简介3.STM32定时器工作原理4.STM32定时器配置与使用5.STM32定时器应用实例6.总结正文:1.引言STM32是一款广泛应用于嵌入式系统的微控制器,拥有丰富的外设资源。
其中,定时器(Timer)是STM32外设中非常关键的部分,它在系统时钟、输入捕捉、输出比较、PWM等功能中起着举足轻重的作用。
本文将详细介绍STM32定时器的用法。
2.STM32定时器简介STM32定时器主要包括基本定时器(Basic Timer)、高级定时器(Advanced Timer)和看门狗定时器(Watchdog Timer)。
其中,基本定时器主要用于系统时钟的生成和控制;高级定时器具有更多的功能,如输入捕捉、输出比较、PWM等;看门狗定时器用于检测系统的运行状态,防止系统崩溃。
3.STM32定时器工作原理STM32定时器的工作原理主要基于计数器、预分频器和比较器。
计数器用于记录定时器滴答(Tick)的数量;预分频器用于控制定时器滴答频率;比较器用于产生定时器溢出信号。
当定时器溢出时,定时器硬件会自动产生中断,通过编程可以设置相应的中断处理程序,实现特定功能。
4.STM32定时器配置与使用配置STM32定时器主要包括以下步骤:(1)使能定时器:通过设置相应寄存器位,使能定时器;(2)配置定时器工作模式:根据需求选择定时器工作模式,如计数模式、PWM模式等;(3)配置定时器时钟源:选择定时器时钟源,如内部时钟、外部时钟等;(4)配置定时器预分频器:设置定时器预分频器值,以满足定时器滴答频率要求;(5)配置比较器:设置比较器值,以产生定时器溢出信号;(6)配置中断:根据需求配置定时器中断,如使能中断、设置优先级等。
5.STM32定时器应用实例以下是一个简单的STM32定时器应用实例:使用STM32F103C8T6微控制器实现一个LED闪烁的程序。
(1)配置定时器:使能定时器TIM2,设置工作模式为计数模式,时钟源为内部时钟,预分频器值为72000,比较器值为65536。
本文讲述如何配置单片机STM32F407VET6高级定时器TIM1输出六路带死区互补PWM波形。
一、高级定时器TIM1介绍
高级定时器TIM1有5种计数模式:
TIM_CounterMode_Up、TIM_CounterMode_Down
TIM_CounterMode_CenterAligned1
TIM_CounterMode_CenterAligned2
TIM_CounterMode_CenterAligned3
PWM输出有2种模式:
TIM_OCMode_PWM1、TIM_OCMode_PWM2
查看ST官方RM0090参考手册,高级定时器TIM1框图如下:
本文以高级定时器TIM1工作在TIM_CounterMode_Up模式,PWM工作在TIM_OCMode_PWM1为例,讲述如何配置输出六路带死区互补PWM波形。
二、配置代码示例
1.IO配置
硬件IO说明
TIM1_CH1---->PE9 TIM1_CH1N---->PE8
TIM1_CH2---->PE11 TIM1_CH2N---->PE10
TIM1_CH3---->PE13 TIM1_CH3N---->PE12
IO配置具体代码如下:
2. 定时器配置
三、实验测试
1. 测试硬件平台接线
2.测试结果
由测试结果可以看到高级定时器TIM1可以输出六路带死区互补PWM波形。
具体死区时间如何计算,下篇文章会讲解,敬请关注!。
STM32CUBEMX配置教程(十二)STM32的定时器触发的固定频率ADC采样(使用DMA)本教程将向您展示如何使用STM32CubeMX配置定时器触发的固定频率ADC采样,并使用DMA进行数据传输。
此配置可以用于您需要按照固定频率对模拟信号进行采样的应用中。
在开始之前,请确保已安装好STM32CubeMX和相应的IDE(如Keil、IAR等),并且您已熟悉STM32CubeMX的基本使用方法。
以下是配置步骤:1. 打开STM32CubeMX,并选择您的目标MCU型号。
2. 在"Pinout & Configuration"选项卡中,配置定时器和ADC引脚。
a.选择一个定时器,并设置其时钟源和频率。
您可以选择任何一个可用的定时器来触发ADC采样。
b.配置ADC引脚,将其连接到您的模拟信号源。
3. 在"Configuration"选项卡中,配置ADC。
a.启用ADC和DMA控制器。
b.配置ADC分辨率,采样时间和采样周期。
这些参数取决于您的应用需求。
c. 在"Mode"选项中,选择"Continuous Conversion Mode"。
这样ADC将会不断地根据定时器触发进行采样。
d. 启用"DMA Continuous Requests"。
这样当ADC完成一次采样后,DMA控制器将自动将数据传输到内存中。
4. 在"NVIC Settings"选项卡中,启用DMA和ADC中断。
5. 在"Project"选项卡中,选择生成代码所需的IDE和工程路径。
然后单击"Generate Code"按钮生成代码。
现在您已成功配置了定时器触发的固定频率ADC采样,并使用DMA进行数据传输。
您可以在生成的代码中初始化和启用各个模块,并编写相应的中断处理函数来处理DMA和ADC中断。
STM32高级定时器死区时间设置探究一、死区设置位置:决定死区时间设置的位是‘刹车和死区寄存器TIM1->BDTR’中的DTG[7:0],设置范围是0x00~0xff。
二、死区时间设置公式如下:DT为死区持续时间,TDTS为系统时钟周期时长,Tdtg为系统时钟周期时长乘以倍数后的死区设置时间步进值。
在72M的定时器时钟下TDTS=1/72M=13.89ns.所以以第一个公式,死区时间能以13.89ns的步进从0调整到127*13.89ns=1764ns第二个公式则能(64+0)*2*13.89~(64+63)*2*13.89=1777.9ns~3528.88ns换个角度看,就是(128~254)*13.89同理,第三个公式就是3555.84ns~7000.56ns换个角度看,就是(256~504)*13.89第四个公式就是7111.68ns~14001.12ns换个角度看,就是(512~1008)*13.89综上:死区时间就是不同的公式代表不同范围的死区时间设置,这个范围是互不重叠的。
而但是在不同的死区时间范围内死区时间设置步进是不同的。
若某个系统时钟下的死区时间不够,可以通过改变定时器时钟来改变最大死区时间范围。
当根据硬件电路的特性定下死区时间后,可以根据目标死区时间范围来找到相应的公式,然后代入公式求解出相应的整数(有时候不一定是整数,那就选择最近的那个),拼接DTG[7:5]+DTG[4:0]即可。
例子:这样当我需要3us的死区持续时间时,则可这么计算:3us在第二个公式决定的死区范围之内。
所以选择第二个公式。
3000/(13.89*2)=108,所以DTG[5:0]=108-64=44,所以DTG=127+44=171=0XabTIM1->BDTR|=0xab;反过来验算//72Mhz,死区时间=13.89nsX108*2=3000us经示波器验证,完全正确。
By zxx2013.07.18。
STM32定时器的使用流程1. 简介STM32定时器是STM32系列微控制器中重要的外设之一。
定时器可以用于生成特定的定时器事件,实现计时、测量时间间隔、产生PWM信号等功能。
本文将介绍STM32定时器的使用流程。
2. STM32定时器的基本工作原理STM32定时器通常由一个或多个计数器和若干个通道组成。
计数器用于计算时间的流逝,而通道用于控制输出。
计数器的计数范围和分辨率可以根据需求进行配置。
通常情况下,定时器通过外部时钟源进行计数,也可以使用内部时钟源。
3. STM32定时器的使用流程使用STM32定时器通常需要以下步骤:3.1 初始化定时器在使用定时器之前,需要初始化定时器的相关参数,包括计数器的计数范围、分频系数等。
通常可以通过寄存器的设置来完成初始化工作。
使用HAL库的话,可以使用HAL_TIM_Base_Init()函数进行初始化。
3.2 配置定时器的工作模式定时器可以根据需求配置为不同的工作模式,常见的模式包括单脉冲模式、连续模式、PWM输出模式等。
可以使用TIM_CR1、TIM_CR2等寄存器进行配置。
使用HAL库的话,可以使用相应的函数进行配置。
3.3 配置定时器的中断和DMA定时器可以配置中断和DMA功能,在特定的条件下触发相应的中断或DMA请求。
可以使用TIM_DIER寄存器进行配置。
使用HAL库的话,可以使用相应的函数进行配置。
3.4 启动定时器在配置完成后,需要启动定时器开始计数。
可以使用TIM_CR1寄存器进行配置。
使用HAL库的话,可以使用相应的函数进行配置。
3.5 处理定时器中断如果配置了定时器中断,当定时器达到设定的计数值时,会触发中断。
在中断服务函数中可以根据需求进行相应的处理。
3.6 设置定时器输出如果配置了定时器的通道输出模式,可以在定时器计数到一定值时,通过通道输出相应的信号。
可以使用TIM_CCR1、TIM_CCR2等寄存器进行配置。
3.7 停止定时器如果需要停止定时器的计数,可以使用TIM_CR1寄存器进行配置。
STM32F407高级定时器TIM1定时配置因为在网上很难找到高级定时器TIM1 的配置,而且高级定时器的配置跟普通定时器不太一样,所以记录一下。
实验板子:正点原子探索者STM32F407ZGT6TIM1、TIM8至TIM11的时钟为APB2时钟的两倍即168M,TIM2至TIM7、TIM12~TIM14的时钟为APB1的时钟的两倍即84M。
//初始化配置void Timer1_Init(u16 arr,u16 psc){TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrecture;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); /*使能定时器1的时钟*/NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;/*定时器1的中断通道使能*/NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/*定时器1的中断通道使能*/NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/*抢占优先级*/NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;/*响应优先级*/NVIC_Init(&NVIC_InitStructure);/*配置中断分组,并使能中断*/TIM_TimeBaseInitStrecture.TIM_Period = arr;/*重装载寄存器*/TIM_TimeBaseInitStrecture.TIM_Prescaler = psc;/*预分配*/TIM_TimeBaseInitStrecture.TIM_ClockDivision = TIM_CKD_DIV1;/*时钟分频*/TIM_TimeBaseInitStrecture.TIM_CounterMode = TIM_CounterMode_Up;/*向上计数*/TIM_TimeBaseInitStrecture.TIM_RepetitionCounter = 0;/*重复计数寄存器*/TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStrecture);/*初始化*/TIM_ClearFlag(TIM1,TIM_FLAG_Update);/*清更新标志位*/TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);/*使能中断*/TIM_Cmd(TIM1,ENABLE);/*使能计数*/}中断函数//中断函数void TIM1_UP_TIM10_IRQHandler(void){if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)//检查指定的TIM中断发生与否:TIM 中断源{TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清除TIMx的中断待处理位:TIM 中断源/***************在此处添加中断执行内容******************/LED1 = ~LED1;printf('定时器1定时器1定时器1定时器1定时器1定时器1');}}主函数测试int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168); //初始化延时函数uart_init(115200);//PA9 PA10 初始化串口波特率为115200//LED_Init(); //PF9 PF10Timer1_Init(10000-1,8400-1);// (10000 x 8400) / 168M = 0.5s.while(1){}}。
高级定时器(TIM1和TIM8)由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱。
它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。
使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。
高级控制定时器和通用定时器是完全独立的,它们不共享任何资源。
它们可以同步操作。
Table 457. TIM寄存器寄存器描述CR1 控制寄存器1CR2 控制寄存器2SMCR 从模式控制寄存器DIER DMA/中断使能寄存器SR 状态寄存器EGR 事件产生寄存器CCMR1 捕获/比较模式寄存器1CCMR2 捕获/比较模式寄存器2CCER 捕获/比较使能寄存器CNT 计数器寄存器PSC 预分频寄存器APR 自动重装载寄存器CCR1 捕获/比较寄存器1CCR2 捕获/比较寄存器2CCR3 捕获/比较寄存器3CCR4 捕获/比较寄存器4DCR DMA控制寄存器DMAR 连续模式的DMA地址寄存器Table 458. 例举了TIM的库函数Table 458. TIM库函数函数名描述TIM_DeInit 将外设TIMx寄存器重设为缺省值TIM_TimeBaseInit根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位TIM_OCInit 根据TIM_OCInitStruct 中指定的参数初始化外设TIMxTIM_ICInit 根据TIM_ICInitStruct 中指定的参数初始化外设TIMxTIM_TimeBaseStructInit 把TIM_TimeBaseInitStruct 中的每一个参数按缺省值填入TIM_OCStructInit 把TIM_OCInitStruct 中的每一个参数按缺省值填入TIM_ICStructInit 把TIM_ICInitStruct 中的每一个参数按缺省值填入TIM_Cmd 使能或者失能TIMx 外设TIM _ITConfig 使能或者失能指定的TIM 中断TIM_DMAConfig 设置TIMx的DMA接口TIM_DMACmd 使能或者失能指定的TIMx 的DMA请求TIM_InternalClockConfig 设置TIMx 内部时钟TIM_ITRxExternalClockConfig 设置TIMx 内部触发为外部时钟模式TIM_TIxExternalClockConfig 设置TIMx 触发为外部时钟TIM_ETRClockMode1Config 配置TIMx 外部时钟模式1TIM_ETRClockMode2Config 配置TIMx 外部时钟模式2TIM_ETRConfig 配置TIMx 外部触发TIM_SelectInputTrigger 选择TIMx 输入触发源TIM_PrescalerConfig 设置TIMx 预分频TIM_CounterModeConfig 设置TIMx 计数器模式TIM_ForcedOC1Config 置TIMx 输出1 为活动或者非活动电平TIM_ForcedOC2Config 置TIMx 输出2 为活动或者非活动电平TIM_ForcedOC3Config 置TIMx 输出3 为活动或者非活动电平TIM_ForcedOC4Config 置TIMx 输出4 为活动或者非活动电平TIM_ARRPreloadConfig 使能或者失能TIMx在ARR 上的预装载寄存器TIM_SelectCCDMA 选择TIMx 外设的捕获比较DMA源TIM_OC1PreloadConfig 使能或者失能TIMx在CCR1 上的预装载寄存器TIM_OC2PreloadConfig 使能或者失能TIMx在CCR2 上的预装载寄存器TIM_OC3PreloadConfig 使能或者失能TIMx在CCR3 上的预装载寄存器TIM_OC4PreloadConfig 使能或者失能TIMx在CCR4 上的预装载寄存器TIM_OC1FastConfig 设置TIMx 捕获比较1 快速特征。
STM32如何设置定时器STM32如何设置定时器下面以stm32的TIM2作为实例一步步配置成为定时器:第一种对定时器的基本配置TIM_TimeBaseStructure.TIM_Period = 1000;//设置自动装载寄存器TIM_TimeBaseStructure.TIM_Prescaler = 35999; //分频计数TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择向上计数TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);TIM_Cmd(TIM2, ENABLE); //是能定时器始能定时器的中断:TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);在开启时钟里一定要打开TIM2的时钟,函数表达式如下:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);4:中断向量函数的编写:void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;#ifdef VECT_TAB_RAM //如果程序在ram中调试那么定义中断向量表在Ram 中否则在Flash中NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif/* Enable the TIM2 global Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}5:中断函数的编写:当有TIM2的无论哪个中断触发中断发生那么就会进入这个函数TIM2_IRQHandler(void)所以这个更新事件的中断判断要依靠以下语句:if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)按照以上步骤配置可以顺利进行定时器的基本定时应用第二种方法:/* Enable TIM2 Update interrupt [TIM2溢出中断允许]*/ TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);中断中的设置为:if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)。
STM32定时器定时时间配置总结STM32系列微控制器内置了多个定时器模块,它们可以用于各种定时功能,如延时、周期性触发、脉冲计数等。
在使用STM32定时器之前,我们需要进行定时时间配置,本文将总结一下STM32定时器定时时间配置的相关知识,包括定时器工作模式、定时器时钟源选择、定时器时钟分频、定时器计数器重载值以及定时器中断配置等内容。
首先,我们需要选择定时器的工作模式。
STM32定时器支持多种工作模式,包括基本定时器模式、高级定时器模式、输入捕获模式和输出比较模式等。
基本定时器模式适用于简单的定时和延时操作,输入捕获模式适用于捕获外部事件的时间参数,输出比较模式适用于产生精确的PWM波形。
根据具体的应用需求,选择合适的工作模式。
其次,我们需要选择定时器的时钟源。
STM32定时器的时钟源可以选择内部时钟源(如系统时钟、HCLK等)或外部时钟源(如外部晶体)。
内部时钟源的稳定性较差,适用于简单的定时操作,而外部时钟源的稳定性较好,适用于要求较高的定时操作。
然后,我们需要选择定时器的时钟分频系数。
定时器的时钟分频系数决定了定时器的时钟频率,从而影响了定时器的计数速度。
我们可以通过改变时钟分频系数来调整定时器的计数速度,从而实现不同的定时时间。
时钟分频系数的选择需要考虑定时器的最大计数周期和所需的定时精度。
接着,我们需要配置定时器的计数器重载值。
定时器的计数器从0开始计数,当计数器达到重载值时,定时器将重新开始计数。
通过改变计数器重载值,可以实现不同的定时时间。
计数器重载值的选择需要考虑定时器的时钟频率和所需的定时时间。
最后,我们需要配置定时器的中断。
定时器中断可以在定时器计数达到重载值时触发,用于通知CPU定时器已经计数完成。
在定时器中断中,我们可以执行相应的中断服务程序,比如改变一些IO口的状态,实现定时操作。
通过配置定时器的中断使能和中断优先级,可以实现不同的中断操作。
需要注意的是,不同型号的STM32微控制器的定时器模块可能略有不同,具体的配置方法和寄存器设置也可能不同,请参考相应的数据手册和参考手册进行具体操作。
基于寄存器操作的STM32高级定时器TIM1的四路PWM输出程序讲解STM32高级定时器TIM1具有四个独立的PWM输出通道,可以用来控制四个不同的设备或驱动器。
在本篇文章中,我们将详细讲解如何使用寄存器操作实现TIM1的四路PWM输出。
首先,需要了解几个相关的概念。
STM32的定时器是通过寄存器进行配置和操作的,其中TIM1是高级定时器,具有更高级的功能和更多的寄存器。
PWM(脉冲宽度调制)是一种常见的控制技术,可实现模拟信号的数字化控制,通过调整高电平和低电平的时间比例来控制目标设备或驱动器的动作。
在开始编写程序之前,我们首先需要对TIM1进行初始化和配置。
以下是一个基本的初始化函数示例:```void TIM1_PWM_Init//开启TIM1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//初始化TIM1的配置TIM_TimeBaseInitTypeDef TIM_BaseStruct;TIM_OCInitTypeDef TIM_OCStruct;TIM_BaseStruct.TIM_Prescaler = 0;TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_BaseStruct.TIM_Period = 999; // 设置周期为1000TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_BaseStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM1, &TIM_BaseStruct);//配置输出比较通道TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCStruct.TIM_Pulse = 0; // 设置脉冲宽度,0表示低电平TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC1Init(TIM1, &TIM_OCStruct);TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_OC2Init(TIM1, &TIM_OCStruct);TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_OC3Init(TIM1, &TIM_OCStruct);TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);TIM_OC4Init(TIM1, &TIM_OCStruct);TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);//启动定时器TIM_Cmd(TIM1, ENABLE);```上述代码是一个初始化TIM1的函数示例,其中包含了基本的配置步骤。
STM32Cubemx配置定时器定时1mS 最近才发现原来我把定时器⾥的配置参数代表的意义给搞混了,这⾥记录⼀下,防⽌以后⾃⼰忘记。
以建⽴⼀个定时1mS定时器为例: 1、先打开定时器 2、配置好时钟 3、配置定时器设置 重点来了,以前在这⾥我⼀直以为这⾥配置的就是时间,然后在调频率的时候,⼀直不对劲,知道查阅了硬⽯的资料才发现,这⾥配置的是进⼊定时器中断的频率,然后要定的时间要跟据这个频率来定时的。
由这个图可见,这⾥配置的是定时器产⽣中断的频率,然后再跟据频率与时间的关系推出定时的时间。
所以定时器频率为 f = 72M / Prescaler / Period = 72000 000 / 72 /1000 = 1000Hz; 定时时间T = 1 / f 则: 1s / 1000Hz = 1000 000us / 1000Hz = 1000us =1ms。
这样就可以定时1ms了啦,如果要做PWM频率调频,就直接改 pre 与 per 算出 f 就可以了。
具体公式如下图(上⾯的计算我是为了⽅便理解把公式逆运算了⼀次): 最后使⽤定时器中断跟关闭定时器中断以及回调函数即可, 使⽤中断的时候注意要先开启中断HAL_TIM_Base_Start_IT(&htim1); //使⽤定时器的时候调⽤这个函数启动HAL_TIM_Base_Stop_IT(&htim1); //停⽌定时器的时候调⽤这个函数关闭void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance == TIM1) { //编写回调逻辑,即定时器1定时1MS后的逻辑 }}补充:最后记得⽣成STM32Cubemx⽂件时打开定时器中断,不然进不了回调函数,⼀般的话习惯⽤TIM3做定时器。
如何采用STM32中的控制定时器Tim1实现计数器功能STM32中的高级控制定时器(Tim1)是由一个16位的自动装载计数器组成,它由一个可编程预分频器驱动。
用途在于:测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较,PWM,嵌入死区时间的互补PWM等)。
使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。
具体如下:16位上下,自动装载计数器。
16位可编程预分频器,计数器时钟频率的分频率的分频系数为1-65535之间任意数值,4个独立通道:输入捕获输出比较PWM生成单脉冲模式输出死区时间可编程的互补输出使用外部信号控制定时器和定时器互连的同步电路在指定数目的计数器周期之后更新定时器寄存器刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态如下事件发生时产生中断:更新:计数器向上溢出或者向下溢出,计数器初始化。
触发事件(计数器启动,停止,初始化)输入捕获输出比较刹车信号输入下面介绍一下采用TIm1实现计数器的功能:步骤一:进行定时器时钟启动:void TIm1_on(){钟设置:启动TIM1RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);}步骤二:实现对定时器的配置(对其内部寄存器进行配置初始化)断NVIC设置:允许中断,设置优先级= TIM1_UP_IRQChannel; //更新事件= 0; //抢占优先级0= 1; //响应优先级1= ENABLE; //允许中断NVIC_Init(//写入设置}将这里基本设施都能好了。
我们可以进行中断函数的设置,就是进入中断要干什么。
tim1中断有:TIM1_BRK_IRQHandler(void)//tim1的暂停中断TIM1_CC_IRQHandler(void)//tim1的捕获比较中断TIM1_TRG_COM_IRQHandler(void)//tim1的触发TIM1_UP_IRQHandler(void)//tim1的刷新中断和通讯中断。
STM32 高级定时器-PWM简单使用
2010-04-14 14:49:29| 分类:STM32 | 标签:|举报|字号大中小订阅高级定时器与通用定时器比较类似,下面是一个TIM1 的PWM 程序,TIM1是STM32唯一的高级定时器。
共有4个通道有死区有互补。
先是配置IO脚:
GPIO_InitTypeDef GPIO_InitStructure;
/* PA8设置为功能脚(PWM) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*PB13 设置为PWM的反极性输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*开时钟PWM的与GPIO的*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/*配置TIM1*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
void Tim1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_DeInit(TIM1); //重设为缺省值
/*TIM1时钟配置*/
TIM_TimeBaseStructure.TIM_Prescaler = 4000; //预分频(时钟分频)72M/4000=18K
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_Period = 144; //装载值18k/144=125hz 就是说向上加的144便满了 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置了时钟分割不懂得不管 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //周期计数器值不懂得不管
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); //初始化TIMx的时间基数单位
/* Channel 1 Configuration in PWM mode 通道一的PWM */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效PA8 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //反向通道也有效 PB13
TIM_OCInitStructure.TIM_Pulse = 40; //占空时间144 中有40的时间为高,互补的输出正好相反 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //互补端的极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //空闲状态下的非工作状态不管 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //先不管
TIM_OC1Init(TIM1,&TIM_OCInitStructure); //数初始化外设TIMx通道1这里2.0库为
TIM_OCInit
/* TIM1 counter enable开定时器*/
TIM_Cmd(TIM1,ENABLE);
/* TIM1 Main Output Enable 使能TIM1外设的主输出*/
TIM_CtrlPWMOutputs(TIM1,ENABLE);
}
//设置捕获寄存器1
void SetT1Pwm1(u16 pulse)
{
TIM1->CCR1=pulse;
}
/*操作寄存器改变占空时间*/
/***************************************************************************************************************
**
TIM1的定时器通道时间1到4 分别为PB8 PA9 PA10 PA11 而互补输出分别为PB13 PB14
PB15
中止PB12 。
如果输出与互补输出极性相同的话就刚好输出高互补低至于PWM模式1 与模式2的区别
在下图:
这个是模式1的了绿为输出黄为互补
*************************************************************************************************
上图是模式2的情况正好和模式1的反过来了144中有40 为高互补的有40为低。
*************************************************************************************************/
//在MAIN 中加点键盘扫描啥的用来改变占空比
/************************************************************
**实验名称:PWM
**功能:是PA8产生PWM输出,PA8为驱动LED1和马达的IO, 通过UP DOWN键,可以改变占空比,从而让ED1和小马达的产生变化
**注意事项:LED是低有效,马达则是高有效,所以LED全灭的时候马达转速达到最高.
**作者:电子白菜
*************************************************************/
#include"STM32Lib\\stm32f10x.h"
#include"hal.h"
extern void SetT1Pwm1(u16 pulse);
int main(void)
{
u16 pulse=40;
ChipHalInit(); //片内硬件初始化
ChipOutHalInit(); //片外硬件初始化
for(;;)
{
if(GET_UP())
{
while(GET_UP());
if(pulse<=144)
{
pulse+=5;
SetT1Pwm1(pulse);
}
}
if(GET_DOWN())
{
while(GET_DOWN());
if(pulse>30)
{
pulse-=5;
SetT1Pwm1(pulse);
}
}
}
}
/***************************************************************************************/
再来两张最小系统板子
/***************************************************************************************/
你也只需一块这样板子再来一点时间与干劲这个历程一样跑的起来。