Hallo Ihr Beiden
Folgende Sachen noch.
In der neuen WINAVR Version gibt es ein kleines Problem mit der Delay.h.
Also auf die maximale Zeit achten, oder selber eine Delay Schleife Proggen.The macro F_CPU is supposed to be defined to a
constant defining the CPU clock frequency (in Hertz).
The maximal possible delay is 768 us / F_CPU in MHz.
Beim eintreten eines ICP wird das Bit gesetzt und der Wert von Timer1 nach
ICR1 kopiert. Danach muss das Bit durch schreiben einer 0 zurückgesetzt
werden.
Code:#include <avr/io.h> #include <avr/delay.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <stdio.h> #include <delay.c> // das unterprogramm warte #include <stdint.h> #define USART_BAUD_RATE 19200 #define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1) #define US_PORT PORTD #define US_PORT_RICHTUNG DDRD #define US_PIN PD7 // Der Pin kommt zum Trigger-Puls Eingang void usart_init(void) { UCSRB = (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN); UBRRL = (unsigned char) USART_BAUD_SELECT; UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1 } void uart_putc(unsigned char c) // Ein zeichen { while(!(UCSRA & (1 << UDRE))) ; /* warte, bis UDR bereit */ UDR = c; /* sende Zeichen */ } void uart_puts(unsigned char *s) // mehrere Zeichen { while (*s) { /* so lange *s != NULL */ uart_putc(*s); s++; } } uint16_t start_messung(void) { uint16_t wert ; //wert_in_cm; Kann auch 300 sein wegen 300cm also reicht unit8 nicht US_PORT|=(1<<US_PIN); // Trigger-Puls auf high // PD6 ist Input Capture Pin beim ATMega8, hier kommt der Echo-Pulse Ausgang hin _delay_us(15); // Laut Datenblatt Trigger-Puls min 10us auf high US_PORT &=~(1<<US_PIN); // Trigger-Puls Eingang wieder auf low _delay_us(185); // Wartet nochmal !!!!!!!1 geht laut Simulator nicht richtig 95 µs werden angezeigt _delay_us(185); //mit 2 Delay kommt man auf 192µs, anpassen !!!!!!!!!!!!!!! TCCR1B &=~(1<<ICES1); // Fallende Flanke für Input Capture TCNT1 = 0; //hinzugefügt, Timer Wert löschen TCCR1B |= (1<<CS11);; // Prescaler 8, damit dauert ein Tackt 1 micro Sekunde, Timer startet while ( !(TIFR & (1<<ICF1 )) ) ; // Warten bis Echo-Puls Ausgang auf low --> Messung beendet, ICF1 ist dann gesetzt if(ICF1>19000) //kein Objekt vor dem Sensor, eigentlich schon wenn größer 18ms laut Datenblatt { wert=0; TCCR1B &= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus TIFR |=(1<<ICF1); // ICF1 Bit wieder löschen durch schreiben einer logischen 1 return wert; // Raus aus der Funktion } else { wert=172*ICR1/10000; // wert ist nun in cm TIFR &= ~(1<<ICF1); // ICF1 Bit wieder löschen durch schreiben einer logischen 0 geändert TCCR1B &= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus return wert; } } int main (void) { US_PORT_RICHTUNG|=(1<<US_PIN); // US_PIN auf Ausgang char s[3]; uint16_t wert_1; usart_init(); for (;;) { wert_1=start_messung(); sprintf(s,"%u",&wert_1); usart_puts(s); usart_puts("\n\r"); warte(20000); } }
Das starten oder stoppen des Timers hat keinen Einfluß auf den Timerwert
in TCNT1. Also vorher löschen oder einlesen und nachher in die Berechnung einfliessen lassen.
MFG
Dieter







Zitieren

Lesezeichen