stm32f107定时器3使用时钟源使用外部时钟源模式2进行定时

终于成功的使用了外部时钟源来作为定时器3的时钟源了,其实操作过程并不难,但是因为自己没有经验,所以走了很多弯路,在这里写这篇博客除了为了给自己记录之外,也希望对大家有帮助。

首先简单介绍一下其功能,我们都知道,stm32中的通用定时器的计数时钟有三种,内部时钟(CK_INT)、外部时钟源(包括外部时钟模式1:外部输入脚(TIx)外部时钟模式2:外部触发输入(ETR) 两种模式)、内部触发输入(ITRx) 这三种,其中内部时钟(CK_INT)是大家都比较常用的,也是在应用中比较多的,我们现在主要来讲一下外部时钟源的模式2外部时钟模式2:外部触发输入(ETR)

关于这部分的内容在《stm32中文参考手册》中的264页有详细的配置介绍,我这里把其配置步骤粘贴出来:

例如,要配置在ETR下每2个上升沿计数一次的向上计数器,使用下列步骤:
1. 本例中不需要滤波器,置TIMx_SMCR寄存器中的ETF[3:0]=0000
2.
设置预分频器,置TIMx_SMCR寄存器中的ETPS[1:0]=01
3.
设置在ETR的上升沿检测,置TIMx_SMCR寄存器中的ETP=0
4.
开启外部时钟模式2,置TIMx_SMCR寄存器中的ECE=1
5.
启动计数器,置TIMx_CR1寄存器中的CEN=1

好了,以上就是操作步骤,但是我们在进行编程的时候考虑的因素要多一些。

1、配置TIM3_ETR引脚为输入引脚PD2(包括使能GPIOD的时钟、配置为GPIO_Mode_IN_FLOATING输入模式),硬件上需要将脉冲连接到该引脚(这是前提),我这里是使用6.78MHz的晶振;

2、配置定时器3:包括使能定时器3对应的时钟引脚,配置定时器3的周期、预分频...参数;

3、因为我们使用了定时器3中断,所以需要给定时器设置优先级,在timerx_nvic_init()中的关于TIM3部分操作;

4、以上都是常用的定时器配置,现在来到了我们的重点了,就是要对上述中我粘贴出来的内容进行配置:首先我们要配置SMCR中的ETF、ETPSETPECE进行配置,非常庆幸的是库函数已经将这几个配置都封装好在TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted,0x00);    中了,我们只需要调用它并填入参数便可;

5、执行完了以上步骤之后,还未行,我们还需要操作triggle中断,因为我们还使用了定时器的update中断TIM_ITConfig(TIM3, TIM_IT_Trigger, ENABLE);,因此我们也需要使能该中断TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

6、接下来,设置定时器3的计数器为0TIM_SetCounter( TIM3, 0);并使能定时器3  TIM_Cmd(TIM3, ENABLE);

7、以上配置就完成了,同时我们需要在定时器3中断函数中进行对TIM_IT_Update进行操作,(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET),然后在其中清除该标志并执行我们需要的操作就可以了,比如说可以让LED灯亮灭等等。

8、以上就是定时器3如何使用外部时钟模式2:外部触发输入(ETR)并开启一个TIM_IT_Update中断进行的简单操作。


我将以上操作的实现的源码会上传在我的资料中,可是我是在公司写的,公司的文件都有加密,我还是把相关的操作都张贴在下方吧,由于篇幅限制的原因,一些其他的外设相关操作我就不贴出来了,比如LED操作或者是串口操作。

第一部分:直接对寄存器操作的,这个我是在网上找的资料,已经忘记链接了,谢谢那位大哥。

#include "stm32f10x.h"
#include "gpio.h"
#include "delay.h"
#include "usart.h"
//#include "systick.h"
#include "timer.h"


int timercount = 0;


void NVIC_CON(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure); 
}


//?????3 ??????? ???
//arr:????????
void TIM3_Int_Init(u16 arr)
{
	//enable port D clock.
	RCC->APB2ENR|=1<<5;
	//set PD.2 as input.
	GPIOD->CRL &= 0xfffff0ff;
	GPIOD->CRL |= 0x00000400;
	//enable TIM3 clock.
	RCC->APB1ENR |= 1<<1;//??TIM3??

	TIM3->ARR=arr;   //??????????
	TIM3->PSC=0;        //???

	//SMCR->ETF = 0000, no triggerl filter.
	TIM3->SMCR &= ~(0xf<<8);
	//SMCR->ETPS = 00, off prescaler.
	TIM3->SMCR &= ~(3<<12);
	//SMCR->ETP = 1, TIM_ExtTRGPolarity_Inverted
	TIM3->SMCR |= 1<<15;	
	//SMCR->ECE external clock enabel.
	TIM3->SMCR |= 1<<14;
	
	//DIER->UID update interrupt enabel.
	TIM3->DIER |= 1<<0;
	//triggle intterupt enabel.
	TIM3->DIER |= 1<<6;

	NVIC_CON();
	//clean counter.
	TIM3->CNT = 0x0;
	//counter enabel.
	TIM3->CR1 |= 1<<0;
}


void TIM3_IRQHandler(void)
{    
	//check if is TIM_IT_Update interrupt. 
	if(TIM3->SR&0X0001)
	{
	
		timercount++;
		if(timercount %2 == 0)
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_9);
		}
		else
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_9);
		}
	} 
	//clear interrupt flag.
	TIM3->SR&=~(1<<0);  
}


int main(void)
{   
	gpio_init();
	usartx_init(TS_UART4, TS_BAUDRATE_19200);	
	TIM3_Int_Init(20); 
    while(1);
}

第二部分的内容就主要是调用库函数实现的,其实操作过程和操作寄存器的一样:

void timerx_rcc_init(uint8_t timerx)
{
	switch(timerx)
	{
		case TS_TIMER2:			
			RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 
			break;
		
		case TS_TIMER3:
			RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 
			break;
		
		default:
			break;
	}
}


void timerx_gpio_init(uint8_t timerx)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	switch(timerx)
	{
		
		case TS_TIMER3://PD2 init. PD2 is the pulse input of timer3.
				//enabel GPIOD's clock.
				RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
		
				GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
				GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2;
				GPIO_Init(GPIOD, &GPIO_InitStructure);
			
			break;
		
		default:
			break;
	}
}


void timerx_nvic_init(uint8_t timerx)
{	
	NVIC_InitTypeDef NVIC_InitStructure;
	
	switch(timerx)
	{
		
		case TS_TIMER3:
				NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
				NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
				NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
				NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
				NVIC_Init(&NVIC_InitStructure);   
				break;		
		default:
			break;
	}
}

void timerx_param_init(uint8_t timerx, uint16_t peri, uint16_t pres)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	
	uint16_t tmpccmrx = 0;
	
	switch(timerx)
	{
		
		case TS_TIMER3:
				TIM_DeInit(TIM3);
				TIM_TimeBaseStructure.TIM_Period = peri;    	    //peri
				TIM_TimeBaseStructure.TIM_Prescaler =pres; 		//pres
				TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
				TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
				TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

				//including set SMCR_ECE bit.
				TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted,0x00);	
				
				TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
				TIM_ITConfig(TIM3, TIM_IT_Trigger, ENABLE);
			
				TIM_SetCounter( TIM3, 0);
				
				TIM_Cmd(TIM3, ENABLE);
			break;
		
		default:
			break;
	}
}

void timerx_octoggle(uint8_t timerx)
{
	TIM_OCInitTypeDef TIM_OCInitStructure;

	switch(timerx)
	{		
		case TS_TIMER3:
				TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
				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);
				TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
			
				TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
				
				TIM_Cmd(TIM3, ENABLE);
				
			break;
		
		default:
			break;
	}
}

void timerx_init(uint8_t timerx, uint16_t peri, uint16_t pres)
{
	timerx_rcc_init(timerx);
	timerx_gpio_init(timerx);
	timerx_nvic_init(timerx);
	timerx_param_init(timerx, peri, pres);
}


void TIM3_IRQHandler(void)   
{
	static u16 capturetimer3 = 0;
	
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
    {
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  
		//capturetimer3 = TIM_GetCapture1(TIM3);
		//TIM_SetCompare1(TIM3, capturetimer3 + CCR1_Val);
		
		//timercount = 1;	
		timercount++;
		if(timercount %2 == 0)
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_9);
		}
		else
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_9);
		}			
    }
}
 
int main()
{   
    gpio_init();
    usartx_init(TS_UART4, TS_BAUDRATE_19200);    
    timerx_init(TS_TIMER3, 20, 0);
    while(1)
    {
        usartx_send_byte(TS_UART4, 0x88);
    }
}
主要操作就是这些。




                
             



  • 8
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值