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
Lesezeichen