1. 程式人生 > >STM32學習---基本定時器(定時中斷)

STM32學習---基本定時器(定時中斷)

//STM32定時器實驗:
/*
STM32一共有8個都為16位的定時器。
其中:
TIM6,TIM7是基本定時器;
TIM2,TIM3,TIM4,TIM5是通用定時器;
TIM1 和 TIM8 是高階定時器。
這是定時器的綜合運用使STM32具有定時、訊號的頻率測量、訊號的PWM測量、PWM輸出、三相六部電機控制及編碼器介面等功能,都是專門為工控領域量身定做的。
*/

/*
一:定時器工作分析:
1.基本定時器:
基本定時器TIM6 和 TIM7 只具備最基本的定時功能,就是累加的時鐘脈衝數超過預定值時,能 觸發中斷 或 觸發DMA請求。
由於在晶片內部與DAC外設相連,可通過觸發輸出驅動DAC,也可作為其他通用定時器的時鐘基準。

這兩個基本定時器使用的時鐘源都是TIMxCLK,時鐘源經過PSC預分頻器輸入至脈衝計數器TIMx_CNT,基本定時器只能工作在向上技術模式,在
過載暫存器TIMx_ARR的計數器中儲存的是定時器的溢位值。

工作時,脈衝計數器TIMx_CNT由時鐘觸發進行計數,當TIMx_CNT的計數值X等於過載暫存器TIMx_ARR中儲存的數值N時,產生溢位時間,可觸發中斷或DMA請求。
然後TIMx_CNT的值重新被置為0,重新向上計數。
*/

對於基本定時器TIM6 和 TIM7 定義的步驟是:
1)對TIM外設首先進行時基定義:

void BaseTIM_CfgInit(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStu;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); 

    TIM_TimeBaseInitStu.TIM_Prescaler = 1000;           //預分頻係數
    TIM_TimeBaseInitStu.TIM_Period = 72 - 1;            //重灌載值  
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStu);

    //注意要開啟定時器中斷,這裡使用更新事件中斷
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

    //開啟計數器
    TIM_Cmd(TIM6, ENABLE);
}

//如何算的預分頻係數?72Mhz/(.TIM_Prescaler+1)*(.TIM_Period+1)=1/中斷產生的間隔;
//其實在定義完.TIM_Period之後,還要定義一個.TIM_ClockDivision,這個結構體成員的定義影響的是:ETRP數字濾波器。而我們使用的是內部時鐘,所以這個變數的定義對實驗結果無影響。

2)隨後定義NVIC:

void NVIC_CfgInit(void)
{
    NVIC_InitTypeDef NVIC_InitStu;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);     //設定中斷分組暫存器
    NVIC_InitStu.NVIC_IRQChannel = TIM6_IRQn;           //外部中斷線,定時器6
    NVIC_InitStu.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStu.NVIC_IRQChannelPreemptionPriority = 1; //搶佔優先順序
    NVIC_InitStu.NVIC_IRQChannelSubPriority = 1;        //子優先順序
    NVIC_Init(&NVIC_InitStu);
}

3)在stm32f10x_it.c中實現定時器超時的中斷處理函式:

void TIM6_IRQHandler(void)
{
	static int i =0;
    if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
    {
			  i++;
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
    }
	if(i==1000){
		GPIO_WriteBit(GPIOD, GPIO_Pin_2,  
                (BitAction)((1-GPIO_ReadOutputDataBit(GPIOD, GPIO_Pin_2))));
		i=0;
		}
}

//可以在其中設定if判斷具體要中斷的時間。

因為定時器的週期是 1ms,此時我設定的條件是及時1000次,即1s,燈的狀態會取反。