零基礎入門stm32基本定時器詳解


一、基本定時器介紹

 

在STM32中,基本定時器有TIM6、TIM7等。基本定時器主要包含時基單元,提供16位的計數,能計數0~65535。基本定時器除了計數功能以外,還能輸出給DAC模塊一個TRGO信號。基本定時器框圖如下:

 

 

二、時基單元介紹

 

STM32的所有定時器都具備時基單元,時基單元的功能就是簡單的計數,即計數時鍾源TMxCLK的脈沖個數,這個時鍾源來至APB1總線。高級和通用定時器還可以使用其他的時鍾源進行計數,在高級定時器和通用定時器中會詳細介紹。在基本定時器框架中可知時基單元包含如下三個部分:

1.ARR 自動重裝載寄存器

2.CNT 計數器

3.PSC  預分頻器

 

基本定時器的定時(計數)功能配置如下:

 

 

void TIM6_IRQHandler(void)

{

static int counter = 0;

if(TIM_GetITStatus(TIM6,TIM_IT_Update))

{

//在設置TIM_SelectOnePulseMode(TIM6,TIM_OPMode_Single);后中斷進去兩次

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

}

}

 

//基本定時器

void TIM6_Configuration()

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

NVIC_InitTypeDef  NVIC_InitStruct;

 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //時鍾使能

 

TIM_TimeBaseInitStruct.TIM_Period = 10 -1;

TIM_TimeBaseInitStruct.TIM_Prescaler = 72;

TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct);//  TIMx->EGR.UG   

 

NVIC_InitStruct.NVIC_IRQChannel  = TIM6_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

NVIC_Init(&NVIC_InitStruct);

 

TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

// TIM_SelectOnePulseMode(TIM6,TIM_OPMode_Single);//如需配置單脈沖模式,開啟此注釋

TIM_ARRPreloadConfig(TIM6,ENABLE);

TIM_Cmd(TIM6,ENABLE);//CEN  位

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

}

 

值得說明的是,基本定時器還支持單脈沖模式,配置單脈沖模式如代碼注釋即可。單脈沖模式要注意的是在定時器溢出兩次后才關閉定時器,即失能定時器。在代碼中,配置有中斷,在單脈沖模式下,可以清晰的看到進入定時器中斷2次。

 

三、定時器信號輸出

 

定時器的信號輸出與定時器中的控制寄存器2(TIM6->CR2)的MMS位相關,基本定時器輸出的信號只能用作DAC的觸發,而高級定時器、通用定時器的輸出信號可以觸發定時器以及DAC,具體細節這里不細說。定時器信號輸出的例子可以參考我的博文http://blog.csdn.net/quentinecho/article/details/79068001。這個例子中使用TIM6輸出的TRGO信號啟動了DAC產生一個三角波,當然其他的DAC觸發方式也可以產生一個三角波。

 

#include "stm32f10x.h"

#include "stm32f10x_rcc.h"

#include "system_stm32f10x.h"

#include "stm32f10x_dac.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_tim.h"

 

/*DAC輸出 = Vref x (DOR/4095)*/

 

//DAC的兩個通道可以配置使用

//相同觸發源/不同觸發源

//同時觸發/獨立觸發    DAC_DualSoftwareTriggerCmd函數設置軟件同時觸發

//使用波形發生器/不使用波形發生器

//使用三角波發生器/使用噪聲發生器/不使用波形發生器

//設置相同DAC_LFSRUnmask_TriangleAmplitude的值/設置不相同DAC_LFSRUnmask_TriangleAmplitude的值

//等等以上各種情況可以任意組合,互不影響。

void DAC_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

DAC_InitTypeDef DAC_InitStruct;

//第一步  使能時鍾

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);

//第二步  配置參數

