__interrupt void port_ISR( ) { i++; //计时因子自增 if(i==3000) //1s改变发光二极管状态一次 { c++; i=0; } P1IFG&=~(BIT5); //清中断标志 } (选做) 如果要每隔10 秒蜂鸣器响一声,如何在任务6 的基础上编程实现?
实现方法:和任务六的第二个选作任务一样,再增加一个计时因子即可。具体代码如下: #include \#include \void delay1() { unsigned int q; for(q=0;q<0xff;q++); } void delay2() //延时函数 { unsigned int d; for(d=0;d<0xffff;d++); } void buzz() //蜂鸣器响一声 { P1OUT&=~BIT7; delay2(); P1OUT|=BIT7; } unsigned int i=0,c=0,k=0,a1,a2,a3,a4; unsigned char LED[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //LED灯 int main ( void ) { WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 _DINT(); //关闭中断允许 P1IE &=~BIT5; P1SEL&=~(BIT1+BIT2+BIT3+BIT4); P1SEL2&=~(BIT1+BIT2+BIT3+BIT4); P1DIR|=BIT1+BIT2+BIT3+BIT4; P1OUT&=~(BIT1+BIT2+BIT3+BIT4); //设置端口P2.0~P2.7为输出 P2SEL=0; P2SEL2=0; P2OUT=0xff; P2DIR=0xff; //设置P1.7为输出 P1SEL&=~BIT7; P1SEL2&=~BIT7; P1OUT|=BIT7; P1DIR|=BIT7; //设置端口P1.5允许中断 P1SEL &=~BIT5; P1SEL2 &=~BIT5; P1REN |=BIT5; P1OUT |=BIT5; P1DIR &=~BIT5; P1IES |=BIT5; P1IFG &=~BIT5; P1IE |=BIT5; _EINT(); //P1.0输出时钟3KHzACLK P1SEL|=BIT0; P1SEL2&=~BIT0; P1DIR|=BIT0; BCSCTL1|=DIVA_2; //设置ACLK时钟源为VLOCLK,并为4分频 BCSCTL3|=LFXT1S_2; while(1) { a1=c/600; a2=(c-600*a1)/60; a3=(c-600*a1-60*a2)/10; a4=c-600*a1-60*a2-10*a3; P2OUT=LED[a4]; //控制第一个数码管显示的数字 P1OUT|=BIT4; P1OUT&=~(BIT1+BIT2+BIT3); delay1(); P2OUT=LED[a3]; //控制第二个数码管显示的数字 P1OUT|=BIT1; P1OUT&=~(BIT2+BIT3+BIT4); delay1(); P2OUT=LED[a2]; //控制第三个数码管显示的数字 P1OUT|=BIT2; P1OUT&=~(BIT1+BIT3+BIT4); delay1(); P2OUT=LED[a1]; //控制第四个数码管显示的数字 P1OUT|=BIT3; P1OUT&=~(BIT1+BIT2+BIT4); delay1(); } } #pragma vector=PORT1_VECTOR __interrupt void port_ISR( ) { i++; //计时因子自增 k++; //计时因子自增 if(i==3000) //1s改变发光二极管状态一次 { c++; i=0; } if(k==30000) //10s蜂鸣器响一声 { buzz(); k=0; } P1IFG&=~(BIT5); //清中断标志 } 思考:中断程序要尽可能的简洁,最好能只处理一些关键程序,如果此题中将控制数码管显示的程序放在中断程序中,则可能导致中断程序执行时间超出预期,秒表将会产生严重误差。 思考2:经过与标准秒表对比,此种方式设置的秒表仍存在一定误差,原因猜测是VLOCLK是由片内低功耗低频振荡器控制的,受环境温度和工作电压影响较大,因此测量值和理论值相差较大。