****************************首選咱們瞭解一下它們的功能吧**************************************************************編程
TIM1和TIM8定時器的功能包括:
● 16位向上、向下、向上/下自動裝載計數器
● 16位可編程(能夠實時修改)預分頻器,計數器時鐘頻率的分頻係數爲1~65535之間的任意
數值
● 多達4個獨立通道:
─ 輸入捕獲
─ 輸出比較
─ PWM生成(邊緣或中間對齊模式)
─ 單脈衝模式輸出
● 死區時間可編程的互補輸出
● 使用外部信號控制定時器和定時器互聯的同步電路
● 容許在指定數目的計數器週期以後更新定時器寄存器的重複計數器
● 剎車輸入信號能夠將定時器輸出信號置於復位狀態或者一個已知狀態
● 以下事件發生時產生中斷/DMA:
─ 更新:計數器向上溢出/向下溢出,計數器初始化(經過軟件或者內部/外部觸發)
─ 觸發事件(計數器啓動、中止、初始化或者由內部/外部觸發計數)
─ 輸入捕獲
─ 輸出比較
─ 剎車信號輸入
● 支持針對定位的增量(正交)編碼器和霍爾傳感器電路
● 觸發輸入做爲外部時鐘或者按週期的電流管理 函數
****************************************************************************************************************ui
以定時器8講解。。。。。。好多代碼都是複製粘貼 代碼可能有的沒有必要,或則思路累贅,可是實測能達到目的編碼
void TIM8_PWM_Init(u16 arr,u16 psc)
{ spa
/*******************************************************************************3d
這一段是各類結構體聲明瞭,就不用多說了orm
********************************************************************************/
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;blog
/*******************************************************************************事件
第一步:時鐘使能ip
********************************************************************************/
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:容許COM的DMA請求 (COM DMA request enable) 0:禁止COM的DMA請求; 1:容許COM的DMA請求。 |
位12 | CC4DE:容許捕獲/比較4的DMA請求 (Capture/Compare 4 DMA request enable) 0:禁止捕獲/比較4的DMA請求; 1:容許捕獲/比較4的DMA請求。 |
位11 | CC3DE:容許捕獲/比較3的DMA請求 (Capture/Compare 3 DMA request enable) 0:禁止捕獲/比較3的DMA請求; 1:容許捕獲/比較3的DMA請求。 |
位10 | CC2DE:容許捕獲/比較2的DMA請求 (Capture/Compare 2 DMA request enable) 0:禁止捕獲/比較2的DMA請求; 1:容許捕獲/比較2的DMA請求。 |
位9 | CC1DE:容許捕獲/比較1的DMA請求 (Capture/Compare 1 DMA request enable) 0:禁止捕獲/比較1的DMA請求; 1:容許捕獲/比較1的DMA請求。 |
位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; } }}