/*一旦使能DACx通道,相應的GPIO引腳就會自動與DAC的模擬輸出相連,為了避免寄生的干擾和額外的功耗,引腳PA4/PA5在之前應當設置成“模擬輸入”

注意是“模擬輸入“,因為STM32中沒有模擬輸出,所以雖然PA4 PA5是輸出模擬信號,也只能設置成GPIO_Mode_AIN*/

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_SetBits(GPIOA,GPIO_Pin_4 | GPIO_Pin_5) ;//PA.4  PA.5輸入高 ,上拉輸入起抗干擾的作用

 

// /*DAC 通道1  PA4 產生噪聲*/

// DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Noise;

// DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO;//DAC_Trigger_T6_TRGO;

// DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//輸出緩存可以用來減少輸出阻抗,無需外部運放即可直接驅動外部負載

// DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits10_0;//每次觸發計算一次LSFR算法,並將得到的值再加上DAC_DHRx的數值,去掉溢出位后寫入DAC_DORx寄存器,輸出特定的電壓

// DAC_Init(DAC_Channel_1,&DAC_InitStruct);//參與LSFR算法的位數由DAC_LFSRUnmask_TriangleAmplitude來確定,DAC_LFSRUnmask_Bits10_0數值表示有10位參與LSFR計算

 

/*DAC 通道1  PA4 普通數模轉換*/

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;//關閉波形發生器

DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO;//DAC_Trigger_Software/DAC_Trigger_Ext_IT9

DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//輸出緩存可以用來減少輸出阻抗,無需外部運放即可直接驅動外部負載

DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//該參數與噪聲/三角波發生器相關,普通DAC轉換是設置為0即可

DAC_Init(DAC_Channel_1,&DAC_InitStruct);  

 

/*DAC 通道2  PA5 產生三角波*/

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;

DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO;

DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_4095;//內部的三角波計數器每次觸發時候之后累加1,該計數器的值與DAC_DHRx的數值相加,去掉溢出位后寫入DAC_DORx寄存器,輸出電壓

DAC_Init(DAC_Channel_2,&DAC_InitStruct);//三角波計數器的最大值由DAC_LFSRUnmask_TriangleAmplitude來確定,當計數器達到這個最大值,然后三角波計數器開始遞減

 

//第三步  使能器件

//DAC_SetDualChannelData(DAC_Align_12b_R,4095,0);等價於DAC_SetChannel1Data(DAC_Align_12b_R, 4095); DAC_SetChannel2Data(DAC_Align_12b_R, 0);  

/*DAC 通道1  PA4 使能*/

DAC_SetChannel1Data(DAC_Align_12b_R, 4095);  //12位右對齊數據格式設置DAC值  設置值最大為4095,設置成4096則溢出,DORx即為0

DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1

 

/*DAC 通道2  PA5 使能*/

DAC_Cmd(DAC_Channel_2, ENABLE);  //使能DAC1

DAC_SetChannel2Data(DAC_Align_12b_R, 0);  //12位右對齊數據格式設置DAC值

}

 

 

//基本定時器

void TIM6_Configuration()

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

//第一步  使能時鍾

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //時鍾使能

 

//第二步 配置參數

TIM_TimeBaseInitStruct.TIM_Period = 10 -1;

TIM_TimeBaseInitStruct.TIM_Prescaler = 72;

TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct);//  TIMx->EGR.UG   

 

 

/*TIM6,7可以輸出3種類型的TRGO信號

#define TIM_TRGOSource_Reset               ((uint16_t)0x0000) //復位 UG

#define TIM_TRGOSource_Enable              ((uint16_t)0x0010) //使能 CEN

#define TIM_TRGOSource_Update              ((uint16_t)0x0020) //更新事件

*/

 

TIM_SelectOutputTrigger(TIM6,TIM_TRGOSource_Update);//輸出觸發TRGO信號  這里TRGO信號就是定時器溢出產生的更新信號

 

//第三步  使能器件

TIM_Cmd(TIM6,ENABLE);//CEN  位

}

 

int main()

{

DAC_Configuration();

TIM6_Configuration();

while(1)

{

}

}

 

看到這里還是沒懂的話可以參考這個視頻資料

http://www.makeru.com.cn/live/1392_1199.html?s=45051


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM