stm32f103_高級定時器——輸入捕獲/輸出比較中斷+pwm=spwm生成


****************************首選我們了解一下它們的功能吧**************************************************************

TIM1TIM8定時器的功能包括:
16位向上、向下、向上/下自動裝載計數器
16位可編程(可以實時修改)預分頻器,計數器時鍾頻率的分頻系數為165535之間的任意
數值
● 多達4個獨立通道:
輸入捕獲
輸出比較
PWM生成(邊緣或中間對齊模式)
單脈沖模式輸出
● 死區時間可編程的互補輸出
● 使用外部信號控制定時器和定時器互聯的同步電路
● 允許在指定數目的計數器周期之后更新定時器寄存器的重復計數器
● 剎車輸入信號可以將定時器輸出信號置於復位狀態或者一個已知狀態
● 如下事件發生時產生中斷/DMA
更新:計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發)
觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)
輸入捕獲
輸出比較
剎車信號輸入
● 支持針對定位的增量(正交)編碼器和霍爾傳感器電路
● 觸發輸入作為外部時鍾或者按周期的電流管理

****************************************************************************************************************

以定時器8講解。。。。。。好多代碼都是復制粘貼    代碼可能有的沒有必要,或則思路累贅,但是實測能達到目的

void TIM8_PWM_Init(u16 arr,u16 psc)
{

/*******************************************************************************

這一段是各種結構體聲明了,就不用多說了

********************************************************************************/
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

/*******************************************************************************

第一步:時鍾使能

********************************************************************************/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);// 使能定時器時鍾
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE); //使能GPIO外設時鍾使能

/*******************************************************************************

第二步:spwm波形輸出管腳的初始化

********************************************************************************/

//設置該引腳為復用輸出功能,輸出TIM1 CH1的PWM脈沖波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_7; //TIM_CH2, 3 4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);

/*******************************************************************************

第三步:定時器的初始化參數

這里我就通過初始化函數 TIM_TimeBaseInit 實現的 

              1-設置自動重載計數周期值 

              2-設置時鍾分頻系數

              3-設置時鍾分頻因子

             4-設置計數方式 (我設置的向上計數模式)

********************************************************************************/

TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值 80K
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鍾頻率除數的預分頻值 不分頻
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鍾分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

/*******************************************************************************

第四步:設置 TIM8_CH2&CH3&CH4 PWM 模式 

1.PWM模式1- 在向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為有效電平,否則為
無效電平;在向下計數時,一旦TIMx_CNT>TIMx_CCR1時通道1為無效電平(OC1REF=0),否
則為有效電平(OC1REF=1)。
2.PWM模式2- 在向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為無效電平,否則為
有效電平;在向下計數時,一旦TIMx_CNT>TIMx_CCR1時通道1為有效電平,否則為無效電
平。
3.輸出比較極性指的是有效電平

從上面的截圖我們可以看出,我們要打開定時8或則關閉定時器八通道pwm輸出時,只需要操作寄存器CCER,也就是用TIM8->CCER指令操作寄存器。

還有捕獲/比較寄存器(TIMx_CCR2~4),對應 3輸通道 CH2~4。因為這 3個寄存器都差不多,我們僅以 TIMx_CCR2 為例介紹:該寄存器是通道2捕獲/比較的值。

其實下面的TIM_Pulse參數就是給CCR2寄存器賦值的,也就是設置待裝入捕獲比較寄存器的脈沖值。通過改變此能改變占空比,TIM8->CCR2代碼實現。

 

CCR2[15:0]: 捕獲/比較通道2的值 (Capture/Compare 2 value)
CC2通道配置為輸出:
CCR2包含了裝入當前捕獲/比較2寄存器的值(預裝載值)
如果在TIMx_CCMR2寄存器(OC2PE)中未選擇預裝載特性,寫入的數值會立即傳輸至當前寄
存器中。否則只有當更新事件發生時,此預裝載值才傳輸至當前捕獲/比較2寄存器中。
當前捕獲/比較寄存器參與同計數器TIMx_CNT的比較,並在OC2端口上產生輸出信號。
CC2通道配置為輸入:
CCR2包含了由上一次輸入捕獲2事件(IC2)傳輸的計數器值。


 

********************************************************************************/

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈沖值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性:TIM輸出比較極性高
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //根據TIM_OCInitStruct中指定的參數初始化外設TIMx

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈沖值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性:TIM輸出比較極性高
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //根據TIM_OCInitStruct中指定的參數初始化外設TIMx

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈沖值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性:TIM輸出比較極性高
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //根據TIM_OCInitStruct中指定的參數初始化外設TIMx

TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1預裝載使能
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1預裝載使能
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //CH1預裝載使能

