Hallo Ihr Beiden
Folgende Sachen noch.
In der neuen WINAVR Version gibt es ein kleines Problem mit der Delay.h.
The macro F_CPU is supposed to be defined to a
constant defining the CPU clock frequency (in Hertz).
The maximal possible delay is 768 us / F_CPU in MHz.
Also auf die maximale Zeit achten, oder selber eine Delay Schleife Proggen.
Beim eintreten eines ICP wird das Bit gesetzt und der Wert von Timer1 nach
ICR1 kopiert. Danach muss das Bit durch schreiben einer 0 zurückgesetzt
werden.
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++;
}
}
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 !!!!!!!1 geht laut Simulator nicht richtig 95 µs werden angezeigt
_delay_us(185); //mit 2 Delay kommt man auf 192µs, anpassen !!!!!!!!!!!!!!!
TCCR1B &=~(1<<ICES1); // Fallende Flanke für Input Capture
TCNT1 = 0; //hinzugefügt, Timer Wert löschen
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, ICF1 ist dann gesetzt
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
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 0 geändert
TCCR1B &= ~(1<<CS12) & ~(1<<CS11) & ~(1<<CS10); // Timer wieder aus
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);
}
}
Das starten oder stoppen des Timers hat keinen Einfluß auf den Timerwert
in TCNT1. Also vorher löschen oder einlesen und nachher in die Berechnung einfliessen lassen.
MFG
Dieter
Lesezeichen