stm32之定时器
1.定时器主要由时钟源、分频器、计时器、重装载值寄存器组成。
2、通用定时器:基本定时器+PWM+输入捕获
3、高级定时器:通用定时器+死区+刹车等。
4、基本定时器:
特性:1.16位自动重装载累加计数器、16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1~65536的任意数值分频
触发DAC的同步电路、在更新事件(计数器溢出)时产生中断/DMA请求
2.计数器时钟由内部时钟(CK_INT)源提供、定时器的频率有硬件自动设置:1.如果APB预分频为1,定时器时钟频率等于APB域的频率
TIMx_CR1寄存器的CEN位, 一旦置CEN位为’1’,内部时钟即向预分频器提供时钟。
2.否则,等于二倍
5、计数器从0累加计数到自动重装载数值(TIMx_ARR寄存器), 然后重新从0开始计数并产生一个计数器溢出事件。每次计数器溢出时可以产生更新事件; (通过软件或使用从模式控制器)设置TIMx_EGR寄存器的UG位也可以产生更新事件。设置TIMx_CR1中的UDIS位可以禁止产生UEV事件, 这可以避免在写入预加载寄存器时更改影子寄存器。 在清除UDIS位为’ 0’ 之前, 将不再产生更新事件, 但计数器和预分频器依然会在应产生更新事件时重新从0开始计数(但预分频系数不变)
6、如果设置了TIMx_CR1寄存器中的URS(选择更新请求), 设置UG位可以产生一次更新事件UEV, 但不设置UIF标志(即没有中断或DMA请求)。当发生一次更新事件时, 所有寄存器会被更新并(根据URS位)设置更新标志(TIMx_SR寄存器的UIF位):
● 传送预装载值(TIMx_PSC寄存器的内容)至预分频器的缓冲区。
● 自动重装载影子寄存器被更新为预装载值(TIMx_ARR)
7、定时器的时钟源:
● 内部时钟 (CK_INT)
● 外部时钟模式 1: 外部输入引脚 (TIx)
● 外部时钟模式 2: 外部触发输入 (ETR)
● 内部触发输入 (ITRx): 使用一个定时器作为另一个定时器的预分频器。
我们一般选用内部时钟作为定时器的时钟源,即RCC的TIMxCLK
8、仅仅作为定时-延时使用时,可选择通用寄存器
1 //psc -- 分频值 arr -- 重装载值 2 //36 2 3 void TIM4_Init(uint16_t psc,uint16_t arr) 4 { 5 RCC->APB1ENR |=(1<<2); 6 TIM4->CNT = 0;//计数器清零 7 TIM4->PSC = psc-1; //分频值 -1的原因是因为传递的是2分频,但是再进行计算时会自动加1,所以要在这-1 8 TIM4->ARR = arr-1; //重装载值 9 //CR1 预装载 、向上计数 、更新请求源、允许更新 10 TIM4->CR1 = 0; 11 TIM4->DIER |=(1<<0);//使能更新中断 12 //设置优先级 11 11 13 NVIC_SetPriority(TIM4_IRQn,0xf); 14 //中断管理使能 15 NVIC_EnableIRQ(TIM4_IRQn); 16 TIM4->CR1 &=~(1<<0);//关闭计数器 17 } 18 19 uint32_t ustime =0; 20 void TIM4_IRQHandler(void) 21 { 22 TIM4->SR &=~(1<<0); 23 if(ustime>0)ustime--; 24 } 25 26 void Delay_us(uint32_t time) 27 { 28 ustime = time; 29 TIM4->CNT =0; 30 TIM4->CR1 |=(1<<0);//打开计数器 31 while(ustime); 32 TIM4->CR1 &=~(1<<0); 33 }
9、不同GPIO口连接不同硬件,在使用到TIM时的配置
1 函数参数:PSC--分频 2 arr--重装载 3 备注:PB3--JTDO 4 --需要重新映射 5 ---复用做普通IO口 6 ---TIM2_CH2 7 需将CH2映射到PB2上 8 ****************************/ 9 void TIM2_Config(u16 psc,u16 arr) 10 { 11 /****底层***********/ 12 GPIO_InitTypeDef GPIO_InitStruct; 13 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; 14 TIM_ICInitTypeDef TIM_ICInitStruct; 15 NVIC_InitTypeDef NVIC_InitStruct; 16 17 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE); 18 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); 19 //关闭JTAG 20 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); 21 //TIM2_CH2重映射到PB3 22 GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2 ,ENABLE); 23 24 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3; 25 GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING ; 26 GPIO_Init(GPIOB,&GPIO_InitStruct); 27 28 /********定时器初始化***********/ 29 TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV2;//2倍频 30 TIM_TimeBaseInitStruct.TIM_Period=arr-1;//重装载值 31 TIM_TimeBaseInitStruct.TIM_Prescaler=psc-1;//分频 32 TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上计数 33 //TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数,使用在高级定时器 34 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct); 35 36 /********初始化输入捕获***********/ 37 38 TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;//通道2 39 TIM_ICInitStruct.TIM_ICFilter=0x0;//不使用滤波器 40 TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Falling;//下降沿 41 TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;//不分频 42 TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;//IC2 43 TIM_ICInit(TIM2,&TIM_ICInitStruct); 44 45 /*************中断***************/ 46 //使能捕获中断和更新中断 47 TIM_ITConfig(TIM2, TIM_IT_Update|TIM_IT_CC2,ENABLE); 48 49 NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn; 50 NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; 51 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; 52 NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; 53 NVIC_Init(& NVIC_InitStruct); 54 55 TIM_Cmd(TIM2,ENABLE);