- 12V Akku mit 280 Ah bauen         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 24

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

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

    LiFePo4 Akku selber bauen - Video
    Also ich hab jetzt mal versucht etwas zusammenzuschreiben...könntet ihr mir vielleicht nen Tip geben ob das prinzipiell so funktioniert ?

    Mein Code lautet:

    //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 T1;
    volatile unsigned int T2;
    volatile unsigned int TD;


    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) /Sekunde hochzählen
    {
    z++;
    if(z==125)
    {
    sekunde++;
    z=0;
    }

    }

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

    TIMER2_interrupt_init();

    while(1)
    {
    if(!(PINA & (1<<PINA0))) //Mit Pin 0 soll T1 gespeichert werden
    {
    T1 = sekunde;
    }
    if(!(PINA & (1<<PINA1))) //Mit Pin 1 soll T2 gespeichert werden und die Differenz berechnet werden
    {
    T2 = sekunde;
    TD = T2-T1;
    }
    }


    Jetzt stellt sich natürlich noch die Frage wie ich TD über UART auslesen kann...würde mich sehr über eine Antwort oder nen Code freuen.

    Vielen Dank und viele Gruesse,

    Jimmy

  2. #12
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Zuerst solltest Du die Variable TD in einen String umwandeln

    unsigned char uc_string[6]; //Stringvariable anlegen.
    ......
    itoa(TC,uc_string);

    Dann wird dieser String per USART gesendet.
    Wie das geht ist von Compiler zu Compiler und der Art des Versendens abhängig.

    Beispiel:
    print(uc_string); //Senden - CR = Carriage Return und LF Line Feed anfügen
    printf("\r\n");

    sprint(uc_string); //Senden - CR und LF anfügen
    sprintf("\r\n");

    for(i=0;i<strlen(uc_string);i++)
    {
    putchar(uc_string[i]) //Senden
    }
    putchar('\r'); //CR und LF anfügen
    putchar('\n);

    Guck aber in deiner Library für die serielle Schnittstelle nach, wie das bei Dir gehandelt wird, welche Syntax verwendet wird und welche Befehle auf diese umgeroutet werden.

    Anbei noch ein kurzes Codeschnipsel, das für Deinen Anwendungsfall nicht optimal ist, aber gut zeigt wie das Ganze funktioniert.

    In diesem Beispiel wird bei einer steigenden Flanke am ICP Pin der alte Wert des Timers ausgelesen und das Sensing auf fallende Flanke umgestellt.
    Fällt die Flanke dann wird der zweite Teil der Routine angesprochen,der aktuelle Wert ermittelt und der vorher ermittelte alte Wert abgezogen.
    Dann wird das Sensing wieder auf steigende Flanke für den nächsten Impuls umgestellt.

    Es wird also die High Time des Impulses ermittelt.
    Das Ganze gehört zu einer Servoimpulsauswertung, bei der eigentlich nur die High Impulslänge wichtig ist.

    Für deine anwendung kannst Du die beiden Codeteile in deinen beiden Tastenabfrage unterbringen.

    Code:
    // Timer 1 input capture interrupt service routine
    interrupt [TIM1_CAPT] void timer1_capt_isr(void)
    {
    if((TCCR1B&0b01000000)>0)       //Interrupt wurde durch steigende Flanke ausgelöst
        {
        ui_oldrise=ICR1;            //Messwert der steigenden Flanke ablegen
        TCCR1B&=0b10111111;         //Interupt Sensing auf fallende Flanke umstellen
        }
    else                            //Interrupt wurde durch fallende Flanke ausgelöst
        {
        ui_pulsebuffer=ICR1-ui_oldrise;     //Pulslänge berechnen
        TCCR1B|=0b01000000;         //Interrupt Sensing auf steigende Flanke Umstellen
        }
    }
    Ich würde die Tastenabfragen in Deiner Anwendung über Interrupts abwickeln.
    Wenn Du z.B. ein Display an deinem System hast, verbringt der Controller oft sehr lange Zeiten in den Displayroutinen.
    Während dieser Zeiten werden die Taster nicht abgefragt und somit die Auslösezeit nicht exakt ermittelt.

    Machst Du die Tastenabfrage im z.B. INT 0 wird die Displayroutine unterbrochen und diese Tastenabfrage sofort ausgeführt.

    Die Zeiten werden dadurch nicht 100% genau, aber wesentlich genauer, als bei Deinem Verfahren, das man übrigens POLLING nennt.

    Noch was solltest Du beachten - Tasten prellen.
    Das bedeutet eine Taste schließt und offnet bei Betätigung mehrmals, bevor der Kontakt letztlich offen bzw. geschlossen ist.
    Bei Deinem 2 Tasten System ist das eigentlich kein Problem, trotzdem sollte Dein Code damit zuecht kommen.

  3. #13
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Also erstmal vielen Dank fuer deine Antwort...sehr viel Informationen
    Kann ich denn 2 ISR mit dem gleichen Timer laufen lassen...hab ja schon eine ISR fuer meine Zählvariable...und mit dem itoa() das versteh ich irgendwie nicht so recht...hab mein Programm mal mit Hilfe des Tutotrials so weit verändert wie es ging...

    //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);
    void uart_init(void);
    void TIMER2_interrupt_init(void);

    //define variables

    volatile unsigned int z;
    volatile unsigned int sekunde;
    volatile unsigned int T1;
    volatile unsigned int T2;
    volatile unsigned int TD;



    void uart_init(void)
    {
    UCSRB |= (1<<TXEN); // UART TX einschalten
    UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1

    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;
    }


    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=199; //alle 0.008 s Interrupt
    TIMSK = (1<<OCIE2);
    }

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

    }

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

    while(1)
    {
    if(!(PINA & (1<<PINA0))) //Mit Pin 0 soll T1 gespeichert werden
    {
    T1 = sekunde;
    }
    if(!(PINA & (1<<PINA1))) //Mit Pin 1 soll T2 gespeichert werden und die Differenz berechnet werden
    {
    T2 = sekunde;
    TD = T2-T1;
    }
    }


    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
    }

    //-------------------------------------------------------------------------------------------------//

    /* ATmega16 */
    int uart_putc(unsigned char c)
    {
    while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
    {
    }

    UDR = c; /* sende Zeichen */
    return 0;
    }


    /* puts ist unabhaengig vom Controllertyp */
    void uart_puts (char *s)
    {
    while (*s)
    { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
    uart_putc(*s);
    s++;
    }
    }

    //-------------------------------------------------------------------------------------------------//

    Weiss nicht so recht wie ich da jetzt meine Variable TD unterkriegen soll !? Un dass er mir die auch noch sendet...also als Terminalprogramm verwende ich hterm und als Entwicklungsumgebung avrstudio4. Mein Board ist ein stk500 und ich habe einen Atmega16 drauf. Mein groesstes Problem ist wie gesagt das Senden eines Variableninhalts und wo ich das unterbringen muss...macht man so etwas in main() in der Schleife oder irgendwie anders ?????

    Viele Gruesse,

    Jimmy

  4. #14
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Also ich hab jetzt nochmal die Randbedingungen fuer die UART-Kommunikation eingefuegt...das Senden eines Strings hab ich schon mal in einem anderen Programm hingekriegt...jetzt fehlt mir noch wie ich die Variable auslese...ich weiss nicht wie das funktioniert...von der Programmiersprache her...da habe ich wohl noch viel zu Lernen

    Vorerst möchte ich auch wenn es ziemlich ungenau ist ersteinmal die Variable senden und am PC sehen können...erst dann wuerde ich mich gerne mit der Genauigkeit beschäftigen und ggfs. umprogrammieren...Hier hab ich nochmal meinen aktuellen Code...es wuerde mir sehr viel helfen wenn ihr vielleicht da drin den Änderungen vornehmt...Die neuen Teile hab ich so abgegrenzt : //----

    Vielen Dank und viele Gruesse


    Code:
    //define all external dependencies
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    //-------------------------------------------------------------------------------------------------//
    #ifndef F_CPU
    #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
    #define F_CPU 3686400 // Systemtakt in Hz 
    #endif
    
    #define BAUD 9600UL // Baudrate
    
    // Berechnungen
    #define UBRR_VAL (((F_CPU)/(BAUD*16))-1) // clever runden
    #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
    #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
    
    //#if ((BAUD_ERROR>10) || (BAUD_ERROR<=10))
    //#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
    //#endif
    //-------------------------------------------------------------------------------------------------//
    
    //declare all used functions
    void Sensor_init(void);
    void LED_SW_init(void);
    void uart_init(void);
    void TIMER2_interrupt_init(void);
    
    //define variables
    
    volatile unsigned int z;
    volatile unsigned int sekunde;
    volatile unsigned int T1;
    volatile unsigned int T2;
    volatile unsigned int TD;
    
    
    
    void uart_init(void)
    {
      UCSRB |= (1<<TXEN);  // UART TX einschalten
      UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
     
      UBRRH = UBRR_VAL >> 8;
      UBRRL = UBRR_VAL & 0xFF;
    }
    
    
    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=199;															//alle 0.008 s Interrupt
      TIMSK = (1<<OCIE2);
      }
    
    ISR(TIMER2_COMP_vect)												//LED soll alle 1s leuchten
    {
     z++;
      if(z==72)
      {
        PORTB ^= (1<<PB0);
        z=0;
      }
    
    }
    
    int main(void)
    {
      Sensor_init();
      LED_SW_init();
      uart_init();
      TIMER2_interrupt_init();
    
     while(1)
    {
    if(!(PINA & (1<<PINA0))) //Mit Pin 0 soll T1 gespeichert werden
    {
    T1 = sekunde;
    }
    if(!(PINA & (1<<PINA1))) //Mit Pin 1 soll T2 gespeichert werden und die Differenz berechnet werden
    {
    T2 = sekunde;
    TD = T2-T1;
    } 
    }
    
    
    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
    	}
    
    //-------------------------------------------------------------------------------------------------//
    
    /* ATmega16 */
    int uart_putc(unsigned char c)
    {
        while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
        {
        }                             
     
        UDR = c;                      /* sende Zeichen */
        return 0;
    }
     
     
    /* puts ist unabhaengig vom Controllertyp */
    void uart_puts (char *s)
    {
        while (*s)
        {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
            uart_putc(*s);
            s++;
        }
    }
    
    //-------------------------------------------------------------------------------------------------//

  5. #15
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    jetzt fehlt mir noch wie ich die Variable auslese
    Die Variable wird in einen String umgewandelt und dann gesendet!

    itoa(variable,string)
    sprint(string)

    Wenns ne long Variable ist, dann wirds halt ltoa(variable,string).

    Hatte Ich Dir aber in diesem Threat schon 2x geschrieben

  6. #16
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    mhhh ja gut....trotzdem danke
    Ich bin noch ziemlich unerfahren...hab also net wirklich ahnung...wuerds aber trotzdem gern verstehen

    Wenn ich jetzt die Variable umwandele...wo lass ich sie mir denn dann schicken...da wo ich die Differenz bilde...und den Rest in meinem Programm kann ich dann so lassen !? Wuerde es dir was ausmachen die Umwandlung und das Senden vielleicht in "meinen Code" reinzuschreiben !?
    Sorry, das sich dir so viel Muehe bereite

    MFG

  7. #17
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Wie wärs hier!
    Code:
    if(!(PINA & (1<<PINA1))) //Mit Pin 1 soll T2 gespeichert werden und die Differenz berechnet werden
    {
    unsigned char uc_string[6]; //Eine String Variable mit 6Stellen wird eingerichtet
    unsigned char i=0; //Eine Schleifenvariable wird eingerichtet
    T2 = sekunde;
    TD = T2-T1;
    itoa(TD,uc_string);
    //nun musst Du nur noch uc_string über UART senden und <CR><LF> anhängen- fertig
    for(i=0;i<strlen(uc_string);i++);
    {
    uart_putc(uc_string[i]);
    }
    uart_putc('\r');      //<CR> und <LF> anfügen
    uart_putc('\n');
    }
    Übrigens, der Befehl itoa ist bei mir (CodeVision AVR) in der stdlib.h, die man natürlich includen muß.
    #include <stdlib.h>
    Wo der Befehl bei AVRGCC ist weiß ich nicht, sollte aber in der Hilfe zu finden sein.

  8. #18
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Vielen Dank für deine Antwort...also hab jetzt mal reingeschrieben...kanns leider heut net mehr ausprobieren...erst morgen früh wieder...muss ich an dem Code jetzt noch etwas ändern !? Oder meinst du das funktioniert so mit dem Senden !? Krieg ich dann pro Tastendruck den Zählstand angezeigt!? Und was macht eigentlich uart_puts..im Tutorial versteh ich das nicht....
    Vielen Dank nochmal...

    Jimmy



    Code:
    //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 T1;
    volatile unsigned int T2;
    volatile unsigned int TD;
    
    
    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) /Sekunde hochzählen
    {
    z++;
    if(z==125)
    {
    sekunde++;
    z=0;
    }
    
    }
    
    int main(void)
    {
    Sensor_init();
    LED_SW_init();
    
    TIMER2_interrupt_init();
    
    while(1)
    {
    if(!(PINA & (1<<PINA0)))         					//Mit Pin 0 soll T1 gespeichert werden
    {
    T1 = sekunde;
    }
    if(!(PINA & (1<<PINA1))) 						//Mit Pin 1 soll T2 gespeichert werden und die Differenz berechnet werden
    {
    unsigned char uc_string[6]; 						//Eine String Variable mit 6Stellen wird eingerichtet
    unsigned char i=0; 							//Eine Schleifenvariable wird eingerichtet
    T2 = sekunde;
    TD = T2-T1;
    itoa(TD,uc_string);
    
    									//nun musst Du nur noch uc_string über UART senden und <CR><LF> anhängen- fertig
    for(i=0;i<strlen(uc_string);i++);
    {
    uart_putc(uc_string[i]);
    }
    uart_putc('\r');      							//<CR> und <LF> anfügen
    uart_putc('\n');
    } 
    }
    
    
    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
    }
    
    
    //-------------------------------------------------------------------------------------------------//
    
    /* ATmega16 */
    int uart_putc(unsigned char c)
    {
    while (!(UCSRA & (1<<UDRE))) 						/* warten bis Senden moeglich */
    {
    }
    
    UDR = c; 								/* sende Zeichen */
    return 0;
    }
    
    
    									/* puts ist unabhaengig vom Controllertyp */
    void uart_puts (char *s)
    {
    while (*s)
    { 									/* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
    uart_putc(*s);
    s++;
    }
    }
    
    //-------------------------------------------------------------------------------------------------//

  9. #19
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.214
    Code:
    /* ATmega16 */
    int uart_putc(unsigned char c)
    {
    while (!(UCSRA & (1<<UDRE)))                   /* warten bis Senden moeglich */
    {
    }
    
    UDR = c;                         /* sende Zeichen */
    return 0;
    }
    Was tut das!?
    Es wird gewartet bis das UDRE Bit im UCSRA Register 1 ist.
    Wenn ich mich recht entsinne bedeutet das, das das Senderegister leer ist.
    while(!(UCSRA&(1<<UDRE)));
    Dann wird das UDR mit dem gewünschten Zeichen beschrieben: UDR=c;
    Die Routine stammt aus Deinem Code! - Eigentlich solltest Du dann schon wissen, was die Routine tut!
    Die Routine gibt noch einen int Wert zurück, damit die aufrufende Routine weiß, das sie ausgeführt wurde.
    Das wurde in meinem Codeschnipsel nicht berücksichtigt und macht hier auch keinen Sinn, weil ja keine anderen Werte als 0 zurück gegeben werden können.
    Es würde Sinn machen, wenn da noch ein Timeout oder sonst eine Fehlererkennung drin wäre, die andere return Werte als 0 generieren kann.
    Der aufruf müsste dann lauten:
    status=uart_putc(uc_string[i]);

    Der Wert 0, den die Routine dann zurück gibt wäre dann in der int Variable status zu finden.
    Da dort aber nur der Wert 0 auftauchen kann, kann man sich die rückgabe des wertes gleich schenken also aus:
    int uart_putc(unsigned char c)
    wird
    void uart_putc(unsigned char c)

    das
    return 0;
    entfällt ersatzlos.



    Diese Senderoutine verschwendet aber eine Menge Rechenzeit - das ist Dir hoffentlich klar!
    Der Controller wartet ja so lange, bis 8Bit + Start und Stoppbit, also 10 Bits, eines Zeichens komplett über die TxD Leitung versendet ist.

    Das dauert bei 9600bit/sek ca. 1ms. In dieser Zeit hätte der Controller bei 8MHz 8000Befehle abarbeiten können!
    Das ist auch der Grund, warum man solche Funktionen über Interrupts erledigt.

    Auch der USART kann Interruptgetriggert arbeiten!

    Man schreibt dazu die zu sendenden Daten in einen Ringpuffer und eine Sendeinteruptroutine holt sich diese Daten dann ab und versentet sie dann ohne weiteres zutun des Hauptprogrammes im Transmit Interrupt des USART.

    Aber arbeite erstmal mit Deiner Methode weiter.
    Das kann man dann bei mehr Programmiererfahrung immer noch mal umbasteln.

  10. #20
    Benutzer Stammmitglied
    Registriert seit
    20.03.2010
    Beiträge
    50
    Also das mit dem Umwandeln hab ich soweit hingekriegt...mein Programm sendet mir auch immer meinen Wert an den PC wenn ich den 2ten Taster druecke...leider funktioniert mein Timer in dem Programm nicht mehr...hab in der ISR die LED eingebaut die doch eigentlich im sekundentakt blinken muesste...warum läuft denn mein Timer nicht mehr...hier mein Programm:


    Vielen Dank und viele Gruesse



    Code:
    //define all external dependencies
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    //-------------------------------------------------------------------------------------------------//
    #ifndef F_CPU
    #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
    #define F_CPU 3686400 // Systemtakt in Hz - Definition als unsigned long beachten
    #endif
    
    #define BAUD 9600UL // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
    
    // Berechnungen
    #define UBRR_VAL (((F_CPU)/(BAUD*16))-1) // clever runden
    #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
    #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille
    
    //#if ((BAUD_ERROR>10) || (BAUD_ERROR<=10))
    //#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
    //#endif
    //-------------------------------------------------------------------------------------------------//
    
    
    
    //declare all used functions
    void Sensor_init(void);
    void LED_SW_init(void);
    void uart_init(void);
    void TIMER2_interrupt_init(void);
    
    //define variables
    
    volatile unsigned int z = 0;
    volatile unsigned int sekunde =0;
    
    void sendString(char* string, int length) {
      for (int c=0; c<length; c++) {
        while (!(UCSRA & (1<<UDRE))) // warten bis Senden moeglich
        {
        }
    
        UDR = string[c];
      }
    }
    
    
    void uart_init(void)
    {
      UCSRB |= (1<<TXEN);  // UART TX einschalten
      UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
     
      UBRRH = UBRR_VAL >> 8;
      UBRRL = UBRR_VAL & 0xFF;
    }
    
    
    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=199;															//alle 0.008 s Interrupt
      TIMSK = (1<<OCIE2);
      }
    
    ISR(TIMER2_COMP_vect)												//LED soll alle 1s leuchten
    {
     z++;
      if(z==72)
      {
        PORTB ^= (1<<PB0);
        sekunde++;
    	z=0;
      }
    
    }
    
    int main(void)
    {
      Sensor_init();
      LED_SW_init();
      uart_init();
      TIMER2_interrupt_init();
      int T1=0;
      int T2=0;
      int TD=0;
      char myTestString[20];	// char-Array deklarieren
      
    
     while(1)
    {
    if(!(PINA & (1<<PINA0))) //Mit Pin 0 soll T1 gespeichert werden
    {
    T1 = sekunde;
    }
    if(!(PINA & (1<<PINA1))) //Mit Pin 1 soll T2 gespeichert werden und die Differenz berechnet werden
    {
    T2 = sekunde;
    TD = T2-T1;
                    
    sprintf(myTestString, "Zeit %d ", TD); // String formatieren
    sendString(myTestString, 10);    // String schicken
    }
     
    }
    }
    
    
    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
    }

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

Labornetzteil AliExpress