stm32定時器配置
軟體工程
想要配置定時器首先的明白定時器時鐘是多少。
計數原理
首先我們來看時鐘圖
APB1 預分頻器,分頻因數按照/1、2、4、8、16,能得到五種分頻方式,
但是 APB1 預分頻器後匯流排設計的最高頻率只能是 36M;所以 APB1 預分
頻器在輸入頻率為 72M 時只能採用 2、4、8、16 四種分頻方式。從圖上
可與看出 TIM2、3、4、5、6、7 輸入端的最高頻率是 36M(最高頻率由
晶片設計決定)。根據 TIM2、3、4、5、6、7 輸出端頻率的設計原則(藍
色框文字說明),當輸入端的頻率是 36M 時,6 個外設時鐘輸出端頻率
是 72M。
APB2 預分頻器,分頻因數按照/1、2、4、8、16,能得到五種分頻方式,
APB2 預分頻器後匯流排設計的最高頻率等達到 72M;所以 APB2 預分頻器只
能採用 1、2、4、8、16 五種分頻方式。從圖上可以看出 TIM1、8 輸入端
的最高頻率是 72M。根據 TIM1、8 輸出端頻率的設計原則(藍色框文字
說明),當輸入端的頻率是 72M 時,2 個外設時鐘輸出端頻率是 72M
4.5.2.3 計數器模式
TIM2-TIM5 可以由向上計數、向下計數、向上向下雙向計數。向上計數模式
中,計數器從 0 計數到自動載入值(TIMx_ARR 計數器內容),然後重新從 0
開始計數併產生一個計數器溢位事件。在向下計數模式中,計數器從自動裝
入的值(TIMx_ARR)開始向下計數到 0,然後從自動裝入的值重新開始,並
產生一個計數器向下溢位事件。而中央對齊模式(向上/向下計數)是計數
器從 0 開始計數到自動裝入值-1,產生一個計數器溢位事件,然後向下計數
到 1 併產生一個計數器溢位事件;然後再從 0 開始重新計數
實驗目的
通過定時器 TIM3 產生間隔 1 秒一次的中斷,在中斷中控制 LED 發光二
極管,每次中斷都使發光二極體狀態取反
在這個小程式中我們要熟悉 TIM3_Configuration()這個函式。
我們全部使用庫函式編寫程式,在這裡要注意“清空”的操作,比如進
入中斷處理程式後,要先清空中斷標誌;進入定時器處理程式時,也要清空
定時器標誌
stm32f10x_gpio.cstm32f10x_rcc.cMisc.c // 中斷控制字(優先順序設定)庫函式stm32f10x_exti.c // 外部中斷庫處理函式stm32f10x_tim.c
// 定時器庫處理函式
一下為需要引入的標頭檔案
#ifndef _pbdata_H
#define _pbdata_H
#include "stm32f10x.h"
#include "stm32f10x_tim.h"
#include "misc.h"
//¶¨Òå±äÁ¿
extern u8 dt;
//¶¨Ò庯Êý
void delay(u32 nCount);
#endif
int main(void)
{
dt=123;
delay(100);
}
void RCC_Configuration(void)
{
SystemInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//LED
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
TIM_TimeBaseStruct.TIM_Period=2000;//³õÖµ Èç¹ûÏëÒª¼ÆÊý2000´Î²úÉúÒ»´ÎÖжÏÄÇô·ÖƵֵΪ 72000000/2000 = 35999
TIM_TimeBaseStruct.TIM_Prescaler=35999;//Ô¤·ÖƵ
TIM_TimeBaseStruct.TIM_ClockDivision=0;
TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;//ÏòÉÏ
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3,ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/****************************************************************************
* Ãû ³Æ£TIM3_IRQHandler
* ¹¦ ÄÜ£ºTIM3Öжϴ¦Àí³ÌÐò
* Èë¿Ú²ÎÊý£ºÎÞ
* ³ö¿Ú²ÎÊý£ºÎÞ
* ˵ Ã÷£º
* µ÷Ó÷½·¨£ºÎÞ
****************************************************************************/
void TIM3_IRQHandler(void)
{
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==Bit_RESET)
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)==Bit_RESET)
{
//LED ϨÃð
GPIO_SetBits(GPIOB,GPIO_Pin_5);
}
else
{
//LED ·¢¹â
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
}
}
}
比較重要的是分頻和過載值的計算
如果想要計數2000次產生一次中斷那麼分頻值為72000000/2000 = 35999
想想如果要產生10us該怎麼配置呢?