day36:Tim基本定时器(通用定时器和高级定时器也可以借鉴)
基本定时器有:Tim6和Tim7,通用定时器有:Tim2-5,高级定时器有:Tim1和Tim8,他们的功能也不同。


======================================
工程结构:

bsp_led.h
#ifndef __BSP_LED_H__
#define __BSP_LED_H__
#include "stm32f10x.h"
#define GPIO_CLK_D4 RCC_APB2Periph_GPIOC // 时钟
#define GPIO_PORT_D4 GPIOC // C端口
#define GPIO_PIN_D4 GPIO_Pin_2 // PC2引脚
#define digitalTOGGLE(p,i) {p->ODR ^= i;}
#define D4_TOGGLE digitalTOGGLE(GPIO_PORT_D4, GPIO_PIN_D4)
/*配置GPIO*/
void LED_GPIO_Config(void);
#endif /*__BSP_LED_H__*/
bsp_led.c
#include "./led/bsp_led.h"
/*LED引脚初始化*/
void LED_GPIO_Config(void)
{
/*外设结构体*/
GPIO_InitTypeDef GPIO_InitStruct_D4;
/*第一步:打开外设的时钟,看stm32f10x_rcc.c这个文件的RCC_APB2PeriphClockCmd函数介绍*/
RCC_APB2PeriphClockCmd(GPIO_CLK_D4, ENABLE);
/*第二步:配置外设的初始化结构体*/
GPIO_InitStruct_D4.GPIO_Pin = GPIO_PIN_D4; // PC2的那盏LED灯(D4)的引脚
GPIO_InitStruct_D4.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStruct_D4.GPIO_Speed = GPIO_Speed_10MHz; // 引脚速率
/*第三步:调用外设初始化函数,把配置好的结构体成员写到寄存器里面*/
GPIO_Init(GPIO_PORT_D4, &GPIO_InitStruct_D4);
}
bsp_basetime.h
#ifndef __BSP_BASETIME_H_ #define __BSP_BASETIME_H_ #include "stm32f10x.h" /********************基本定时器TIM参数定义************/ #define BASIC_TIM TIM6 // Tim6定时器 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd // Tim6定时器时钟【APB1总线上】 #define BASIC_TIM_CLK RCC_APB1Periph_TIM6 // Tim6本身的时钟 #define BASIC_TIM_Period 1000-1 // 一轮计数到999 #define BASIC_TIM_Prescaler 71 // 时钟预分频数 #define BASIC_TIM_IRQ TIM6_IRQn // Tim6作为中断源 #define BASIC_TIM_IRQHandler TIM6_IRQHandler // Tim6的中断函数 /**************************函数声明********************************/ void BASIC_TIM_Init(void); #endif /*__BSP_BASETIME_H_*/
bsp_basetime.c
#include "./basetime/bsp_basetime.h"
// 中断优先级配置
static void BASIC_TIM_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;
// 设置主优先级为 0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// 设置抢占优先级为3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// 初始化
NVIC_Init(&NVIC_InitStructure);
}
/*
* 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
* 另外三个成员是通用定时器和高级定时器才有.
*-----------------------------------------------------------------------------
*typedef struct
*{
* TIM_Prescaler 都有
* TIM_CounterMode TIMx,x[6,7]没有,其他都有
* TIM_Period 都有
* TIM_ClockDivision TIMx,x[6,7]没有,其他都有
* TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有
*}TIM_TimeBaseInitTypeDef;
*-----------------------------------------------------------------------------
*/
static void BASIC_TIM_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 开启定时器时钟,即内部时钟CK_INT=72M
BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);
// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period; // 计算:1ms
// 时钟预分频数为
TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;
// 时钟分频因子 ,基本定时器没有,不用管
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,基本定时器没有,不用管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);
// 清除计数器中断标志位
TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);
// 开启计数器中断
TIM_ITConfig(BASIC_TIM, TIM_IT_Update, ENABLE);
// 使能计数器
TIM_Cmd(BASIC_TIM, ENABLE);
}
void BASIC_TIM_Init(void)
{
// 中断优先级配置
BASIC_TIM_NVIC_Config();
// 定时器配置
BASIC_TIM_Mode_Config();
}
main.c
#include "stm32f10x.h"
#include "./led/bsp_led.h"
#include "./basetime/bsp_basetime.h"
volatile uint32_t time = 0; // ms计时变量
int main(void)
{
// LED引脚初始化
LED_GPIO_Config();
// 定时器初始化
BASIC_TIM_Init();
// 判断time的时间,切换LED灯的状态
while(1)
{
// 500ms LED灯闪烁一次
if(time >= 500)
{
// 让time复位,重新下一轮周期的计时
time = 0;
// 改变LED灯的状态
D4_TOGGLE;
}
}
}
实验现象:LED灯每隔500ms闪烁一次
=========================== 换成其他的定时器,只需修改bsp_basetime.h文件
换成Tim7:
#ifndef __BSP_BASETIME_H_ #define __BSP_BASETIME_H_ #include "stm32f10x.h" /********************基本定时器TIM参数定义************/ #define BASIC_TIM TIM7 // Tim7定时器 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd // Tim7定时器时钟【APB1总线上】 #define BASIC_TIM_CLK RCC_APB1Periph_TIM7 // Tim7本身的时钟 #define BASIC_TIM_Period 1000-1 // 一轮计数到999 #define BASIC_TIM_Prescaler 71 // 时钟预分频数 #define BASIC_TIM_IRQ TIM7_IRQn // Tim7作为中断源 #define BASIC_TIM_IRQHandler TIM7_IRQHandler // Tim7的中断函数 /**************************函数声明********************************/ void BASIC_TIM_Init(void); #endif /*__BSP_BASETIME_H_*/
换成通用定时器(Tim2-Tim5),比如换成Tim2:
#ifndef __BSP_BASETIME_H_ #define __BSP_BASETIME_H_ #include "stm32f10x.h" /********************基本定时器TIM参数定义************/ #define BASIC_TIM TIM2 // Tim2定时器 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd // Tim2定时器时钟【APB1总线上】 #define BASIC_TIM_CLK RCC_APB1Periph_TIM2 // Tim2本身的时钟 #define BASIC_TIM_Period 1000-1 // 一轮计数到999 #define BASIC_TIM_Prescaler 71 // 时钟预分频数 #define BASIC_TIM_IRQ TIM2_IRQn // Tim2作为中断源 #define BASIC_TIM_IRQHandler TIM2_IRQHandler // Tim2的中断函数 /**************************函数声明********************************/ void BASIC_TIM_Init(void); #endif /*__BSP_BASETIME_H_*/
换成高级定时器(Tim1和Tim8),比如换成Tim1:
#ifndef __BSP_BASETIME_H_ #define __BSP_BASETIME_H_ #include "stm32f10x.h" /********************基本定时器TIM参数定义************/ #define BASIC_TIM TIM1 // Tim1定时器 #define BASIC_TIM_APBxClock_FUN RCC_APB2PeriphClockCmd // Tim1定时器时钟【APB2总线上】 #define BASIC_TIM_CLK RCC_APB2Periph_TIM1 // Tim1本身的时钟 #define BASIC_TIM_Period 1000-1 // 一轮计数到999 #define BASIC_TIM_Prescaler 71 // 时钟预分频数 #define BASIC_TIM_IRQ TIM1_UP_IRQn // Tim1作为中断源 #define BASIC_TIM_IRQHandler TIM1_UP_IRQHandler // Tim1的中断函数 /**************************函数声明********************************/ void BASIC_TIM_Init(void); #endif /*__BSP_BASETIME_H_*/
以上换成其他的定时,LED灯也是每隔500ms闪烁一次。程序可移植性非常强。

浙公网安备 33010602011771号