/*******************************************************************************

第五步:中斷打開,優先級配置

TIM_IT_Update:更新中斷,計數器向上溢出/向下溢出,計數器初始化(通過軟件或者內部/外部觸發) 

TIM_IT_CC1~4:都是捕獲/比較中斷,貌似都是平等的,即輸入捕獲,輸出比較

TIM_IT_Trigger:觸發事件(計數器啟動、停止、初始化或者由內部/外部觸發計數)

使用的時候都是調用函數TIM_ITConfig()來使能指定的中斷類型,調用TIM_GetITStatus()函數來查看是否有中斷發生,入口參數都是平等的。

可能就是不同的事件導致中斷的發生略有不同

輸入捕獲中斷:發生輸入捕獲,立即在硬件上產生一個中斷標志,產生中斷請求,要是當前沒有比捕獲中斷更高級別的中斷在執行或等待執行,那么就會立即跳轉到你中斷函數里面去執行代碼。
13.4.4 TIM1 TIM8 DMA/中斷使能寄存器(TIMx_DIER)

 

15 保留,始終讀為0
14 TDE:允許觸發DMA請求 (Trigger DMA request enable)
0:禁止觸發DMA請求;
1:允許觸發DMA請求。
13 COMDE:允許COMDMA請求 (COM DMA request enable)
0:禁止COMDMA請求;
1:允許COMDMA請求。
12 CC4DE:允許捕獲/比較4DMA請求 (Capture/Compare 4 DMA request enable)
0:禁止捕獲/比較4DMA請求;
1:允許捕獲/比較4DMA請求。
11 CC3DE:允許捕獲/比較3DMA請求 (Capture/Compare 3 DMA request enable)
0:禁止捕獲/比較3DMA請求;
1:允許捕獲/比較3DMA請求。
10 CC2DE:允許捕獲/比較2DMA請求 (Capture/Compare 2 DMA request enable)
0:禁止捕獲/比較2DMA請求;
1:允許捕獲/比較2DMA請求。
9 CC1DE:允許捕獲/比較1DMA請求 (Capture/Compare 1 DMA request enable)
0:禁止捕獲/比較1DMA請求;
1:允許捕獲/比較1DMA請求。
8 UDE:允許更新的DMA請求 (Update DMA request enable)
0:禁止更新的DMA請求;
1:允許更新的DMA請求。
7 BIE:允許剎車中斷 (Break interrupt enable)
0:禁止剎車中斷;
1:允許剎車中斷。
6 TIE:觸發中斷使能 (Trigger interrupt enable)
0:禁止觸發中斷;
1:使能觸發中斷。
5 COMIE:允許COM中斷 (COM interrupt enable)
0:禁止COM中斷;
1:允許COM中斷。
4 CC4IE:允許捕獲/比較4中斷 (Capture/Compare 4 interrupt enable)
0:禁止捕獲/比較4中斷;
1:允許捕獲/比較4中斷。



3 CC3IE:允許捕獲/比較3中斷 (Capture/Compare 3 interrupt enable)
0:禁止捕獲/比較3中斷;
1:允許捕獲/比較3中斷。
2 CC2IE:允許捕獲/比較2中斷 (Capture/Compare 2 interrupt enable)
0:禁止捕獲/比較2中斷;
1:允許捕獲/比較2中斷。
1 CC1IE:允許捕獲/比較1中斷 (Capture/Compare 1 interrupt enable)
0:禁止捕獲/比較1中斷;
1:允許捕獲/比較1中斷。
0 UIE:允許更新中斷 (Update interrupt enable)
0:禁止更新中斷;
1:允許更新中斷。

********************************************************************************/

TIM_ClearFlag(TIM8, TIM_FLAG_Update);//清除中斷標志,如果沒有添加這條語句,會先進一次中斷

TIM_ITConfig(TIM8, TIM_IT_CC2/*TIM 輸入捕獲中斷源*/, ENABLE); //使能或者失能指定的TIM中斷
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;//TIM8捕捉比較中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主輸出使能 高級定時器需要這句   我們還需要
                                                   //使能剎車和死區寄存器(TIM1_BDTR)的 MOE 位,以使能整個 OCx(即 PWM)輸出


TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的預裝載寄存器

/*******************************************************************************

如果在TIMx_CCMR1寄存器(OC1PE)中未選擇預裝載功能,寫入的數值會立即傳輸至當前寄
存器中。否則只有當更新事件發生時,此預裝載值才傳輸至當前捕獲/比較1寄存器中。

 

 

所以我用的通道而輸入捕獲中斷,在中斷函數里給三個通道占空比賦值,雖然通道二發生輸入捕獲后,通道3或則通道4有可能還沒有發生輸入捕獲,但是由於我已經選擇了預裝在功能,所以數值還是要等定時器8發生更新事件時在傳輸到輸入捕獲寄存器(CCR2~4),這就沒有影響了。

********************************************************************************/



TIM_Cmd(TIM8, ENABLE); //使能TIM1

}

/*******************************************************************************

第六步:中斷函數編寫

SVPWM1_P......:正弦表

********************************************************************************/


uint16_t count = 0;
uint16_t num = 360;//sizeof(SVPWM1_P)/(sizeof(SVPWM1_P[0]));
void TIM8_CC_IRQHandler(void)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET)
{
TIM8->SR = (uint16_t)~TIM_IT_CC2; //清除TIMx的中斷待處理位:TIM 中斷源
TIM8->CCR2 = SVPWM1_P[count];
TIM8->CCR3 = SVPWM2_P[count];
TIM8->CCR4 = SVPWM3_P[count];
count++;
if(count==num)
{
count=0;
}
}
}


免責聲明!

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



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