- LiTime Speicher und Akkus         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 18 von 18

Thema: counter Problem (SRF05 Ultraschallsensor C code)

  1. #11
    Benutzer Stammmitglied
    Registriert seit
    27.03.2009
    Beiträge
    96
    Anzeige

    Praxistest und DIY Projekte
    Hardware:
    -Asuro
    ->Atmega8
    ->externer Quarz 8Mhz
    -Ultraschallsensor SRF05

    Hier ist mein aktuellster Code:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <avr/io.h>
    #include <inttypes.h>
    #include <util/delay.h>
    #include "asuro.h"
    
    int main(void)
    {
    
      Init();
      
      uint16_t ergebnis;
      char buffer [20];  //Doofe Frage: Was macht die Zahl in den eckigen Klammern???
      ergebnis = 0;
     
    
      while (1)
      {     
    
         DDRC |= (1<<PC3);              // PC3 Ausgang
         PORTC |= (1<<PC3);             // PC3 High
         _delay_us(20);                 // warte 20 µSekunden
         PORTC &= ~(1<<PC3);           // PC3 Low
         DDRC &= ~(1<<PC3);            // PC3 Eingang
         while(!(PINC & (1<<PC3)));   //warte auf Echo Signal
         TCCR1B = (1<<CS11);            // starte timer Prescaler 8
         TCNT1 = 0;                    // setze Timer1 auf 0
         while((PINC & (1<<PC3)));    //warte auf Echoende
         ergebnis = TCNT1;
         TCCR1B &= ~(1<<CS11);           // Stoppe timer
         
         itoa(ergebnis, buffer, 10); //übersetze (int)ergebnis in ASCII
         ergebnis = 0;
         SerPrint("\n\r Ergebnis: \n\r"); 
         SerPrint(buffer);              //übertragung des Ergebnisses über RS232
         _delay_ms(500);            //warte 500ms
      }
    }
    Ich erhalte in meiner UART Konsole bei ca. 12cm Abstand einen Wert von ca. 250,
    wenn ich nun den Abstand vergrößere dann wird dieser Wert kleiner bis er 1 beträgt.
    Vergrößere ich wieder den Abstand zähl er den Wert wieder bis auf ca. 250 u.s.w..
    Ist das nicht ein komisches Verhalten???

  2. #12
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Hab' mir mal das Datenblatt für den Sensor gesucht, der setzt das intern um, das ist also nicht die Laufzeit des Schalls, sondern die Formel lautet:
    Zurückgegebener Impuls in µs / 58 = Wert in cm, bei min. 100µs und max. 25000µs

    Bei einem Prescaler mit 8 und einem 8MHz Takt hast Du in 25000µs einen Zählerstand von 25000. Kann es sein, dass mit der Ausgaberoutine etwas nicht klappt ?
    Weise doch mal Ergebnis den Wert 25000 fest zu und gib das aus.

    Das Teil mit den eckigen Klammern ist ein Char-Array, das Äquivalent zu Strings in Bascom, die Zahl bezeichnet die Länge des Arrays.

  3. #13
    Benutzer Stammmitglied
    Registriert seit
    27.03.2009
    Beiträge
    96
    Code:
    int main(void)
    {
    
      Init();
      
      char buffer [10];
      uint16_t distance=0;
    
      while (1)
      {     
         distance = 25000;
         itoa(distance, buffer, 10); //übersetze (int)ergebnis in ASCII
         SerPrint("\n\r Ergebnis: \n\r"); 
         SerPrint(buffer);              //übertragung des Ergebnisses über RS232
         _delay_ms(500);            //warte 500ms
      }
    }
    Hab ich gemacht. In der Konsole erscheint auch 25000, also hier dürfte der Fehler nicht liegen.
    Ich stehe gerade so ziemlich aufm Schlauch
    Ich bin mir ziemlich sicher das der Fehler irgendwie mit dem Timer zusammenhängt.
    Ich befürchte ich komme mit der Bit schreibweiße noch ein wenig durcheinander.
    Es macht bei mir keinen Unterschied ob ich Das CS11 Bit so schreibe:
    TCCR1B = (1<<CS11); // starte timer Prescaler 8
    oder so wie man es bei den Ausgängen macht:
    TCCR1B |= (1<<CS11); // starte timer Prescaler 8

    Mache ich vielleicht dort einen Fehler???

    Vielleicht lösche ich das Bit ja auch falsch???
    TCCR1B &= ~(1<<CS11); // Stoppe timer

    Ich hoffe du kannst mir noch einmal helfen

  4. #14
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Maxtronik Beitrag anzeigen
    Es macht bei mir keinen Unterschied ob ich Das CS11 Bit so schreibe:
    TCCR1B = (1<<CS11); // starte timer Prescaler 8
    oder so wie man es bei den Ausgängen macht:
    TCCR1B |= (1<<CS11); // starte timer Prescaler 8
    Solange TCCR1B vorher 0 war, macht das keinen Unterschied. Beim Einschalten des µC's ist das Register 0.
    Nur soll man bei der ersten Initialisierung nicht verodern (|=), sondern direkt zuweisen. Grund dafür: Wenn z.B. ein Bootlader aktiv war, kann der das Register schon vorbesetzt haben, dann kommt mit Verodern Murks raus.
    Was macht eigentlich das Init() ? Auch würde ich noch TCCR1A auf 0 setzen, einfach der Gründlichkeit halber und damit ich sicher bin, das alle beteiligten Register den von mir gewünschten Wert haben.
    Mache ich vielleicht dort einen Fehler???
    Nein, hab's simuliert und sieht alles gut aus, in Ergebnis steht der Wert in µs.
    Vielleicht lösche ich das Bit ja auch falsch???
    TCCR1B &= ~(1<<CS11); // Stoppe timer
    Ist auch richtig. Du bist sicher das richtige Target gewählt und F_CPU definiert zu haben ?
    Welcher Optimierungslevel ist eingestellt ?
    Bekommst Du Warnings ? Wenn ja, welche ?

  5. #15
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Schreibweise mit TCCR1B = (1<<CS11); ist besser, weil man da das ganze Register definiert, also alles richtig einstellt, egal was vorher drin war. Die andere Version wird meistens auch gehen, weil der normale Mode default ist. die Version mit dem |= wird ggf. kürzer weil dafür spezielle ASM Befehle existieren.

    So ähnlich ist es mit dem Stoppen des Timers - das kommt hier ohnehin nach dem Auslesen, ist also nicht von Bedeutung. Man könnte es ggf. Probieren den Timer erst zu stoppen, und dann auszulesen. Im Prinzip sollte es aber auch bei laufendem Timer gehen.
    An sich macht GCC das auslesen von 16 Bit Registern richtig, man könnte es ggf. auch mal von Hand probieren (erst low Byte lesen), oder den erzeugten Code ansehen.

    An sich kann ich da keinen Fehler sehen. Ein versuch wäre ggf. noch den Timer erst auf 0 zu setzen und dann zu starten. Im Prinzip sollte aber beides gehen.

    Eine kleine Ungenauigkeit ist da noch drin bei der Ausgabe. Statt itoa sollte man utoa nehmen, denn die variable ist uint16_t. Bis gut 32000 sollte das aber auch noch keinen Unterschied machen.

    Die 58 µs/cm kommen übrigens ganz gut hin mit der Laufzeit. Das ist also schon die Zeit bis zu Echo.

  6. #16
    Benutzer Stammmitglied
    Registriert seit
    27.03.2009
    Beiträge
    96
    Was macht eigentlich das Init() ?
    Gute Frage! Das ist ein Dienst aus der asuro.c
    Dieser Dienst setzt folgende Timer bits:
    TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
    TCCR1B = (1 << CS11); // tmr1-Timer mit MCU-Takt/8 betreiben.
    Ich würde sagen wir haben den Fehler entdeckt .
    Das ist dann wohl einer dieser arten von Fehlern, die einem peinlich sein könnten.
    Und ich dachte die ganze Zeit dieses init() wäre ein fester Bestandteil von C .
    Ich bin halt blutiger Anfänger in C.
    Vielen Dank MagicWSmoke
    EDIT: und natürlich auch dir Besserwessi(Hab deinen Post erst danach gelesen )
    Geändert von Maxtronik (14.04.2012 um 21:18 Uhr)

  7. #17
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Besserwessi Beitrag anzeigen
    die Version mit dem |= wird ggf. kürzer weil dafür spezielle ASM Befehle existieren.
    Die Timerregister sind meist oberhalb des IO-Adressbereiches, den SBI & CBI erreichen können, diese Opcodes gehen nur bis 0x1F.
    Beim ATM8 sitzt TCCR1B auf 0x2E, damit ist die Sequenz: IN, ORI, OUT, bei der direkten Zuweisung dagegen nur: LDI, OUT, ein Takt weniger.
    Ports liegen oft im Bereich unter 0x1F, da ist Bit-weises Setzen und Löschen dann tatsächlich schneller.
    Die 58 µs/cm kommen übrigens ganz gut hin mit der Laufzeit. Das ist also schon die Zeit bis zu Echo.
    Ja, richtig. Ist ja der Weg hin und zurück.

  8. #18
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Maxtronik Beitrag anzeigen
    TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
    Ja, das war das Kritische, das hat 'ne 8-Bit PWM eingestellt und den Zähler "etwas" zusammengekürzt.
    TCCR1B = (1 << CS11); // tmr1-Timer mit MCU-Takt/8 betreiben.
    War dagegen kein Problem, da von Dir gesetzt.
    Das ist dann wohl einer dieser arten von Fehlern, die einem peinlich sein könnten.
    Passieren nicht, wenn man die Kontrolle über die Register selbst übernimmt.
    Vielen Dank MagicWSmoke
    Bitte, gern geschehen.

Seite 2 von 2 ErsteErste 12

Ähnliche Themen

  1. SRF04 oder SRF05 Ultraschallsensor ?!
    Von kamatschka im Forum Sensoren / Sensorik
    Antworten: 10
    Letzter Beitrag: 13.04.2012, 17:25
  2. Antworten: 27
    Letzter Beitrag: 14.10.2009, 19:49
  3. SRF05 Ultraschallsensor an atmega32, kein Signal
    Von bruegae im Forum Sensoren / Sensorik
    Antworten: 3
    Letzter Beitrag: 20.11.2008, 21:58
  4. Git es den Ultraschallsensor SRF05 mit analoger Spannung?
    Von Sheridan im Forum Sensoren / Sensorik
    Antworten: 6
    Letzter Beitrag: 18.04.2007, 17:35
  5. Ultraschallsensor SRF05
    Von MORRI$ im Forum Sensoren / Sensorik
    Antworten: 0
    Letzter Beitrag: 31.07.2006, 16:12

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus