STM32F103 TIM学习笔记

看官方的参考手册,边看边调,做些记录,也供有需要的人参考。

时钟源的选择可以参考这篇文章,写的很清晰

STM定时器时钟源选择函数_stm32 定时器选择时钟源-CSDN博客

1、内部时钟源(CK_INT):时基配置、PWM输出、更新中断

复位后默认是内部时钟源

复制代码
void GPIOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	/* GPIOA Configuration: Channel 1, 2 and 3 as alternate function push-pull */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 ;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);



	/* GPIOB Configuration: Channel 1N, 2N and 3N as alternate function push-pull */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_Init(GPIOB, &GPIO_InitStruct);


	//输出GPIO方便观察波形
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

	GPIO_Init(GPIOC, &GPIO_InitStruct);

}

void TIM1_Init(void)//1毫秒定时
{

	//时基设置
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); 
    /* Time Base configuration */
    TIM_TimeBaseStructure.TIM_Prescaler = 71;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period =999;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);


	//输出设置
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	/* Channel 1, 2,3 and 4 Configuration in PWM mode */
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 200;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);

	

	//中断设置
	NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;   
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure); 

	//使能更新中断
    TIM_ClearFlag(TIM1,TIM_FLAG_Update);
    TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);

	//使能定时器
    TIM_Cmd(TIM1, ENABLE);
	
	//PWM输出
	TIM_CtrlPWMOutputs(TIM1, ENABLE);

  
}

void TIM1_UP_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET)
    {  
        TIM_ClearFlag(TIM1,TIM_FLAG_Update);
			
		GPIOC->ODR^=GPIO_Pin_13;
    }
}
int main (void)
{
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	RCC_ClocksTypeDef RCC_Clocks;
	RCC_GetClocksFreq(&RCC_Clocks); //查看RCC时钟配置结果

	GPIOInit();
	TIM1_Init();

	
//	TIM_ETR_Init();


	
	while(1)
	{
		
	}
}

2、外部时钟模式1:外部输入引脚

复制代码
void TIM_TIxExternalClock_Init(void)
{

	//第一步:开启外部时钟和外设时钟(注意使用APB1的开启时钟函数,因为TIM2是APB1总线的外设
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
		

		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		
		GPIO_InitTypeDef GPIO_InitStructure;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA,&GPIO_InitStructure);
	
		TIM_TIxExternalClockConfig(TIM1,TIM_TIxExternalCLK1Source_TI1,TIM_ICPolarity_Rising,0);
	

		
	//第三步:配置时基单元(在stm32f10x_tim.h文件中查找函数)
		TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
		TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频
		TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//指定计数器模式(此处选择向上计数)
		TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//指定要在下一次更新事件时加载到ARR自动重新加载寄存器中的周期值	ARR取值[0,65535]
		TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//指定用于划分TIM时钟的预分频器值    PSC取值[0,65535]
		TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//指定重复计数器的值(高级定时器才用得上,本项目给0)
		TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);//初始化时基单元
		
		TIM_ClearFlag(TIM1,TIM_FLAG_Update);
		
	//第四步:使能更新中断(在stm32f10x_tim.h文件中查找函数)
		TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
	//开启了更新中断到NVIC的通路
	//第五步:配置NVIC
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
		NVIC_InitTypeDef NVIC_InitStructure;
		NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;//指定中断通道
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//指定IRQ通道的抢占优先级
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//指定IRQ通道的响应优先级
		NVIC_Init(&NVIC_InitStructure);
	//第六步:启动定时器(在stm32f10x_tim.h文件中查找函数)
		TIM_Cmd(TIM1,ENABLE);
		
	//至此定时器就可以开始工作了,当产生更新时,就会触发中断

	 

}

3、外部时钟模式2:外部触发输入ETR

复制代码
void TIM_ETR_Init(void)
{
//第一步:开启外部时钟和外设时钟(注意使用APB1的开启时钟函数,因为TIM2是APB1总线的外设
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
    
//需要额外配置GPIO来驱动对射式红外传感器
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
//第二步:选择时基单元的时钟(在stm32f10x_tim.h文件中查找函数)
    TIM_ETRClockMode2Config(TIM1,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_Inverted,0x00);
//通过ETR引脚的外部时钟模式2配置
//时基单元就由外部时钟ETR(查表可知引脚PA0)驱动了
    
//第三步:配置时基单元(在stm32f10x_tim.h文件中查找函数)
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//指定计数器模式(此处选择向上计数)
    TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//指定要在下一次更新事件时加载到ARR自动重新加载寄存器中的周期值  ARR取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//指定用于划分TIM时钟的预分频器值    PSC取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//指定重复计数器的值(高级定时器才用得上,本项目给0)
    TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStructure);//初始化时基单元
    
    TIM_ClearFlag(TIM1,TIM_FLAG_Update);
    
//第四步:使能更新中断(在stm32f10x_tim.h文件中查找函数)
    TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
//开启了更新中断到NVIC的通路
//第五步:配置NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;//指定中断通道
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//指定IRQ通道的抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//指定IRQ通道的响应优先级
    NVIC_Init(&NVIC_InitStructure);
//第六步:启动定时器(在stm32f10x_tim.h文件中查找函数)
    TIM_Cmd(TIM1,ENABLE);
    
//至此定时器就可以开始工作了,当产生更新时,就会触发中断
}  
相关推荐
撩得Android一次心动19 分钟前
Linux编程笔记3【个人用】
linux·笔记
憧憬成为java架构高手的小白21 分钟前
黑马八股--中间件学习之MQ(RabbitMQ)
学习·中间件
撩得Android一次心动2 小时前
Linux编程笔记4【个人用】
linux·笔记·学习
放学校门口见2 小时前
vscode部署stm32开发调试环境
ide·vscode·stm32
user-猴子2 小时前
让网页“活”过来 —— 用AI打造会自主学习的动态知识图谱
人工智能·学习·知识图谱
网络工程小王3 小时前
【HCIE-AI】10.pytorch模型迁移分析
人工智能·学习·华为·llama
xqqxqxxq4 小时前
技术笔记:上下文工程(Context Engineering)心得总结(李博杰《深入理解 AI Agent》2.1,2.2观后总结)
人工智能·笔记
魔城烟雨4 小时前
从零开始学习betaflight《3-硬件接口设计规范标准》
学习·设计规范
z20348315205 小时前
CLion开发STM32——文件管理
stm32·单片机·嵌入式硬件·clion
weixin_452077646 小时前
STM32 烧录程序后上电不工作问题集合
stm32·单片机·嵌入式硬件