完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
各位大侠好: 小弟编写了一个测量频率的程序,TC1 工作在普通计数模式,用于记录外部输入的脉冲数,TC2 工作在比较定时模式,定时时间为20ms ,主程序每隔2s钟测量一次。可是测量时,发现当程序一运行“tiMSK |= BIT(OCIE2); ”就立马进入 TC2 的中断服务程序,中断服务程序做完了才返回,然后我在“TIMSK |= BIT(OCIE2); ”前加了一句“TIFR |= BIT(OCF2);”程序能正常走不是立即进入中断服务程序,但是测量值大约是实际值的三分之一。这边小弟不理解为什么要加“TIFR |= BIT(OCF2);”,而且测量值怎么会偏低这么多,麻烦各位大侠帮我看一下,谢谢! 程序: #include #include #include #include #include #define uint unsigned int #define ulint unsigned long int #define uchar unsigned char #define Led_ON PORTB &= ~BIT(PB1) #define Led_OFF PORTB |= BIT(PB1) #define Beep_ON PORTB |= BIT(PB2) #define Beep_OFF PORTB &= ~BIT(PB2) #define S0_ON PORTC |= BIT(PC0) #define S0_OFF PORTC &= ~BIT(PC0) #define S1_ON PORTC |= BIT(PC1) #define S1_OFF PORTC &= ~BIT(PC1) #define S2_ON PORTC |= BIT(PC2) #define S2_OFF PORTC &= ~BIT(PC2) #define S3_ON PORTC |= BIT(PC3) #define S3_OFF PORTC &= ~BIT(PC3) #define OE_ON PORTD |= BIT(PD6) #define OE_OFF PORTD &= ~BIT(PD6) void Init(); void InitUART(); void InitTC1(); void InitTC2(); void InitINT0(); void delayms(uint z); void Receive(uchar rbuf); void SendChar(uchar TempBuf); void SendString(const uchar *AddressPointer); void AnalysisCommand(); void DisposeValue(ulint temp_data); void ShowValue(uchar *p , signed char j); void TestRed(); void TestBlue(); void TestGreen(); void TestClear(); void TestAll(); ulint count = 0 ; uchar TimerONFlag ; uchar ConvertFlag ; uchar TestAllFlag ; const uchar waittime=10; const uchar CommandPrompt[]={"Command error , please check ! "}; struct { uchar index ; uchar index_end; uchar r_flag_end1; uchar r_flag_end2; uchar comm_infor[20]; } Receive_command={0,19,0,0,{0}}; void main() { Init(); delayms(2000); SendString("Color Test ! r"); SendString("Begin ..."); SendChar('r'); while(1) { TestRed(); delayms(2000); } } void Init() { DDRD &= ~BIT(PD0) ; // set PD0 , as input RXD DDRD &= ~BIT(PD5); // set PD5 , as input TC1 DDRD |= BIT(PD1)+ BIT(PD6); // set PD1, PD6(OE) as output TXD DDRB |= BIT(PB1) + BIT(PB2) ; // set PB1 , PB2 as output DDRC |= BIT(PC0) + BIT(PC1) + BIT(PC2) + BIT(PC3) + BIT(PC4) + BIT(PC5) ; // PC0--PC5,(S0--S3) as output TimerONFlag=0 ; // not open Timer , test CLI(); InitUART(); InitTC1(); InitTC2(); // InitINT0(); S0_ON; // 100% output S1_ON; SEI(); // open global interrupt } void InitUART() { UCSRA = 0X00 ; UCSRB = 0X00 ; UCSRC = 0X00 ; // control register clear UCSRA |= BIT(UDRE) ; // data buf empty , could receive data UCSRB |= BIT(RXCIE) + BIT(RXEN) + BIT(TXEN); // enable RXB interrupt UCSRC |= BIT(URSEL) + BIT(UCSZ1)+ BIT(UCSZ0); // SET 1 UBRR=0x2F; // Baud 9600 7.3728 Mhz U2X = 0 } void InitTC1() { TCCR1A &= ~BIT(WGM11) + ~BIT(WGM10); TCCR1B &= ~BIT(WGM12) + ~BIT(WGM13); // usual mode TCCR1B &= ~BIT(CS12) + ~BIT(CS11) + ~BIT(CS10); // unable TC1 TCNT1 = 0X00 ; // clear TCNT1 } void InitTC2() { TCCR2 &= ~BIT(WGM20); TCCR2 |= BIT(WGM21) + BIT(CS22) + BIT(CS21) + BIT(CS20); // 1024 divide frequency , CTC mode TCNT2 = 0X00; // clear TCNT2 OCR2 = 0X8F; // 20ms } /*void InitINT0() { // MCUCR |= BIT(ISC01) + BIT(ISC00) ; // INT0 rise edge trigger MCUCR |= BIT(ISC01) ; MCUCR &= ~BIT(ISC00); }*/ void TestRed() { S2_OFF; S3_OFF; OE_OFF; delayms(waittime); ConvertFlag=0; SendString("R :"); TCNT1 = 0X00 ; TIFR |= BIT(OCF2); // for test TIMSK |= BIT(OCIE2); // enable TC2COMP TCCR1B |= BIT(CS12) + BIT(CS11) + BIT(CS10); // rise edge trigger counter while(ConvertFlag==0); DisposeValue(count); } /*void TestBlue() { S2_OFF; S3_ON; OE_OFF; delayms(waittime); ConvertFlag=0; SendString("B :"); GICR |= BIT(INT0); // enable INT0 } void TestGreen() { S2_ON; S3_ON; OE_OFF; delayms(waittime); ConvertFlag=0; SendString("G :"); GICR |= BIT(INT0); // enable INT0 } void TestClear() { S2_ON; S3_OFF; OE_OFF; delayms(waittime); ConvertFlag=0; SendString("I :"); GICR |= BIT(INT0); // enable INT0 } void TestAll() { TestRed(); while(ConvertFlag==0); TestGreen(); while(ConvertFlag==0); TestBlue(); while(ConvertFlag==0); TestClear(); while(ConvertFlag==0); }*/ void SendChar(uchar TempBuf) { UCSRB &= ~BIT(RXCIE) ; // unable RXB interrupt UDR = TempBuf ; while((UCSRA & BIT(TXC))==0); UCSRA &= ~BIT(TXC) ; // clear flag bit UCSRB |= BIT(RXCIE) ; // enable RXB interrupt } void SendString(const uchar *AddressPointer) { UCSRB &= ~BIT(RXCIE); // unable RXB interrupt while(' |