热度 15
2012-11-4 15:05
2271 次阅读|
0 个评论
AVRstudio6下写的,IDE自带GCC。使用Timer1的输入捕获,晶振8M. #include stdio.h #define F_CPU 8000000 #include util/delay.h #include avr/io.h #include avr/iom128.h #include avr/interrupt.h //中断信号头文件 #define LED PORTE //数据口 #define LEDDDR DDRE //数据口方向寄存器 #define PORT_DATA PORTC #define PORT_SEL PORTA #define DDR_DATA DDRC #define DDR_SEL DDRA #define DDR_WAVE_TRIG DDRD #define DDR_WAVE_ECHO DDRD #define PORT_WAVE_TRIG PORTD #define PORT_WAVE_ECHO PORTD #define PIN__WAVE_TRIG PIND #define PIN__WAVE_ECHO PIND #define TRIG PD6 #define ECHO PD4 #define delay_us(x) _delay_us(x) //AVR GCC延时函数 x(us) #define delay_ms(x) _delay_ms(x) //AVR GCC延时函数 x(ms) #define uchar unsigned char #define uint unsigned int #define ulong unsigned long volatile ulong ov_counter=0; volatile uint rising_edge,falling_edge; volatile ulong pulse_clocks = 1000;//高电平宽度 volatile uint temp; const char Table ={0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f}; char Date ={1,2,3,4}; void Display(char *p) { char i,sel=0x01; for(i=0;i4;i++) { PORT_SEL = sel; // 1 表示选通 PORT_DATA = ~Table ]; if(i == 0) PORT_DATA = ~(17); delay_ms(2); PORT_DATA= 0xFF ; sel= sel1; } } void Io_Init(Void) { DDR_DATA = 0xFF; PORT_DATA = 0x00; DDR_SEL = 0x0F; PORT_SEL = 0x0F; DDR_WAVE_ECHO = ~(1ECHO);//ECHO设输入 ,ICP1 DDR_WAVE_TRIG |= (1TRIG);// 触发脉冲设输出 PORT_WAVE_ECHO = ~(1ECHO);//ECHO和TRIG均初始化为0 PORT_WAVE_TRIG = ~(1TRIG); LEDDDR |= 0XFF; LED = 0xFF; } void Initial_Timer(void) { TCCR1B = 0; TCCR1A = 0x00; TCCR1B = (1ICNC1)|(1ICES1)|(1CS11);//8, 上升沿触发 TIMSK |= (1TICIE1)|(1TOIE1);//使能ICP捕捉中断,溢出中断 } /* (count * div)/8M * 340/2 m (count * div)/8M * 340/2 *1000 mm count*8/8000000 * 170*1000 = count*17/100 mm ; */ void Calc_Distance( char* p) { volatile unsigned long TN = 0; TN = (falling_edge*17/100);// 单位为mm p = TN/1000; p = (TN % 1000)/100; p = (TN % 100)/10; p = TN % 10; } void GenerateTrig(void) { PORT_WAVE_TRIG |= (1TRIG); delay_us(30); PORT_WAVE_TRIG = ~(1TRIG); } /* void main() { unsigned int count = 0; Io_Init(); Initial_Timer(); //asm("SEI"); //打开全局中断 while(1) { GenerateTrig(); while(!(PIN__WAVE_ECHO (1 ECHO))) // wait for echo raising {;} TCNT1H = 0; TCNT1L = 0; while((PIN__WAVE_ECHO (1 ECHO))) // wait for echo falling {;} falling_edge = TCNT1L; temp = TCNT1H; falling_edge |= temp8; Calc_Distance(Date); Display(Date); Display(Date); } } */ void main() { unsigned int count = 0; Io_Init(); Initial_Timer(); asm("SEI"); //打开全局中断 while(1) { Calc_Distance(Date); count++; if(count 100)//产生一次Trig { count = 0; GenerateTrig(); } Display(Date); } } ISR(TIMER1_OVF_vect) { ov_counter++; } ISR(TIMER1_CAPT_vect) { if(PIN__WAVE_ECHO (1 ECHO)) //上升沿 { TCNT1H = 0; TCNT1L = 0; TCCR1B = ~(1ICES1); //改为下降沿中断 ov_counter=0; LED ^= (1PE7); LED |= ~((1PE7)|(1PE6)); } else //下降沿 { falling_edge = ICR1L; temp = ICR1H; falling_edge |= temp8; TCCR1B |= (1ICES1); LED ^= (1PE6); LED |= ~((1PE7)|(1PE6)); } } /* ISR(TIMER1_CAPT_vect) { if(PIN__WAVE_ECHO (1 ECHO)) //上升沿 { rising_edge = ICR1L; temp = ICR1H; rising_edge |= temp8; TCCR1B = ~(1ICES1); //改为下降沿中断 ov_counter=0; LED ^= (1PE7); LED |= ~((1PE7)|(1PE6)); } else //下降沿 { falling_edge = ICR1L; temp = ICR1H; falling_edge |= temp8; TCCR1B |= (1ICES1); pulse_clocks = (ulong)falling_edge - (ulong)rising_edge + (ulong)ov_counter*0x10000; LED ^= (1PE6); LED |= ~((1PE7)|(1PE6)); } } */