完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我最近在做一个案子,就是利用TCS3200 检测 LED 的颜色,TCS3200 检测到不同的颜色会输出不同的频率,也就利用单片的做一个检测频率的程序,我已经利用51单片机初步实现频率检测的程序,但是51能检测的最大频率为:30~40 KHz,不能满足更高 频率的测量要求,所以我就选用 AVR 单片机(ATMEGA8L)来做,算法也是参照51写的,一个测量过程的算法是这样:配置 AVR 单片的 INTO 的中断方式为上升沿触发,中断程序中有个计数器,第一次触发时,打开定时器1(定时器1用的是16位的计数方式)开始 50ms 的定时, 中断每触发一次,计数器加1,直到50ms定时中断到了,关闭 INT0 和定时器1 ,然后调用数据处理函数,根据计数器的值算出检测到的频率值。可是 AVR 单片机在运行的时候程序好像跑飞了一样,一个测量过程,定时器1好像中断了好几次,我分析了一下,应该是中断嵌套的时候出错了,我做了一些修正算法,但是程序还是不能正常的运行测量。我附上我写的程序,请各位达人,帮我看看,谢谢啦! #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) // low effectiv #define OE_ON PORTD |= BIT(PD6) #define OE_OFF PORTD &= ~BIT(PD6) void Init(); void InitUART(); void InitTC1(); 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=15; 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(); while(ConvertFlag==0); delayms(2000); } } void Init() { DDRD &= ~BIT(PD0) + ~BIT(PD2) ; // set PD0, PD2 as input RXD ,INT0 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 CLI(); // clear global interrupt InitUART(); InitTC1(); InitINT0(); S0_ON; // 100% output S1_ON; SEI(); // set 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) + ~BIT(CS10) + ~BIT(CS12) ; TCCR1B |= BIT(CS11); // 8 divide frequency , usual mode TCNT1 = 0X4BFF ; // 50ms } void InitINT0() { MCUCR |= BIT(ISC01) + BIT(ISC00) ; // INT0 rise edge trigger } void TestRed() { S2_OFF; S3_OFF; OE_OFF; delayms(waittime); ConvertFlag=0; SendString("R :"); GICR |= BIT(INT0); // enable INT0 } 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(' |