|
最近再做一個帶藍牙接口的血壓計項目,項目中使用了STM32F10364引腳的MCU,在硬件設計中,因為外設較多,導致每個通用定時器至少有兩個PWM輸出引腳被占用,現(xiàn)在要控制RGB燈,只能用一個普通IO引腳模擬PWM輸出。
相關的硬件電路設置如下:
GPIOA1------------------------------RGBBLUE燈
GPIOB1------------------------------RGBGREEN燈
GPIOD2------------------------------RGBRED燈
RGB燈采用了共陽極電路,所以在PWM的輸出急性設置時,將極性設置為高電平,定時器的初始化如下圖所示:
void initLedTimer( void ){
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_DeInit( TIM2 );
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure );
TIM_TimeBaseStructure.TIM_Period =TIMER_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler =TIMER_PRESCALER;
TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; // 不分頻
TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure );
TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse =DEFAULT_DUTY_CYCLE;
TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;
//
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
//
TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Enable);
//
TIM_OC2Init(TIM2,&TIM_OCInitStructure);
//
TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Enable);
//
TIM_OC3Init(TIM3,&TIM_OCInitStructure);
//
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
//
TIM_OC4Init(TIM3,&TIM_OCInitStructure);
//
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
//
TIM_OCStructInit(&TIM_OCInitStructure );
TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_Pulse =DEFAULT_DUTY_CYCLE;
//
TIM_OC2Init(TIM3,&TIM_OCInitStructure);
//
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
// ARR重裝載使能
TIM_ARRPreloadConfig(TIM2,ENABLE);
TIM_ARRPreloadConfig(TIM3,ENABLE);
//
TIM_ClearITPendingBit( TIM2,TIM_IT_Update );
TIM_ClearITPendingBit( TIM3,TIM_IT_Update | TIM_IT_CC2 );
//定時器2和3中斷使能
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_ITConfig(TIM3,TIM_IT_Update |TIM_IT_CC2, ENABLE);
}
輸出極性為高電平的意思就是說,假如說占空比為20%,那么他表示,低電平占整個周期20%的時間,反之如果設置極性為低電平,那么表示高電平占用整個周期的20%。
如何用GPIOD2模擬PWM波形呢? 關鍵的地方就是同時必須使用定時器中斷
如下圖所示:在使能某個PWM中斷的同時,使能定時器中斷,這樣定時器在T1時刻產生溢出中斷,PWM在t1+t2時刻產生比較中斷。在產生溢出中斷時,將GPIO引腳置為高電平,在產生比較中斷時,將引腳置為低電平。例程如下圖所示:
void TIM3_IRQHandler( void )
{
if(TIM3->SR & TIM_SR_CC2IF )
{//產生溢出中斷
if( effectFlag & BREATH_FLAG_D2 )
{
GPIOD->BRR =GPIO_Pin_2;//引腳置為低電平
}
// Clearthe pending Bit
TIM3->SR = ~TIM_SR_CC2IF;
}
if(TIM3->SR & TIM_SR_UIF )
{//產生比較中斷
// Clear the pending Bit
TIM3->SR = ~TIM_SR_UIF;
if(GPIOD2_FLAG& effectFlag )
{
// 灝嗗紩鑴氱疆涓洪珮鐢靛鉤
GPIOD->BRR =GPIO_Pin_2;
}
//濡傛灉timer3 涓嶅啀浣跨敤,鍒欏叧闂?
if( 0 == ( TIM3->CCER & (TIM_CCER_CC3E | TIM_CCER_CC4E | TIM_CCER_CC2E ) ) ){
// 鍏抽棴timer3
TIM3->CR1 &= ~TIM_CR1_CEN;
// 鍏抽棴鏃墮挓
RCC->APB1ENR &=~RCC_APB1RSTR_TIM3RST;
}
}
}
這種做法是在資源不足的情況下使用的,在將占空比設置為0或者設置為100%時,定時器的溢出中斷和PWM的比較中斷重合,這個時候,用GPIOD2驅動led,就會發(fā)現(xiàn)led燈都是亮點,因為中斷重合,在將占空比設置為0時,定時器的溢出中斷進不去,所以無法將引腳置為低電平,所以燈一直是亮點。處理的方法時,判斷當發(fā)現(xiàn)占空比為0時,?直接將GPIOD2引腳置為高電平,同時使effectFlag的GPIOD2_FLAG位為0.
|
|