見名知意,當然是使能TIM3定時器的啊。使CC4E置位為1就可以了。
我們文本的例子是定時器3的通道3,對應PB0管腳。
1.開啟TIM3時鐘,配置 PB0要使用 TIM3,我們必須先開啟 TIM3的時鐘,這點相信大家看了這麼多代碼,應該明白了。這裡我們還要配置 PB0 為復用輸出(當然還要使能 GPIOB的時鐘),這是因為 TIM3_CH3通道將使用 PB0的復用功能作為輸出,我們配置 PB0為復用輸出,才可以實現 TIM3_CH3的 PWM 經過 PB0輸出。
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM外設時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能GPIO外設時鐘
//設置該引腳為復用輸出功能,輸出TIM3 CH3的PWM脈衝波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM3_CH3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 100;
TIM_TimeBaseStructure.TIM_Prescaler =360-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
接下來,我們要設置 TIM3_CH3為 PWM 模式,我們要通過配置 TIM3_CCMR2的相關位來控制 TIM3_CH3 的模式。在庫函數中,PWM 通道設置是通過函數 TIM_OC1Init()~TIM_OC4Init()來設置的,不同的通道的設置函數不一樣,這裡我們使用的是通道 3,所以使用的函數是 TIM_OC3Init()。這裡的結構體我就不多少了,自己看一下就可以明白,對於普通定時器我們只需要設置下面這四個參數就可以了。
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 500;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //根據TIM_OCInitStruct中指定的參數初始化外設TIMx
③配置佔空比:佔空比=配置佔空比的值/TIM_TImeBaseStructure.TIM_Period,這裡的佔空比為50/100=50%
50%的佔空比那麼波形也一定是一半高一半低對吧,一會我們仿真看一看。
4使能TIM3所有的都配置完了,最後能一下TIM3。
TIM_Cmd(TIM3, ENABLE);//使能TIM3
使能TIM3在CCR3上的預裝載寄存器
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); ////使能TIM3在CCR3上的預裝載寄存器,即TIM3_CCR3的預裝載值在更新事件到來時才能被傳送至當前寄存器中。
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM3在ARR上的預裝載寄存器 (影子寄存器)
這裡我們來講一下影子寄存器:
1.有影子寄存器的有3個:分頻寄存器PSC,自動重裝載寄存器 ARR,自動捕獲CCRx(x是對應的通道),注意,PSC,ARR,CCRx不是影子寄存器,而是它們對應的"預裝載寄存器"
2、影子寄存器才是真正起作用的寄存器,但是ST沒有提供這個寄存器出來,只是提供出與之相對應的預裝載寄存器,分別為"PSC,ARR,CCRx"
3、我們用戶能接觸到,能修改或讀取的都是預裝載寄存器,ST只是把它們開放出來(影子寄存器並沒有開放給用戶),其實就是ARR寄存器,如:TIM3->ARR
4、從預裝載寄存器ARR傳送到影子寄存器,有兩種方式,一種是立刻更新,一種是等觸發事件之後更新;這兩種方式主要取決於寄存器TIMx->CR1中的"APRE"位;
APRE=0,當ARR值被修改時,同時馬上更新影子寄存器的值;APRE=1,當ARR值被修改時,必須在下一次事件發生後才能更新影子寄存器的值;
5、怎麼樣馬上立刻更改影子寄存器的值,而不是下一個事件;方法如下:
將ARPE=0,TIM_ARRPreloadConfig(TIM3, DISABLE);
在ARPE=1,TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_ARRPreloadConfig設置為DISABLE 和ENABLE的問題,他的作用只是允許或禁止在定時器工作時向ARR的緩衝器中寫入新值,以便在更新事件發生時載入覆蓋以前的值。在開始初始化的時候你已經把
TIM_TimeBaseStructure.TIM_Period=100; (ARR的值),後來也一直是這個值,原因是你沒有編寫中斷服務函數或者你在中斷服務函數中根本就沒有給ARR緩衝器重新寫入新值,所以設置為DISABLE 和ENABLE都沒有影響,但是最保險的方法就是使能一下。匯總一下代碼:void TIM3_PWM_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);//使能GPIO外設時鐘
//設置該引腳為復用輸出功能,輸出TIM3 CH3的PWM脈衝波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM3_CH3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 100; //輸出PWM波形的頻率=定時器的輸入頻率/TIM_TImeBaseStructure.TIM_Period,200 000Hz/100=2000Hz,即0.5ms一個周期
TIM_TimeBaseStructure.TIM_Prescaler =360-1;//不分頻 輸入頻率=APB1時鐘/(預分頻係數+1)=72 000 000Hz/360=200 000Hz =200K
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_Pulse = 50; //佔空比=配置佔空比的值/TIM_TImeBaseStructure.TIM_Period,500/1000=50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //CH3預裝載使能
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM3在ARR上的預裝載寄存器 (影子寄存器)
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
主函數就很簡單,一個while函數就可以解決。
int main(void)
{
SystemInit ();
TIM3_PWM_Init();
while(1)
{
}
}
TB6612引腳分配:
VM PWMA---->TIM3_CH3(PBO)
VCC AIN2---->GPIOB_12
GND AIN1---->GPIOB_13
AO1 STBY---->GPIOB_14
AO2 BIN1---->GPIOB_15
BO2 BIN2---->GPIOA_12
BO1 PWMB---->TIM3_CH4(PB1)
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
int main(void)
{
u16 i=0;
SystemInit ();
TIM3_PWM_Init();
while(1)
{
i++;
TIM_SetCompare3(TIM3,i);//定時器3的通道3
if(i==100) i=0;
}
}