Also ich hab jetzt den Code noch bisschen verbessert in der Zeile:
TCCR1B&= ~(1<<CS12) & ~(1<<CS11) & ~(CS10); // Timer wieder aus
muss es am ende natürlich auch so sein & ~(1<<CS10) vielleicht hat der Compiler hier garkeinen Fehler gemeldet. Die Folgen könnten sich dann schon sehr komisch auf das Ergebniss auswirken. Im Code im anderen Thread hab ichs auch geändert.
Und ich fand deine ganzen UART Funktionen bisschen komisch(hab da einiges nicht verstanden), hab mal meine (die aus dem Datenblatt vom ATmega) eingefügt. Und auch wie du das Ergebniss verschickst hab ich bisschen geändert. :
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(!(USR & (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
TCCR1B&=~(1<<ICES1); // Fallende Flanke für Input Capture
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
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 geändert!!
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 1
TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus geändert!!
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);
}
}
Und das mit dem Teiler von 10000 stimmt schon, die Formel ist aus dem Datenblatt vom srf04. Hab auch mal mit ein paar fiktiven Werten rumgerechnet und die Formlel passt. Probiers einfach mit dem Code jetzt nochmal aus. Ich hab auf jeden Fall wieder nen gravierenden Fehler (vor allem wenn der Compiler nichts gesagt hat) ausgebessert.
Ach und wegen der Mühe, macht mir garnichts. Wenn der Code mal einwandfrei funktioniert habe ich und andere auch was davon.
Gruß Muraad
EDIT: Ich hab nochmal was geändert und zwar habe ich in die Funktion noch eine Warteschleife von 185us eingebaut bevor der Timer startet. Da im Datenblatt vom srf04 steht das erst ein 200us langer 40kHz Burst kommt bevor die Zeit gemessen werden kann/soll. Vorher wartet er ja schon 15us
Lesezeichen