Hi,
ich bin am experimentieren, wie ich einen sehr genauen Zähler in C
schreiben kann.
Ich habe mich bereits an dem 8-Bit Timer versucht:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Timer.2FCounter_des_AVR
Dazu habe ich den CPU Frequenzteiler von 1024 verwendet und dann jeden
Overflow i++ rechnen lassen. Dann wurde das ganze ausgewertet, wenn i >
3906 ist, sollte eigentlich eine Sekunde rum sein und eine LED leuchten.
Allerdings braucht die 2-3 Sekunden bis sie endlich angeht, was
warscheinlich an der if Schleife liegen wird.
Vorhaben ist folgende: Ich möchte mit einer Schaltung und je einen
Ultraschallempfänger/-sender einen Abstand von 10 - 100 cm messen
können. Die Schallgeschwindigkeit in Luft beträgt 34300 cm/s, da der
Schall zum Boden und wieder zurück muss, sind es bei 10 cm Messenfernung
20 cm, die der Schall zurücklegen muss, also braucht er dafür: 34300/20
s?
Für dein Anliegen dürfte sich der Input Capture Pin eignen.
Dass deine LED erst nach 2-3 Sec angeht liegt wahrscheinlich daran, dass
du die Fuses noch nicht richtig programmiert hast und der AVR mit dem
internen 1MHz Osc. läuft.
ACHTUNG: Vor dem Programmieren der Fuses unbedingt den Abschnitt im
Tutorial lesen.
Immer erst die Fuses auslesen und die entsprechenden Fuses dann ändern.
Bei falsch gesetzten Fuses kanns dir passieren dass du den Proz. nicht
mehr programmieren kannst.
Gruß
Roland
@ Orikson
>ich bin am experimentieren, wie ich einen sehr genauen Zähler in C>schreiben kann.
Das hat mit C wenig zu tun, eher mit der Hardware des uC.
>Dazu habe ich den CPU Frequenzteiler von 1024 verwendet und dann jeden>Overflow i++ rechnen lassen. Dann wurde das ganze ausgewertet, wenn i >>3906 ist, sollte eigentlich eine Sekunde rum sein und eine LED leuchten.>Allerdings braucht die 2-3 Sekunden bis sie endlich angeht, was>warscheinlich an der if Schleife liegen wird.
Genaue Zähler arbeiten nicht mit If-Schleifen (wobei es If-Schleifen gar
nicht gibt)
>Vorhaben ist folgende: Ich möchte mit einer Schaltung und je einen>Ultraschallempfänger/-sender einen Abstand von 10 - 100 cm messen>können. Die Schallgeschwindigkeit in Luft beträgt 34300 cm/s, da der>Schall zum Boden und wieder zurück muss, sind es bei 10 cm Messenfernung>20 cm, die der Schall zurücklegen muss, also braucht er dafür: 34300/20>s?
Schallgeschwindigkeit: 330 m/s = 330mm/ms = 10mm/ 30,3us
Um sowas genau zu messen musst du die Input Capture Funktion benutzten.
Genaueres steht dazu in jedem Datenblatt.
MfG
Falk
ich würde dann die Rechnung auch anders machen.
angenommen dein Quarz läuft mit 4 MHz, so schaffst du 343m bei 4000000
Takten, also 85,75µm je Takt.
Bei einem Prescaler von 64 wären das 5,488 mm/ Timertick
bzw bei nem Prescale von 1024 87,808 mm/ Timertick
Mit dem ICP kannst dann dem Timerwert zum Zeitpunkt des Impulses
auslesen, am Besten schaust mal ins Datenblatt wie das geht.
Gruß
Roland
Hi und danke erst mal für die vielen Antworten!
Ich hab das Datenblatt mal durchgelesen. Sovie wie ich rauslesen konnte
ist aber nur, dass die Input Capture Funktion auf Pin PB0 liegt, eine
Schaltung/Code konnte ich nicht finden. Von daher gehe ich mal aus, dass
das auslesen der ICF reine Softwaresache ist?!
Und bitte steinigt mich nicht, ich bastle erst ne Woche mit dem Mega8
rum (LCD und Tasten gehen aber schon ;-P)
du müsstest erst mal deinen Timer richtig initialisieren (Prescaler,
Input Capture Interrupt)
dann regelmäßig einen US-Burst aussenden und zeitgleich den Timer
starten.
(das aussenden kann man evtl über Output Compare=0 machen)
Irgendwann tritt dann der ICF-Interrupt ein und da musst nur den dabei
abgespeichherten Timerwert auslesen, umrechnen und anzeigen :-)
Achtung, je nach Prescaler läuft der Timer früher oder später über...
ich hoffe du hast im ausführlichen Datenblatt, bei mir Seite 120 und
nicht in der Summary nachgesehen.
Gruß
Roland
Guten Morgen,
Das Program gibt es schon, aber das ist für einen AT90S8535 gedacht.
Normalerweiße sollte sich das doch auf nen Mega8 übertragen lassen,
oder? Mein LCD hängt wie an einem AVR-Ctrl Board im 4 Bit Modus am
Mega8, ich habe 3 Taster und 3 LEDs und 2 Stecker, an die ich je ein
Erweiterungsboard hängen kann.
Nachdem ich jetz aber alle Pins etc. angepasst habe meldet mir AVR
Studio immernoch 15 Fehler. Folgende Variablen sind nicht deklariert:
GIMSK, GIFR, .EXT_INT1, TIM1_OVF, UBRR, UCR. Außerdem kennt er
#asm("sei") nicht. Ich würde mal tippen, dass das in ner Headerdatei
drin ist, die ich nicht eingebunden habe... Folgende habe ich aber
eingebunden: stdint.h, avr/interrupt.h, avr/io.h, util/delay.h und
inttypes.h. Dazu noch eine lcd.h die ich mir aus dem Code aus m Tutorial
hier gebastelt habe und in anderen Projekten funktioniert...
Werde mal den Code raussuchen und hier posten...
>>Nachdem ich jetz aber alle Pins etc. angepasst habe meldet mir AVR>>Studio immernoch 15 Fehler. Folgende Variablen sind nicht deklariert:>>GIMSK, GIFR, .EXT_INT1, TIM1_OVF, UBRR, UCR.
Diese Register heissen auf einem mega8 schlichtweg anders: UBRR hat
jetzt 16 Bit mit den Namen UBRRH und UBRRL. Genauso ist UCR aufgeteilt
in UCSRA und UCSRB.
Die Namen (und Positionen) der einzelnen Bits in den Registern sind auch
auf allen avrs unterschiedlich, da gibt es keine gemeinsame Norm. Es
hilft beim Wechsel des Controllers nur das waelzen des Datenblattes. Im
Allgemeinen heissen die Register aber zumindest aehnlich - man kann also
einfach die register summary nehmen und nach einem aehnlich Namen
suchen, in der Regel findet man das passende.
Hab mich mal durch die Datenblätter gekämpft und die Namen und Werte
gekämpft und mal geändert... Leider hab ich immernoch exakt die selben
Fehler, nur dass jetz die angeblich richtigen Namen anstelle der anderen
auftauchen...