Hallo Ihr Beiden
Ja ich weiß das das da steht, stimmt aber nicht so ganz. Atmel hat da eine eigene Auslegung. Schau dir doch mal die Fuse Bits an, ist doch je nach Progger genau so.Und Dino Dieter im Datenblatt vom ATmega32 steht doch ausdrücklich das man das Bit durch schreiben einer logischen 1 löscht?!
Gruß Muraad
Schade das du meinen Rat nicht angenommen hast. Das geht in die Hose.TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus
Hier mal meine Version von der Software
Ablauf: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++; } } // PD6 ist Input Capture Pin beim ATMega8, hier kommt der Echo-Pulse Ausgang hin uint16_t start_messung(void) { uint16_t wert = 0 ; //wert_in_cm; //Timer vorbereiten TCCR1B &=~(1<<ICES1); // Fallende Flanke für Input Capture TCNT1 = 0; // Timer1 löschen US_PORT|=(1<<US_PIN); // Trigger-Puls auf high _delay_us(11); // Laut Datenblatt Trigger-Puls min 10us auf high US_PORT &=~(1<<US_PIN); // Trigger-Puls Eingang wieder auf low while ( !(PIND & (1<<PD6))); //warten bis der Echo Impuls anfängt TCCR1B |= (1<<CS11); // Prescaler 8, damit dauert ein Tackt 1 micro Sekunde, Timer startet while ( !(TIFR & (1<<ICF1))); // Warten bis Input Capture Flag gesetzt ---> Echo-Eingang ist low if(ICR1 < 20000) // gültiger Bereich (max 18 ms + Reserve ) wert= (unsigned int) (ICR1 / 58); //umrechnen in cm (laut Datenblatt ) TCCR1B &= ~(1<<CS11); // Timer wieder aus TIFR &= ~(1<<ICF1); // ICF1 Bit wieder löschen durch schreiben einer logischen 0 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(); //bei Rückgabe 0 ungültige Messung sprintf(s,"%u",&wert_1); usart_puts(s); usart_puts("\n\r"); warte(20000); } }
Trigger Impuls ausgeben ( 11 µs)
warten bis der Echo Impuls auf High geht
Timer starten
warten bis ICF1 high ist
Abfrage ob gültiger Bereich
Umrechnen
und Ende
Ich erwarte einen Impuls zwischen 100 µs und 18 mS, laut Datenblatt.
Werte über 20 ms sind ungültig.
Wenn es immer noch nicht klappt, folgende Zeile
if(ICR1 < 20000) // gültiger Bereich (max 18 ms + Reserve )
mal löschen und sehen was dann rauskommt.
Diese Zeile bringt immer eine Fehlermeldung wegen USR. Kennt der mega 16 nicht. ???????while(!(USR & (1 << UDRE))) asm volatile("NOP"); /* warte, bis UDR bereit */
MFG
Dieter
Lesezeichen