- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 7 von 7

Thema: Weis nicht mehr weiter :-(

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2007
    Alter
    41
    Beiträge
    12

    Weis nicht mehr weiter :-(

    Anzeige

    E-Bike
    Hallo Leute,

    Sorry dass ich euch wiedermal auf die Nerwen falle aber ich brauche "mal wieder" eure Hilfe.

    Ich habe folgendes Programm:

    Code:
    // Timer_Interrupt_TEST_2.c Programm //
    
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    int A;
    int Delai;
    
    // Routine d'interruption
    //-----------------------
    
    ISR (TIMER1_COMPB_vect) {
    	if(A==0x00){
    		PORTB=0x05;
    		}
    	
    	if(A==0x01){
    		PORTB=0x00;
    		}
    
    	if(A==0x0A){
    		PORTB=0x0A;
    		}
    
    	if(A==0x0B){
    		PORTB=0x00;
    		}
    
    	A=A++;
    	OCR1B=TCNT1+Delai;
    
    	if(A==0x14){
    		A=0;
    		}
    }
    
    // Programme principal:
    //---------------------
    
    int main () {
    
    	A=0;
    
    	DDRB=0xFF; 				// PORTB mis en sortie
    	DDRC=0xFF;
    
    	Delai=3686000/20/20/165;
    
    
    	TCCR1B=(3<<CS10); 		// timer1 source: ck/64
    
    
    	OCR1B=TCNT1+Delai; 		// initialisation du registre de comparaison
    
    
    	TIMSK|=(1<<OCIE1B); 	// autorisation de l'interruption
    
    	sei (); 				// autorisation de toutes les interruptions
    
    
    while (1){
    		}
    	
    }

    Dieses Program funktioniert auch prima nur ich muss es noch soweit ergänzen , dass die ISR Routine durchlaufen wird wenn PORTA == 0x01 ist.

    d.h. erst wenn Pin 0 am portA betätigt wird, soll die unterrupt routine durchlaufen werden und dann erst beim nachsten betätigen von Pin 0 wieder von vorn durchlaufen werden.



    Dieses Programm soll für eine B2 Schaltung mit Thyristoren sein.
    Am Pin0 vom port A soll ein Rechtecksignal anliegen der immer dann 1 wird, wenn der Nulldurchgang der Positiven halbwelle erfolgt und während 2-5ms anliegt.

    Da der Nulldurchgang aber immer nur 1x pro Periode kommt , soll nach ablaufren der ISR der Programm in der While(1) schleifr "nix tuhn" bis wieder der Pin0 am portA betätigt wird.


    hab es schon mit sei (); in einer If schleife probiert und mit einer cli(); im "if(A==0x14){
    A=0;
    }" probiert, ist aber nix draus geworden

    Ich habe mir überlegt , wenn man eine if schleife schreiben würde, wo man den Timer1 startet und am ende der ISR routine :
    " if(A==0x14){
    A=0;
    }"
    den Timer1 wieder Stoppen würde, dann müsste es gehen, da bei dem nachsten betätigen von Pin0 am PortA der Timer ja wieder gestartet werden würde. Das Problem ist ich weiss nicht wie ich den timer Stoppen und Starten kann.


    Wass kann ich denn jetzt tun


    Ein Newbie fragt den Forengötter um rat.




    Euer Nightlord

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von robocat
    Registriert seit
    18.07.2006
    Beiträge
    935
    eigentlich müsste es ja mit cli(); und sei(); funktionieren. "eigentlich" weil ich das grade nicht testen kann.

    geht sicher geschickter, aber wie wäre das hier:
    Code:
    ISR (TIMER1_COMPB_vect) 
    { 
      if(PINA==1&&A==0x14)
      {
        A=0;
      }
    
      if(A<0x14)
      {
        if(A==0x00)  
        { 
          PORTB=0x05; // könnte man dort einfügen, wo A auf 0 gesetzt wird 
        } 
        
        if(A==0x01)
        { 
          PORTB=0x00; 
        } 
    
        if(A==0x0A)
        { 
          PORTB=0x0A; 
        } 
    
        if(A==0x0B)
        { 
          PORTB=0x00; 
        } 
        A=A++; 
        OCR1B=TCNT1+Delai; 
      }
    }
    der zähler bleibt bei 0x14 stehen, und beginnt erst wieder von 0 aufwärts zu zählen, wenn PINA=1 ist.

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    In die while-Schleife:
    if((PINA(1<<PA0)){
    TCCR1B|=(1<<CS10)|(1<<CS11); //timer start
    }

    Und am Anfang der ISR schreibst du:
    TCCR1B&=(~(1<<CS10)|(1<<CS11)); // timer stopp

    Das ist eine der vielen Möglichkeiten.

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2007
    Alter
    41
    Beiträge
    12

    Es Funzt.

    Jepp es klappt:

    Habe soeben das Program ergänzt und es funktioniert genau so wie ich es möchte.


    Code:
    // Timer_Interrupt_TEST_3.c Programm //
    
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    
    int A;
    int Delai;
    
    // Routine d'interruption
    //-----------------------
    
    ISR (TIMER1_COMPB_vect) {
    
    
    	if(A==0x00){
    		PORTB=0x05;
    		}
    	
    	if(A==0x01){
    		PORTB=0x00;
    		}
    
    	if(A==0x0A){
    		PORTB=0x0A;
    		}
    
    	if(A==0x0B){
    		PORTB=0x00;
    		}
    
    	A=A++;
    	OCR1B=TCNT1+Delai;
    
    	if(A==0x0C){		//0x14
    		A=0;
    	TCCR1B=(0<<CS10); // timer stopp	
    		}
    }
    
    // Programme principal:
    //---------------------
    
    int main () {
    
    	A=0;
    
    	DDRB=0xFF; 				// PORTB mis en sortie
    	DDRC=0xFF;
    
    	Delai=3686000/20/20/165;
    
    	OCR1B=TCNT1+Delai; 		// initialisation du registre de comparaison
    
    	TIMSK|=(1<<OCIE1B); 	// autorisation de l'interruption
    
    	sei (); 				// autorisation de toutes les interruptions
    
    
    while (1){
    
    	if(PINA == 0xFE){ 
    		TCCR1B=(3<<CS10); //timer1 start, timer1 source: ck/64
    		} 
    	}	
    }

    Natürlich währe es ohne eure Hilfe nix geworden.

    Danke normals.

    Dass mit dem

    CS12, CS11, CS10 (Clock Select Bits)
    Diese 3 Bits bestimmen die Quelle für den Timer/Counter:
    CS12 CS11 CS10 Resultat
    0 0 0 Stopp, Der Timer/Counter wird angehalten.
    0 0 1 CPU-Takt
    0 1 0 CPU-Takt / 8
    0 1 1 CPU-Takt / 64
    1 0 0 CPU-Takt / 256
    1 0 1 CPU-Takt / 1024
    1 1 0 Externer Pin T1, fallende Flanke
    1 1 1 Externer Pin T1, steigende Flanke



    hatte ich aus einer anderen Website aber bin gestern einfach nicht darauf gekommen, obwohl es gross draufstand... 0<<CS10 = timer Stopp eieiei


    Naja jetzt gehts ja lol


    Ciao

    Euer Nightlord

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2007
    Alter
    41
    Beiträge
    12

    EIEIEIE

    Hallo leute, ich bin ess schon wieder.

    Unser nächstes Problem besteht darin, dass ich den inhalt vom TCNT1 auf die schnittstelle heraus geben will. Dies geht aber irgendwie nicht so richtig, wie ich mir dass so vorstelle.

    Ein Freund hat diesen Testprogram entwickelt damit der Atmel den eingegebenen text im VBTREM (Sonderprogram) liest und wieder zurückschickt.

    Ich habe lediglich die Rot markierten zeilen eingefügt, um zu testen, ob der Atmel mir dass herrausgibt, wass ich will.

    Das Program funktioniert so:

    Der Atmel fragt immer dien Sendeport ab nach neuen informationen. Wird ein Zeichen zum Atmel gesendet, so speichert er dieser den Wert in den buffer und dann sendet er das Zeichen zur schnittstelle zurück.

    Die rot markierten Zeilen habe ich eingefügt, damit mit der Atmel, bei jedem gesendeten Zeichen diesen durch den Wert von TEST ersetzt und diesen dann zurückschickt anstatt des von mir gesendeten Zeichens.

    kurz:
    Egal welches Zeichen ich in den VBTERM eingebe, soll mir der Atmel den vert von TEST, also 576 zurücksenden.

    VBTERM ist ein program in dem ich die Zeichen (Ziffern oder auch ganze sätze)eingeben kann , die ich dem Atmel senden will.




    Code:
    #include <avr/io.h> 
    #include <inttypes.h> 
    
    
    // Sollte schon im Makefile definiert sein. 
    // In dem Fall hier einfach löschen. 
    #define F_CPU 3686000UL 
    
    #define BAUD 9600UL 
    #define UBRR_BAUD ((F_CPU/(16L*BAUD))-1) 
    
    int TEST;
    
    TEST = 576;
    
    // USART initialisieren 
    void uart_init(void) 
    { 
    // Baudrate einstellen (Normaler Modus) 
    UBRRH = (uint8_t) (UBRR_BAUD>>8 ); 
    UBRRL = (uint8_t)UBRR_BAUD; 
    
    // Aktivieren von receiver und transmitter 
    UCSRB = (1<<TXEN) | (1<<RXEN); 
    
    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit 
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); 
    						//UCSRC |= (1<<URSEL)|(3<<UCSZ0); 
    } 
    
    int main(void) 
    	{
       
    
     
    	uint8_t buffer; 
    
    	// USART initialisieren 
    	uart_init(); 
    
    	while (1) 
    		{ 
    		// Warten bis Daten empfangen wurden 
    		while ( !(UCSRA & (1<<RXC)) ); 
    
    		// Empfangsregister auslesen */
    		buffer = UDR; 
    
    	buffer = TEST;
    
    		// Warten bis der Sendepuffer frei ist 
    		while ( !( UCSRA & (1<<UDRE)) ); 
    
    		// Daten in den Puffer schreiben und damit senden 
    		UDR = buffer; 
    		} 
                    return 0; 
    
    	}

    Nur leider sendet mir der Atmel nicht den Wert von TEST (576) sondern er wandelt diesen Wert in ein ASCII-Zeichen um und sendet mir diesen.


    Beide Programme (also der Sendeprogramm und den Ersten programm für die B2) muss ich anschliesend miteinander verbinden damit der Atmel den erstmals ermittelten wert von TCNT1 schickt.

    Diesen benötige ich, um die Interrupts so genau wie möglich an der Netzfrequez anzupassen.




    Mein Kollege und ich sind schon am verzweiffeln.
    Wenn wir schreiben
    TEST = '576';
    Sendet uns der Atmel , bei jeder eingabe im VBTERM, immer nur die letzte Ziffer, also 6.


    Wass können wir da tun damit der Atmel uns "576" Sendet anstatt irgendwass anderes???






    Euer Nightlord

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.12.2004
    Alter
    40
    Beiträge
    165
    Die Integervariable in einen String umwandeln, und dann diese 3 Zeichen senden.

    Die passende Funktion dazu:
    char* ltoa(long int __val, char *__s, int __radix) klick

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    25.10.2007
    Alter
    41
    Beiträge
    12
    Hm... ich bekomme dass irgendwie nicht hin, weiss echt nicht weiter.

    Solte echt nicht so schwer sein den Wert von TCNT1 zu lesen und abzuschicken.

    P.S. dass mit dem char* ltoa(long int __val, char *__s, int __radix) bekomme ich ebensowenig hin.




    Euer Nightlord

Berechtigungen

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

12V Akku bauen