我用F5438A定时器B输出50HZ的PWM波,并用P2.6和P2.7外接两个按键,在外部中断中增加/减少TBCCR2的值来调节PWM波的占空比,如果按键不按下去在示波器上观察SMCLK是正常的16M,按键按了大概前5次左右是能正常调节占空比的,但再按按键示波器上就能观察到时钟变成了26-28M左右,而且这时候外部中断也进不去了,同样PWM波的周期和正脉宽受时钟影响也变大了,并且无法调节。求大神解答!以下是程序代码:
#include<msp430f5438a.h>
unsigned int s=3000; //s存放将要改变的TBCCR2的值,并将它赋值给TBCCR2
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
P1DIR = BIT0+BIT1; //P1.0和P1.1设置为输出,点亮两个LED
/*-------有关端口中断的设置--------*/
P2OUT = BIT6+BIT7;
P2REN = BIT6+BIT7; //因为按键另一端接地了,所以P2.6 P2.7输入端口要上拉
P2IES = BIT6+BIT7; //中断触发边沿为下降沿
P2IFG &= ~(BIT6 + BIT7);
P2IE = BIT6+BIT7; //中断打开
/*-------有关时钟系统的设置--------*/
P5SEL = BIT3 + BIT2;
P7SEL = BIT0 + BIT1; //晶振输入端口为第二功能
UCSCTL6 &= ~0x8000u; //XT2驱动能力设为8-16MHZ
UCSCTL6 &= ~(XT1OFF + XT2OFF ); //打开XT1和XT2
__bis_SR_register(SCG0);
UCSCTL3 = SELREF__XT2CLK; //DCO的参考时钟源为XT2CLK(8MHz)
UCSCTL1 = DCORSEL_5;
UCSCTL2 = 1; //DCOCLKDIV=MCLK=SMCLK=2*8=16MHz
__bic_SR_register(SCG0);
do
{
UCSCTL7 &= ~(XT2OFFG + XT1HFOFFG+ XT1LFOFFG + DCOFFG);
SFRIFG1 &= ~OFIFG;
}while(SFRIFG1 & OFIFG); //等待时钟系统稳定
P11DIR = BIT0+BIT1+BIT2;
P11SEL = BIT0+BIT1+BIT2; //设置ACLK,MCLK,SMCLK的端口输出
/*-------有关定时器的设置--------*/
P4DIR = BIT2;
P4SEL = BIT2; //设置P4.2为第二功能,即TB0.2的输出
TB0CCR0=40000; //决定输出PWM波的周期
TB0CCR2=3000; //范围为1000-5000,决定输出PWM波的占空比
TB0CCTL2 = OUTMOD_7;
TB0CTL = ID_3 + TBSSEL__SMCLK + MC__UP + TBCLR; //默认16位计数值,8分频,SMCLK,上升计数,清零
_EINT(); //打开总中断
LPM0; //进入低功耗模式0 }
/*-------PORT2的中断函数--------*/
#pragma vector=PORT2_VECTOR
__interrupt void aaaa(void)
{
__delay_cycles(4000000); //按键消抖,貌似按键抖动的时间比较长,所以延时也比较长
if(P2IFG & BIT6) //如果是P2.6触发中断
{
s+=200;
if(s>5000)
s=5000;
else
TBCCR2=s; //改变TBCCR2的值
P1OUT |=BIT1;
__delay_cycles(4000000);
P1OUT &=~BIT1; //点亮LED示意
P2IFG &= ~BIT6; //清除中断标志位
}
if(P2IFG & BIT7) //如果是P2.7触发中断
{
s-=200;
if(s<1000)
s=1000;
else
TBCCR2=s; //改变TBCCR2的值
P1OUT |=BIT0;
__delay_cycles(4000000);
P1OUT &=~BIT0; //点亮LED示意
P2IFG &= ~BIT7; //清除中断标志位
}
}