-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 24

Thema: Sei() Cli() Atmega 16 Timer starten/stoppen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50

    Sei() Cli() Atmega 16 Timer starten/stoppen

    Anzeige

    Hallo Leute,

    da ich vorhabe eine Stoppuhr zu programmieren habe ich mir zum Testen folgendes Programm ueberlegt:

    [//define all external dependencies
    #include <avr/io.h>
    #include <avr/interrupt.h>




    //declare all used functions
    void Sensor_init(void);
    void LED_SW_init(void);

    //define variables

    volatile unsigned int z;

    void TIMER2_interrupt_init(void)
    {
    TCCR2 = (1<<WGM21)|(0<<WGM20)|(1<<CS22)| (1<<CS21) |(0<<CS20); //CTC mode und Prescaler auf 256
    TCNT2=0;
    OCR2=249; //alle 0.008 s Interrupt
    TIMSK = (1<<OCIE2);
    }

    ISR(TIMER2_COMP_vect) //LED soll alle 1 leuchten
    {
    z++;
    if(z==125)
    {
    PORTB ^= (1<<PB0);
    z=0;
    }

    }

    int main(void)
    {
    Sensor_init();
    LED_SW_init();

    TIMER2_interrupt_init();

    while(1)
    {
    if(!(PIND & (1<<PD0))) sei(); //Mit Pin 0 soll Timer gestartet werden

    if(!(PIND & (1<<PD7))) cli(); //Mit Pin 7 soll Timer stoppen
    }
    }


    void Sensor_init(){

    DDRA=0x00; // Port A has to be used as a digital input
    PORTA=0xff; // activate internal pull-up resistors for PORTA
    }

    void LED_SW_init(){

    DDRB=0xFF; // PORTB is output for LEDs
    PORTB=0xFF; // all LEDs off
    }
    ]

    Wenn ich den Taster 0 druecke soll der Timer aktiviert werden und wenn ich den andren Taster Pin 7 druecke soll er deaktiviert werden und nicht mehr zaehlen bzw die LED hier nicht mehr im sekundentakt blinken. Dieses Programm habe ich nur geschrieben um das Grundprinzip meines Programms zu testen...

    Jetzt meine Probleme:

    1) Die LED blinkt immer und reagiert auf keinen Taster:

    2) Wenn ich von Port D die Bruecke zu RXD TDX drin habe, blinkt zu Beginn gar nichts. Erst wenn ich sie rausnehm fängt die LED an zu blinken.


    Später will ich mit meinem Programm die Zeit stoppen, d.h. wenn der Taster 0 gedrueckt ist, soll der Timer starten und wenn der Taster 7 gedrueckt ist soll der Timer stoppen. Wie krieg ich das hin, dass meine LED nach gedruecktem Taster 0 blinkt und wenn ich Taster 7 einmal druecke aufhoert ?

    Vielen Dank und viele Gruesse,

    Jimmy[/code]

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.183
    Mit cli sperrst du alle Interrupts und mit sei gibst du alle wieder frei.
    Der Timer läuft aber trotzdem weiter. Der Timer startet mit setzen der CSxx Bit im TCCR2 Register und wird mit löschen dieser Bit wieder gestoppt.
    Auf PortD sind keine PullUp aktiv.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von steveLB
    Registriert seit
    24.10.2005
    Beiträge
    481
    sei und cli bewirken nur das schalten der interrupts und deren vektoren, der timer läuft trotzdem weiter nur wird das interrupt nicht mehr ausgeführt


    hm am besten postet du noch wie die Tasten angeschlossen sind .

    desweiteren, Timer kannst auch anhalten indem du die CS02 01 00 bits im TCCRx register auf null setzt, und wieder aktivierst in dem du sie so setzt wie oben.

    edit: da war wohl jemand schneller
    [X] <-- Nail here for new Monitor

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.183
    So wie es jetzt ist, ist es natürlich nicht schön, da der Timer bei jedem Durchlauf wieder gestartet wird solange die Taste gedrückt ist.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Also mein Ziel ist es einen Timer mit einem Taster zu starten bzw. genau dann eine Variable hochzaehlen lassen. Wenn ich einen anderen Taster druecke moechte ich mir per UART den Zaehlerstand ausgeben lassen. Wie kann man denn so etwas machen ? Es geht mir jetzt nur darum wie ich den Timer fuer so was per Taste starte.

    Aber was mit dem PortD los is hab ich jetzt nicht verstanden...warum beeinflusst dieser die Funktion meines Programmes obwohl ich ihn nirgends drin hab!

    Vielen Dank und viele Gruesse

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.183
    Soweit sollte es schon passen. Du hast nur die Tasten im Programm auf PIND.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Also mein Ziel ist es einen Timer mit einem Taster zu starten bzw. genau dann eine Variable hochzaehlen lassen. Wenn ich einen anderen Taster druecke moechte ich mir per UART den Zaehlerstand ausgeben lassen. Wie kann man denn so etwas machen ?
    Das geht am einfachsten über die Manipulation des TCCR1B Registers für Timer 1.

    Zuerst setzt du bei einem Tastendruck der Starttaste das TCNT1 Register auf 0
    TCNT1=0;

    Danach Stellst du das TCCR1B auf den gewünschten Teilerfaktor ein.
    TCCR1B=0b00000100; //für Prescaler :256
    Der Timer 1 zählt nun hoch.

    Bei Druck auf die Taste Stopp holst Du Dir den Wert aus dem TCNT1 Register
    ui_zeit=TCNT1;
    und stoppst den Counter 1
    TCCR1B=0b00000000;
    Eventuell brauchst Du noch eine Überlaufvariable, weil der TCNT1 nur 16 Bit breit ist.
    Dann muß natürlich der TIMER1 Overflow Interrupt aktiviert werden.

    Die Tastenabfrage kannst Du jeweils in einen Interrupt packen.
    Start z.B. in den INT0 und Stopp in den ICP1 Interrupt, weil damit das ICR Register des Timers 1 mit dem aktuellen Zählerstand gefüllt wird, den man dann nur noch auszulesen braucht.

    Den ermittelten Wert kannst Du dann mit itoa bzw. ltoa in einen String verwandeln und über die serielle Schnittstelle ausgeben.

    Ich würd bei der Stopp Taste ( Interrupt ) ein Flag setzen , der Timerwert speichern und dann erst in der Hauptroutine den Sendestring generieren und an den USART ausgeben.
    Dadurch wird die Interruptroutine auch sehr kurz.

    Du hast natürlich bei der Aktivierung des TIMER 1 ein paar Prozessortakte verloren, weil natürlich zuerst die Interruptroutine aufgerufen und das TCCR1B Register beschrieben wird, bevor der Timer 1 zu zählen beginnt.
    Kommt drauf an, wie genau die ermittelte Zeit sein muß und welchen Prescaler Du verwendest.

    Ne andere Methode:
    Ich persönlich verwende auch eine relative Zeitmessung mit freilaufendem Timer.

    Der Zählerstand wird bei Druck auf die Starttaste ausgelesen und abgespeichert.
    Bei Druck auf die Stopptaste wird der Zählerstand erneut ausgelesen und der vorher ermittelte Wert angezogen.
    Wenn Du unsigned Variablen verwendest funktioniert das auch bei einem Überlauf des Timers, oder der Überlaufvariable.

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Soweit so gut Super!!! Vielen vielen Dank !!!!Ich kann die LED die im sekundentakt blinkt ueber meine schalter aktivieren und deaktivieren jaaaaaaaaaaaaaaaaaaaa

    wenn ich jetzt meine Uhr da rein haue...wie speicher ich denn beim ausschalten meinen Zaehlstand in einer Variable ab ? Ich möchte sie mir nämlich per UART ausgeben lassen...so sieht mein Programm dann aus:

    //define all external dependencies
    #include <avr/io.h>
    #include <avr/interrupt.h>




    //declare all used functions
    void Sensor_init(void);
    void LED_SW_init(void);

    //define variables

    volatile unsigned int z;
    volatile unsigned int sekunde;
    volatile unsigned int minute;
    volatile unsigned int stunde;


    void TIMER2_interrupt_init(void)
    {
    TCCR2 = (1<<WGM21)|(0<<WGM20)|(1<<CS22)| (1<<CS21) |(0<<CS20); //CTC mode und Prescaler auf 256
    TCNT2=0;
    OCR2=249; //alle 0.008 s Interrupt
    TIMSK = (1<<OCIE2);
    }

    ISR(TIMER2_COMP_vect) //Stoppuhr
    {
    z++;
    if(z==125)
    {
    sekunde++;
    z=0;
    }

    if(sekunde==60)
    {
    minute++;
    sekunde=0;
    }

    if(minute==60)
    {
    stunde++;
    minute = 0;
    }

    }

    int main(void)
    {
    Sensor_init();
    LED_SW_init();

    TIMER2_interrupt_init();

    while(1)
    {
    if(!(PINA & (1<<PINA0))) sei(); //Mit Pin 0 soll Timer gestartet werden

    if(!(PINA & (1<<PINA1))) cli(); //Mit Pin 1 soll Timer stoppen
    }
    }


    void Sensor_init(){

    DDRA=0x00; // For using the floating sensor the Port A has to be used as a digital input
    PORTA=0xff; // activate internal pull-up resistors for PORTA
    }

    void LED_SW_init(){

    DDRB=0xFF; // PORTB is output for LEDs
    PORTB=0xFF; // all LEDs off
    }

    Ich hab ja hier die Variablen: sekunde, minute, stunde...ich wuerd sie gern in einer Variablen umgerechnet zusammenfassen und dann an genau einmal an der PC per UART schicken. Und das wäre dann noch genau dann der Fall wenn ich Taster 1 betätige...irgendjemand ne Ahnung ?

    Viele Gruesse und nochmal vielen Dank!!

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Das mit dem freilaufendem Timer is natuerlich ne feine sache Wuerde es dir was ausmachen den Quellcode hier reinzustellen !? Hab noch nicht so die grosse Erfahrung damit...vielen Dank und viele Gruesse

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Es geht mir dann speziell darum wie ich die Zaehlwerte abspreichere...also bei Druck von Start taste speichere Zaehlstand....bei Druck von Stopptaste speichere diesen Zaehlstand...und dann die Subtraktion...vom prinzip hab ich das verstanden und es gefällt mir auch besser als mein Weg...

    Vielen Dank

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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