Hallo Ihr Beiden

Und Dino Dieter im Datenblatt vom ATmega32 steht doch ausdrücklich das man das Bit durch schreiben einer logischen 1 löscht?!
Gruß Muraad
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.


TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus
Schade das du meinen Rat nicht angenommen hast. Das geht in die Hose.

Hier mal meine Version von der Software

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);

    }
}
Ablauf:

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.


while(!(USR & (1 << UDRE))) asm volatile("NOP"); /* warte, bis UDR bereit */
Diese Zeile bringt immer eine Fehlermeldung wegen USR. Kennt der mega 16 nicht. ???????


MFG
Dieter