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
先确定好计数重装载值,再打开中断,这样就不会重启了