Ok danke dir dann schreib ich die Funktion mal schnell um
Hier der neue Code:
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))) asm volatile("NOP"); /* 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 ; //wert_in_cm;
US_PORT|=(1<<US_PIN); // Trigger-Puls auf high
_delay_us(15); // Laut Datenblatt Trigger-Puls min 10us auf high
_delay_us(15);
US_PORT&=~(1<<US_PIN); // Trigger-Puls Eingang wieder auf low
_delay_us(185); // Wartet nochmal
_delay_us(185);
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 )) ) asm volatile("NOP");
// Warten bis Input Capture Flag gesetzt ---> Echo-Eingang ist low
if(ICR1>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
TCNT1=0; // Wird jetzt auf 0 gesetzt!!!!!!!!!
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
TCCR1B= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus
TCNT1=0; // AUF 0 setzten !!!!!!
TIFR|=(1<<ICF1); // ICF1 Bit wieder löschen durch schreiben einer logischen 1
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);
}
}
Jetzt wird am ende der Funktion jedesmal zuers der Timer1 ausgeschaltet und anschließend das Register TCNT1 auf 0 gesetzt.
Pepisoft wenn du nochmal so nett sein könntest und den Code testest
Gruß Muraad
Lesezeichen