STM32F40EZT6 定时器中断

片内滴答定时器(SysTick)定时原理

        系统定时原理是由晶振产生电流脉冲,而电流脉冲的频率F是固定的,那么通过记录脉冲节拍数N;那么:T=N/F,或者说T=1/F

STM32F40EZT6 定时器中断_第1张图片

第一步:设置SysTick->CTRL(控制个状态寄存器)

STM32F40EZT6 定时器中断_第2张图片

        设置SysTick->CTRL的第三位(TICKINT)设置检查外部时钟还是内部时钟(我选的外部时钟),并将第十六位状态位(COUNTGLAG)置零,TICKINT一般设为0;

        第二步:设置自动重载寄存器(ARR)

自动重载寄存器可以设置23位即最大值为二的23次方。我设置的是按照我修改的数据计算出21个节拍为一微秒。

计算过程:

首先得分析时钟树,PLL为CPU主频,那么PLL接收的是哪晶振呢?

STM32F40EZT6 定时器中断_第3张图片

根据时钟树可以看到连接HSE OSC这个,给出的频率也是一个范围,这是因为芯片型号的不同频率可能会不一样。但根据引脚编码结合原理图可以看到OSC_OUT 和OSE_IN对应的是8MHz的频率,但过程中又有那么多分频之类的。参数也是未知的。这个就是软件的事了。

STM32F40EZT6 定时器中断_第4张图片

STM32F40EZT6 定时器中断_第5张图片

通过启动程序模块的代码可以看到(不同型号的找对应信号的),一下代码,

  *=============================================================================
  *                    Supported STM32F40xxx/41xxx devices
  *-----------------------------------------------------------------------------
  *        System Clock source                    | PLL (HSE)
  *-----------------------------------------------------------------------------
  *        SYSCLK(Hz)                             | 168000000
  *-----------------------------------------------------------------------------
  *        HCLK(Hz)                               | 168000000
  *-----------------------------------------------------------------------------
  *        AHB Prescaler                          | 1
  *-----------------------------------------------------------------------------
  *        APB1 Prescaler                         | 4
  *-----------------------------------------------------------------------------
  *        APB2 Prescaler                         | 2
  *-----------------------------------------------------------------------------
  *        HSE Frequency(Hz)                      | 25000000
  *-----------------------------------------------------------------------------
  *        PLL_M                                  | 25
  *-----------------------------------------------------------------------------
  *        PLL_N                                  | 336
  *-----------------------------------------------------------------------------
  *        PLL_P                                  | 2
  *-----------------------------------------------------------------------------
  *        PLL_Q                                  | 7
  *-----------------------------------------------------------------------------
  *        PLLI2S_N                               | NA
  *-----------------------------------------------------------------------------
  *        PLLI2S_R                               | NA
  *-----------------------------------------------------------------------------
  *        I2S input clock                        | NA
  *-----------------------------------------------------------------------------
  *        VDD(V)                                 | 3.3
  *-----------------------------------------------------------------------------
  *        Main regulator output voltage          | Scale1 mode
  *-----------------------------------------------------------------------------
  *        Flash Latency(WS)                      | 5
  *-----------------------------------------------------------------------------
  *        Prefetch Buffer                        | ON
  *-----------------------------------------------------------------------------
  *        Instruction cache                      | ON
  *-----------------------------------------------------------------------------
  *        Data cache                             | ON
  *-----------------------------------------------------------------------------
  *        Require 48MHz for USB OTG FS,          | Disabled
  *        SDIO and RNG clock                     |
  *-----------------------------------------------------------------------------
  *=============================================================================

这里的HSE为25000 000Hz(即25MHz)那么这个参数就对不上了,HSE出来的第一个分频参数 PLL_M 也跟着最好改改  不然不好算(记得修改文件权限,因为这文件是只读的)。

STM32F40EZT6 定时器中断_第6张图片

改完后:

  HSE(8MHz)/PLL_M(8)*PLL_N(336)/ PLL_P(2) /AHB(1) =168MHz

168MHz/8=21MHz;

所以21个节拍为1us;

第三步:SysTick->VAL清空计数器

STM32F40EZT6 定时器中断_第7张图片

第四步:启动计时器        

        SysTick->CTRL|=0x01;

定时器到达设定时间判断:标志位是否为1即可

代码如下:

        这是一个精准延迟1微妙,通过直接操作寄存器设置完成的。

void delay_us(int x){
	
	SysTick->CTRL=0;
	SysTick->LOAD=x*21-1;
	SysTick->VAL=0;
	SysTick->CTRL|=0x01;
	while(!(SysTick->CTRL&(0x01<<16)));
}

通用定时器TIM14 (定时器中断)

        通用定时器跟片内滴答定时器原理基本一致,都是通过脉冲频率推算时间的;

STM32F40EZT6 定时器中断_第8张图片

STM32F40EZT6 定时器中断_第9张图片

STM32F40EZT6 定时器中断_第10张图片

TIM14对应的是APB1 (这里的频率为什么这么算我也不大清楚,有知道的麻烦告知)

这里采用标准库函数设置;

代码如下:

void timeer_init(){
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
//	设置分频 将84MH降为10000Hz
	TIM_TimeBaseInitStruct.TIM_Prescaler=8400-1;
//	设置计数模式往上加,还是往下减
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
//	设置自动复位计数器为10000,恰好为1秒
	TIM_TimeBaseInitStruct.TIM_Period=10000-1;
//	设置分频为1
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
//	初始化定时器
	TIM_TimeBaseInit(TIM14, &TIM_TimeBaseInitStruct);
//	开启定时器
	TIM_Cmd( TIM14, ENABLE);
//	打开定时器中断
	TIM_ITConfig(TIM14, TIM_IT_Update,ENABLE);
//	设置仲裁优先级,并打开中断
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel= TIM8_TRG_COM_TIM14_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=5;
	NVIC_InitStruct.NVIC_IRQChannelCmd= ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
	NVIC_Init(&NVIC_InitStruct);
}
// 中断处理函数编写
void TIM8_TRG_COM_TIM14_IRQHandler(){
//		检查中断标准位是否为1
	if(TIM_GetITStatus(TIM14,TIM_FLAG_Update)==SET){
//		开关灯
		PF_ODR(9)=!PF_ODR(9);
//		降中断标志位复位
		TIM_ClearITPendingBit( TIM14, TIM_FLAG_Update);
	}
}

你可能感兴趣的:(STM32,stm32,嵌入式硬件,单片机)