1 利用單片機輸出pwm波,實驗中要求改變pwm波的頻率,我們通過調用 TIM_SetAutoreload(TIM4,(9000000/fre));函數來實現
但是調用 TIM_SetAutoreload(TIM4,(9000000/fre));會導致單片機重啟,原本的函數是這樣的:
1 if(cc1101_RxBuf_tmp[2] == tmp[0] && cc1101_RxBuf_tmp[3] == tmp[1] &&\ 2 cc1101_RxBuf_tmp[4] == tmp[2] && cc1101_RxBuf_tmp[5] == tmp[3])//發來的報警和設備管家存的報警ID一置 3 { 4 if( beep_volume != 0) 5 { 6 /* 7 出廠后Beep_Voice_Type默認被置成 1 8 beep_volume != 0 表示當前不是處於靜音狀態 9 */ 10 /* 11 1 通過改變計數初值從而改變PWM波的頻率 12 2 f為PWM波的頻率 13 */ 14 15 16 BEEP_enable();//有打開定時器中斷的功能 17 } 18 19 fre = 500;//PWM波的頻率 20 TIM_SetAutoreload(TIM4,(9000000/fre));//控制頻率,通過改變計數初值從而改變PWM波的頻率 21 TIM_SetCompare1(TIM4,((9000*Beep1[beep_volume]/fre)));//控制占空比 Beep[beep_volume] 22 beep_switch = 1;//開報警 23 24 25 上面這個是觸發中斷函數 26 27 28 void TIM4_IRQHandler(void) 29 { 30 if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) 31 { 32 /***************報警時的處理**************/ 33 if(beep_switch == 1)//beep_switch會在收到報警時被置1 34 { 35 /* 36 由於在這個過程中,定時器的時間會發送改變,超時計時放在這就會導致時間不准確,所以 37 超時計時還是放在定時器3中完成 38 */ 39 if((fre<500) || (fre>=3300)) 40 { 41 fre=500; 42 } 43 44 if(fre<780) 45 { 46 fre=fre+10; 47 } 48 else if(fre<1100) 49 { 50 fre=fre+20; 51 } 52 else if(fre<3300) 53 { 54 fre=fre+100; 55 } 56 TIM_SetAutoreload(TIM4,(9000000/fre));//控制頻率,通過改變計數初值從而改變PWM波的頻率 57 TIM_SetCompare1(TIM4,((9000*Beep1[beep_volume])/fre));//控制占空比 Beep[beep_volume] 58 59 } 60 61 TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); 62 } 63 } 64 這個是中斷函數
分析原因:
通過BEEP_enable()函數,有打開定時器中斷的功能,在之前就已經有了一個計數重裝載值,這個值很小,所以在
TIM_SetAutoreload(TIM4,(9000000/fre));執行到一般就進中斷,進中斷又對這個函數進行配置
所以導致單片機重啟,應該做以下修改。
1 if( beep_volume != 0) 2 { 3 /* 4 出廠后Beep_Voice_Type默認被置成 1 5 beep_volume != 0 表示當前不是處於靜音狀態 6 */ 7 /* 8 1 通過改變計數初值從而改變PWM波的頻率 9 2 f為PWM波的頻率 10 */ 11 fre = 500;//PWM波的頻率 12 TIM_SetAutoreload(TIM4,(9000000/fre));//控制頻率,通過改變計數初值從而改變PWM波的頻率 13 TIM_SetCompare1(TIM4,((9000*Beep1[beep_volume]/fre)));//控制占空比 Beep[beep_volume] 14 15 BEEP_enable(); 16 } 17
先確定好計數重裝載值,再打開中斷,這樣就不會重啟了