Temporizador TIM - STM32
Temporizador TIM (Temporizador)
O temporizador pode contar o relógio de entrada e disparar uma interrupção quando o valor da contagem atingir o valor definido. A unidade de base de tempo
do contador de 16 bits, prescaler e registro de recarga automática, sob o relógio de contagem de 72MHz Pode atingir um tempo máximo de 59,65s.
Não só tem a função de interrupção de tempo básica, mas também inclui seleção de fonte de relógio interno e externo, captura de entrada, comparação de saída, interface de codificador, modo de disparo mestre-escravo e outras funções. De acordo com a complexidade e cenários de aplicação, é dividido em avançado Existem três tipos de temporizadores, temporizadores gerais e temporizadores básicos.
Mesmo se eu alterar o valor do prescaler no meio da contagem, a frequência de contagem ainda permanecerá na frequência original até que a rodada atual de contagem seja concluída, e o valor de divisão de frequência alterado entrará em vigor na próxima rodada de contagem.
Todos os registradores com uma sombra preta possuem mecanismos de buffer, como registradores de sombra.
O objetivo da introdução deste registrador sombra é, na verdade, para sincronização, ou seja, para fazer com que o evento de alteração de valor e atualização ocorram de forma síncrona, para evitar erros causados por alterações durante a operação e para interromper as etapas de configuração do temporizador
.
Relógio RCC
. A segunda etapa é selecionar a base de tempo A fonte de relógio da unidade
A terceira etapa, configurar a unidade de base de tempo
A quarta etapa, configurar o controle de interrupção de saída, permitir a atualização da saída de interrupção para o NMIC
A quinta etapa, configurar o NVIC, abra o canal de interrupção do temporizador no NMIC e atribua uma
prioridade Seis etapas, é o controle de operação
#include "stm32f10x.h" // Device header
//exten声明变量,就是告诉编译器,现在有Num这个变量,e
//它在别的文件里定义了,用户跨文件使用变量
extern uint16_t Num;
void Timer_Intial(void)
{
//第一步开启时钟,初始化RCC,选择TIM2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//第二步选择时基单元的时钟,选择内部时钟,选择TIM2
TIM_InternalClockConfig(TIM2);
//第三步配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频系数 1分频
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数的模式 向上计数
//计数器溢出频率:CK CNT_OV = CKCNT /(ARR + 1)= CK PSC /(PSC + 1)/(ARR +1)
//配置定时为1s,则CK CNT_OV=1;CKCNT=72MHz=72000000;
TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;//周期,ARR自动重装器的值 范围0~65536
TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;//PSC预分频器的值 范围0~65536
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //重复计数器的值 高级计数器才有
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
//第四步配置输出中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//更新中断
//清除中断标志位,能够避免刚初始化完就进中断的问题
TIM_ClearFlag(TIM2,TIM_IT_Update);
//第五步,配置NVIC
//注意:分组方式整个芯片只能用一种,因此,分组的代码只需要执行一次
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择中断分组
//初始化NVIC
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
//第六步,运行控制
TIM_Cmd(TIM2,ENABLE);
}
//定时器的中断函数
void TIM2_IRQHandler(void)
{
//首先检查一下中断标志位
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
{
Num++;
//清除标志位
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
#ifndef _TIMER_H
#define _TIMER_H
void Timer_Intial(void);
#endif
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "Timer.h"
uint16_t Num;
int main(void)
{
while(1)
{
}
}
Como usar variáveis entre arquivos, usadas na função de interrupção
A primeira solução é usar variáveis cross-file, que podem ser declaradas com extern.A
segunda solução é cortar a função de interrupção para a função principal, que está na mesma pasta da variável.