stm32f072--定時器17使用CH1N通道輸出pwm時沒有波形的原因

昨天剛寫了篇文章分析定時器pwm輸出初始化,以爲都懂了再用會很簡單,今天使用TIM17就出問題了— 。—

使用TIM17_CH1N對應引腳PB7,因爲之前用的定時器15也是CH1N,就直接把TIM15的初始化搬過來改成TIM17,結果TIM15是有波形輸出,而TIM17沒有任何輸出!!!真是奇怪了。。

void TIM17_PWM_Init(void)
{	
    uint16_t ChannelPulse = 0,PWM_TimerPeriod; 
    
	GPIO_InitTypeDef         GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef        TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;	
    //引腳初始化
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17 , ENABLE);  
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);//使能GPIOA時鐘和複用功能時鐘	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM2二通道PWM波形輸出端口PA1			 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//設置引腳爲推輓輸出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 	//設置引腳爲上拉		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//設置引腳速度爲50MHZ
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_2);	
    
    /* 
        系統時鐘48mhz,180us,週期10ms,48*1000*10 >65535,要分頻
    */
	PWM_TimerPeriod = (unsigned int)( 1000*25 ) - 1;
    ChannelPulse = (uint16_t) (((uint32_t) 45 * (PWM_TimerPeriod - 1)) / 100);//佔空比5%	
	/* Time 定時基礎設置*/
	TIM_TimeBaseStructure.TIM_Prescaler = 48-1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  /* Time 定時設置爲上升沿計算模式*/
	TIM_TimeBaseStructure.TIM_Period = PWM_TimerPeriod;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM17, &TIM_TimeBaseStructure);	
	TIM_ARRPreloadConfig(TIM17, ENABLE);
    
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;             //TIM脈衝寬度調製模式1
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //比較輸出使能
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;     //輸出極性:TIM輸出比較極性高	
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;//輸出空閒狀態
	TIM_OCInitStructure.TIM_Pulse =ChannelPulse;              
	TIM_OC1Init(TIM17, &TIM_OCInitStructure);          //根據TIM_OCInitStruct中指定的參數初始化外設TIMx
    
	TIM_OC1PreloadConfig(TIM17, TIM_OCPreload_Enable); //使能TIMx在CCR1上的預裝載寄存器
	TIM_Cmd(TIM17, ENABLE);
  /* TIM1 Main Output Enable */
  TIM_CtrlPWMOutputs(TIM17, ENABLE);
}

開始找原因:

先對比T15和T17寄存器值的區別,沒問題,再看手冊,T17的寄存器沒發現問題。。

試試修改參數,將有效脈衝由低改成高等改參數,沒有波形;

T17開中斷,中斷函數加一個輸出引腳的翻轉,量這個引腳是會翻轉,說明定時器計時沒問題;

試試CH1通道輸出pwm有沒有波形,將引腳改爲PB9,輸出有波形!!再將CH1N也加進來,都有波形了!!

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;             //TIM脈衝寬度調製模式1
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //比較輸出使能
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//TIM_OutputState_Enable
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;     //輸出極性:TIM輸出比較極性高	
    TIM_OCInitStructure.TIM_OCPolarity= TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState= TIM_OCIdleState_Reset;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;//輸出空閒狀態
	TIM_OCInitStructure.TIM_Pulse =ChannelPulse;               //1200設置待裝入捕獲比較寄存器的脈衝值,取值必須在0x0000~0xFFFF之間,佔空1200/2400
	TIM_OC1Init(TIM17, &TIM_OCInitStructure);          //根據TIM_OCInitStruct中指定的參數初始化外設TIMx

那就是CH1的參數影響CH1N了,將TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;

//TIM_OCInitStructure.TIM_OCPolarity= TIM_OCPolarity_High;隱掉這句,都沒影響,還是有波形,那就差

TIM_OCInitStructure.TIM_OCIdleState= TIM_OCIdleState_Reset;就是這句影響了,將這句隱掉後就跟一開始一樣,CH1N沒有波形!!

那就看看這句到底是怎麼影響的?

對比寄存器變化:

      (隱掉TIM_OCIdleState)                   (未隱掉TIM_OCIdleState)

看TIM_OCIdleState_Reset              ((uint16_t)0x0000)定義,並沒有涉及其他位,怎麼會有三位的值變化了,再看是不是不設置的話默認值不是0,仿真調試發現,沒有設置TIM_OCIdleState時默認成了0x0115,也就是CR2|=0X0115,這也就解釋了OIS1 (bit8)CCUS(bit2) CCPC(bit0)位都置1的原因了。

這個默認值0x0115是怎麼來的??(未解決)

繼續查是哪一位影響的:

將CCPC=0後有波形,

CCPC=1時沒有波形。所以這一位導致的沒有輸出,那看看這一位是幹什麼的:

僅在有互補輸出時起作用??(未解決)

TIM_OC1Init函數裏:雖然寫着assert_param檢查參數範圍,但是assert_param沒有起作用,因爲它的宏定義沒有開。所以TIM_OCIdleState的值超範圍了也沒報錯。

 

另外,TIM_OutputState,TIM_OCPolarity不設置使用默認值的話並不是0,雖然這個值沒有影響。。。

對了,這個問題對TIM15並沒有影響,TIM15的TIM_OCIdleState也是0x0115,但是它能有波形,奇怪不奇怪?

暫時的結論:

初始化設置完整一點,即使互補通道中只用一個通道,還是要將結構體TIM_OCInitStructure裏的參數都附一個值:

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;    //TIM脈衝寬度調製模式1
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;//
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //輸出極性:TIM輸出比較極性高	
TIM_OCInitStructure.TIM_OCPolarity= TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState= TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;//輸出空閒狀態TIM_OCInitStructure.TIM_Pulse =ChannelPulse;               
TIM_OC1Init(TIM17, &TIM_OCInitStructure); 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章