目录
时钟选择
计数器时钟可以由下列时钟提供:
1.内部时钟(CK_INT)
2.外部时钟模式1:外部输入脚(TIx)
3.外部时钟模式2:外部触发输入(ETR)外部输入捕获
4.内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer而作为另一个定时器Timer2的预分频器。
默认使用的是内时钟
内部时钟选择
时钟计算方法:
默认调用SystemInit函数情况下:
SYSCLK=72M
AHB时钟=72M
APB1时钟=36M
所以APB1的分频系数=AHB/APB1=2,所以,通用定时器时钟CK_INT=2*36M=72M。
以向上计数来讲解
首先CNT_EN定时器使能,计数器寄存器从0开始向上计数,计数到36计数器会溢出,然后会有一个更新事件,会更新中断标志,如果使能了中断会产生中断,进入中断服务函数。
定时器中断实验相关寄存器
计数器当前值寄存器CNT
预分频寄存器TIMx_PSC
自动重装载寄存器TIMx_ARR
控制寄存器1(TIMx_CR1)
中断使能寄存器(TIMx_DIER)
常用库函数
定时器结构体讲解
typedef struct
{
uint16_t TIM_Prescaler; //预分频系数
uint16_t TIM_CounterMode; //计数模式向上/向下/中心对齐
uint16_t TIM_Period; //自动装载值(定时周期)
uint16_t TIM_ClockDivision; //时钟分频
uint8_t TIM_RepetitionCounter; // 重复计数
} TIM_TimeBaseInitTypeDef;
//定时器参数初始化
void TIM_TimeBaseInit(TIM_TypeDef* TIMx,
TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//定时器使能函数
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
//定时器中断使能函数
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
//状态标志位获取和清除
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
定时器中断实现步骤
1使能定时器时钟
RCC_APB1PeriphClockCmd()
2初始化定时器,配置ARR,PSC
TIM_TimeBaseInit
3开启定时器中断,配置NVIC
Void TIM_ITConfig();
NVIC_Init();
4使能定时器
TIM_Cmd();
5编写中断服务函数
TIMx_IRQHandler()
实验源码:
实验介绍:定时器500ms时间到打印提示语句
/**
******************************************************************************
* @file : user_rcc_config.c
* @brief : V1.00
******************************************************************************
* @attention
*
******************************************************************************
*/
/* Include 包含---------------------------------------------------------------*/
#include "user_rcc_config.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define 定义----------------------------------------------------------------*/
/* Macro 宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function 函数--------------------------------------------------------------*/
/*!
\brief 定时器初始化
\param[in] none
\param[in] none
\retval none
*/
void Rcc_config(void)
{
/*使能GPIOA时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*使能UART1时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
/*使能定时器3时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
}
/************************************************************** END OF FILE ****/
/**
******************************************************************************
* @file : user_gpio.c
* @brief : V1.00
******************************************************************************
* @attention
*
******************************************************************************
*/
/* Include 包含---------------------------------------------------------------*/
#include "user_gpio.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define 定义----------------------------------------------------------------*/
/* Macro 宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function 函数--------------------------------------------------------------*/
/*!
\brief GPIO初始化函数
\param[in] none
\param[in] none
\retval none
*/
void Gpio_Init(void)
{
/*GPIO结构体*/
GPIO_InitTypeDef GPIO_InitTypeDefstruct;
/*UART1发送引脚配置*/
GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_AF_PP;//推挽复用输出
GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_10MHz;
/*写入结构体到GPIOA*/
GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
/*UART1接收引脚配置*/
GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_10MHz;
/*写入结构体到GPIOA*/
GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
}
/************************************************************** END OF FILE ****/
/**
******************************************************************************
* @file : user_uart.c
* @brief : V1.00
******************************************************************************
* @attention
*
******************************************************************************
*/
/* Include 包含---------------------------------------------------------------*/
#include "user_uart.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define 定义----------------------------------------------------------------*/
/* Macro 宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
extern uint16_t USART_RX_STA;
extern uint8_t USART_RX_BUF[200];
/* Constants 常量--------------------------------------------------------------*/
/* Function 函数--------------------------------------------------------------*/
#if 1
#pragma import(__use_no_semihosting)
/*实现Printf代码*/
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}
#endif
/*!
\brief UART1初始化
\param[in] none
\param[out] none
\retval none
*/
void Uart1_Init(u32 bound)
{
/*UART结构体*/
USART_InitTypeDef USART_InitTypeDefstruct;
/*UART结构体配置*/
USART_InitTypeDefstruct.USART_BaudRate = bound; //波特率
USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流
USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能
USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验
USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位
USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位
/*写入USART1*/
USART_Init(USART1,&USART_InitTypeDefstruct);
/*使能串口1*/
USART_Cmd(USART1,ENABLE);
}
/*!
\brief UART1中断服务函数
\param[in] none
\param[out] none
\retval none
*/
void USART1_IRQHandler(void)
{
}
/************************************************************** END OF FILE ****/
/**
******************************************************************************
* @file : user_timer.c
* @brief : V1.00
******************************************************************************
* @attention
*
******************************************************************************
*/
/* Include 包含---------------------------------------------------------------*/
#include "user_timer.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define 定义----------------------------------------------------------------*/
/* Macro 宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function 函数--------------------------------------------------------------*/
/*!
\brief 定时器初始化
\param[in] 装载值
\param[in] 分频系数
\retval none
*/
void Tim3_Init(uint16_t arr, uint16_t psc)
{
/*定时器结构体*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeDefstruct;
/*NVIC结构体*/
NVIC_InitTypeDef NVIC_InitTypeDefstruct;
TIM_TimeBaseInitTypeDefstruct.TIM_Period = arr; //自动装载值
TIM_TimeBaseInitTypeDefstruct.TIM_Prescaler = psc; //分频系数
TIM_TimeBaseInitTypeDefstruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInitTypeDefstruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
/*写入定时器3*/
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeDefstruct);
/*使能定时器更新中断配置*/
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
/*定时器中断优先级配置*/
NVIC_InitTypeDefstruct.NVIC_IRQChannel= TIM3_IRQn; //USART1中断通道
NVIC_InitTypeDefstruct.NVIC_IRQChannelCmd = ENABLE; //使能USART1中断
NVIC_InitTypeDefstruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitTypeDefstruct.NVIC_IRQChannelSubPriority = 1;//子优先级
/*写入NVIC中*/
NVIC_Init(&NVIC_InitTypeDefstruct);
/*使能定时器*/
TIM_Cmd(TIM3,ENABLE);
}
/*!
\brief TIM3_IRQHandler
\param[in] none
\param[in] none
\retval none
*/
void TIM3_IRQHandler(void)
{
/*判断是不是更新中断*/
if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
{
printf("定时器时间到\r\n");
}
/*清除更新中断*/
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
/************************************************************** END OF FILE ****/
/**
******************************************************************************
* @file : user_mian.h
* @brief : V1.00
******************************************************************************
* @attention
*
******************************************************************************
*/
/* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "user_timer.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define 定义----------------------------------------------------------------*/
/* Macro 宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
//最多一次接收200个字节
uint8_t USART_RX_BUF[200];
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
uint16_t USART_RX_STA=0; //接收状态标记
/* Constants 常量--------------------------------------------------------------*/
/* Function 函数--------------------------------------------------------------*/
int main(void)
{
/*配置系统中断分组为2位抢占2位响应*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/*延时函数初始化*/
delay_init();
/*RCC配置*/
Rcc_config();
/*GPIO初始化*/
Gpio_Init();
/*USART1初始化*/
Uart1_Init(9600);
/*定时器3初始化*/
Tim3_Init(5000-1,7200-1); //0.5s= 5000*7200/72M(72000000)(秒为单位)
//500ms=5000*7200000/72M(72000000)(毫秒位单位)
/*死循环*/
while(1){
printf("正常运行\r\n");
delay_ms(100);
}
}
/************************************************************** END OF FILE ****/