I am using an ATmega328P MCU with an 16 MHz external oscillator. I need to measure distance of Ultrasonic Sensor HC-SR04 using the ATmega328P Timer 1 Input Capture interrupt. I have to measure the Echo pulse time between the rising and falling edges. Then send the calculated distance via UART. I tried to simulate on Proteus, but it doesn't work. Can anybody give me some direction how to do it? . I'm using the CodeVisionAVR IDE. Here's my code:
#include <mega328p.h> #include <stdio.h> #include <delay.h> #define Trigger PORTB.0 #define Echo PINB.1 // Declare your global variables here unsigned int distance; unsigned long echoStart, echoEnd, time; void setup() { DDRB = (0<<DDB1) | (1<<DDB0); DDRC = (1<<DDC2) | (1<<DDC0); //Timer 1 initialization TCCR1A = 0; TCCR1B = (1 << ICES1) | (1 << CS10); //rising edge, no prescaler TIFR1 = (1<<ICF1); TIMSK1 = (1 << ICIE1); } void initUSART() { // USART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: Off // USART Transmitter: On // USART0 Mode: Asynchronous // USART Baud Rate: 9600 UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0); UCSR0B=(0<<RXCIE0) | (1<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80); UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0); UBRR0H=0x00; UBRR0L=0x67; } interrupt [TIM1_CAPT] void timer1_capt_isr(void) { TCCR1B = 0x41; //Rising edge, no prescaler while((TIFR1&(1<<ICF1)) == 0); echoStart = (ICR1H << 8) | ICR1L; TIFR1 = (1<<ICF1); //Clear ICF flag TCCR1B = 0x01; //Falling edge, no prescaler while ((TIFR1&(1<<ICF1)) == 0); echoEnd = (ICR1H << 8) | ICR1L; //Take value of capture register TIFR1 = (1<<ICF1); // Clear ICF flag } void main() { setup(); initUSART(); // Global enable interrupts #asm("sei") while (1) { Trigger = 1; delay_us(10); Trigger = 0; time = echoEnd - echoStart; distance = time / 58; printf("Distance: %2d\r\n", distance); delay_ms(500); } }