STM32----3----PWM
[ ST32
PWM form Timer ]
TIM6 and
TIM7 不能產生 PWM
TIM1 and TIM8
高級計數器 各可以同時產生 7 組 PWM
TIM2,3,4,5
普通計時器 各可以同時產生 4 組 PWM
ST32
最多可以同時產生 30組PWM(2x7 + 4x4 )
[ PWM Reg
]
TIMx_CCMR1
..2, (捕獲/比較 mode Reg)
TIMx_CCER (捕獲/比較 enable Reg)
TIMx_CCR1..4 (捕獲/比較 working Reg)
TIMx_CCMR1
=> CH1,CH2
TIMx_CCMR2
=> CH3,CH4
void PWM_Configuration(void)//PWM初始化函數
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //計時器初始化結構
TIM_OCInitTypeDef TIM_OCInitStructure; //通道輸出初始化結構
GPIO_InitTypeDef GPIO_InitStructure; //輸出通道的GPIO管腳結構
//(1)TIM3初始化,時間基部分
TIM_TimeBaseStructure.TIM_Period =999; //週期0~999
TIM_TimeBaseStructure.TIM_Prescaler = 71; //時鐘分頻
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //時鐘分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //基本初始化
//TIM_ITConfig(TIM3, TIM_IT_CC4, ENABLE); //打開中斷,中斷需要這行代碼
//(2)TIM3通道初始化 ,CCP部分
TIM_OCStructInit(& TIM_OCInitStructure); //默認參數
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作狀態
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //設定為輸出,需要PWM輸出才需要這行代碼
TIM_OCInitStructure.TIM_Pulse =250 ; //占空長度
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高電平
TIM_OC4Init(TIM3, &TIM_OCInitStructure); //通道初始化
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作狀態
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //設定為輸出,需要PWM輸出才需要這行代碼
TIM_OCInitStructure.TIM_Pulse =500 ; //占空長度
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高電平
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //通道初始化
//TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作狀態
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //設定為輸出,需要PWM輸出才需要這行代碼
TIM_OCInitStructure.TIM_Pulse =750 ; //占空長度
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高電平
TIM_OC2Init(TIM3, &TIM_OCInitStructure)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作狀態
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //設定為輸出,需要PWM輸出才需要這行代碼
TIM_OCInitStructure.TIM_Pulse =900 ; //占空長度
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高電平
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_Cmd(TIM3, ENABLE); //使能TIM3,到此在TIM中已配置完成,下面開始配置GPIO
//(3)PWM輸出通道初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//選擇PC
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //管腳頻率為50MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //模式為推挽輸出
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOA寄存器
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3 , ENABLE);
}
===================================================================
[Ext2: 啟動PWM 範例 5 個步驟]
//Step1.啟動TIM1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//Step2. PA.8口設置為TIM1的OC1輸出口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Step3.使能TIM1的輸出比較匹配中斷
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//Step4. TIM模組設置
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//TIM1基本計數器設置
TIM_BaseInitStructure.TIM_Period = 0xffff; //這裡必須是65535 ( TIMx_ARR)
TIM_BaseInitStructure.TIM_Prescaler = 71; //預分頻71,即72分頻,得1M (TIMx_PSC)
TIM_BaseInitStructure.TIM_ClockDivision = 0;
TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure);
//TIM1_OC1模組設置
TIM_OCStructInit(& TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //管腳輸出模式:翻轉
TIM_OCInitStructure.TIM_Pulse = 2000; //翻轉週期:2000個脈衝
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能TIM1_CH1通道
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出為正邏輯
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //寫入配置
//清中斷
TIM_ClearFlag(TIM1, TIM_FLAG_CC1);
//TIM1中斷源設置,開啟相應通道的捕捉比較中斷
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
//TIM1開啟
TIM_Cmd(TIM1, ENABLE);
//通道輸出使能
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
//Step5.TIM1 中斷服務副程式
void TIM1_CC_IRQHandler(void)
{
u16 capture;
if(TIM_GetITStatus(TIM1, TIM_IT_CC1) == SET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM1);
TIM_SetCompare1(TIM1, capture + 2000);
//這裡解釋下:
//將TIM1_CCR1的值增加2000,使得下一個TIM事件也需要2000個脈衝,
//另一種方式是清零脈衝計數器
//TIM_SetCounter(TIM2,0x0000);
}
}
=====================================================
[ ext3 PWM drive demo code ]
/*
這個是STM32的PWM輸出模式,STM32的TIM1模組是增強型的計時器模組,天生就是為電機控制而生,可以產生3組6路PWM,同時每組2路PWM為互補,並可以帶有死區,可以用來驅動H橋。
下面的代碼,是利用TIM1模組的1、2通道產生一共4路PWM的代碼例子,
類似代碼也可以參考ST的固件庫中相應exampleC語言:TIM1模組產生PWM,帶死區
*/
//Step1.開啟TIM和相應埠時鐘//啟動GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|\RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,\ENABLE);
//啟動AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//啟動TIM1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
//Step2.GPIO做相應設置,為AF輸出//PA.8/9口設置為TIM1的OC1輸出口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//PB.13/14口設置為TIM1_CH1N和TIM1_CH2N輸出口
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//Step3.TIM模組初始化
voidTIM_Configuration(void){
TIM_TimeBaseInitTypeDefTIM_BaseInitStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
TIM_BDTRInitTypeDefTIM_BDTRInitStructure;
//TIM1基本計數器設置(設置PWM頻率)//頻率=TIM1_CLK/(ARR+1)
TIM_BaseInitStructure.TIM_Period=1000-1;
TIM_BaseInitStructure.TIM_Prescaler=72-1;
TIM_BaseInitStructure.TIM_ClockDivision=0;
TIM_BaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_BaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM1,&TIM_BaseInitStructure);
//啟用ARR的影子寄存器(直到產生更新事件才更改設置)
TIM_ARRPreloadConfig(TIM1,ENABLE);
//TIM1_OC1模組設置(設置1通道占空比)
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_Pulse=120;
TIM_OC1Init(TIM1,&TIM_OCInitStructure);
//啟用CCR1寄存器的影子寄存器(直到產生更新事件才更改設置)
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
//TIM2_OC2模組設置(設置2通道占空比)
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse=680;
TIM_OC2Init(TIM1,&TIM_OCInitStructure);
//啟用CCR2寄存器的影子寄存器(直到產生更新事件才更改設置)
TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
//死區設置
TIM_BDTRInitStructure.TIM_OSSRState=TIM_OSSRState_Enable;
TIM_BDTRInitStructure.TIM_OSSIState=TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel=TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime=0x90;//這裡調整死區大小0-0xff
TIM_BDTRInitStructure.TIM_Break=TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity=TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
//TIM1開啟
TIM_Cmd(TIM1,ENABLE);
//TIM1_OC通道輸出PWM(一定要加)
TIM_CtrlPWMOutputs(TIM1,ENABLE);
}
//其實,PWM模組還可以有很多花樣可以玩,比方在異常時(如CPU時鐘有問題),可以緊急關閉輸出,以免發生電路燒毀等嚴重事故。
沒有留言:
張貼留言