- 3D-Druck Einstieg und Tipps         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 13 von 13

Thema: Zwei getrennt regelbare PWM-Signale an zwei Pins von PortC

  1. #11
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Anzeige

    E-Bike
    Oder du wartest nicht beim Empfang:
    Code:
    // Zeichen empfangen
    int uart_getc_nowait (void)
    {
        if (!(UCSRA & (1<<RXC)))  // warten bis Zeichen verfuegbar
            return  -1
        return (int) UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    Du reagierst dann nur auf die Funktion, wenn sie nicht -1 liefert (ist was anderes als 0xff, daher gibt sie int zurück).

    Mit der Interrupt-Lösung musst du dir auch merken, ob das Zeichen schon ausgewertet wurde, und da reicht 1 Byte auch nicht mehr.
    Disclaimer: none. Sue me.

  2. #12
    Neuer Benutzer Öfters hier
    Registriert seit
    07.02.2006
    Ort
    Weimar
    Beiträge
    19
    Hallo, danke für Eure Hinweise. Ich habe mein Programm jetzt nochmal etwas umdisponiert. Ich habe nun die Taster-Abfrage vollständig herausgenommen und versuche nun die PWM-Signale direkt durch Werte vom PC aus zu steuern. Der PC sendet Werte im Wertebereich von 0-255. Diese Werte sollen auf dem MC über "uart_getc()" der Variable "var" zugewiesen werden. Wenn ich jetzt versuche "OCR1BL = var;" zu setzen, dann funktioniert die Wertzuweisung irgendwie nicht, d.h. die LED ändert wird anfangs angeschaltet und ändert dann aber Ihre Helligkeit nicht mehr. Ich sende die Werte von "var" über "uart_putc(var);" gleich direkt an den PC zurück, um diese zu überprüfen. Sie scheinen soweit in Ordnung zu sein. Warum klappt das dann nicht?
    Wenn ich vom PC aus ein "a" oder ein "b" sende und auf dem MC entsprecht die Variable Status incrementieren bzw. decrementiere und im Folgenden "OCR1AL = status;", dann funktioniert es. Die LED verändert Ihre Helligkeit.

    Hier nochmal mein Programm:
    Code:
    #include <avr/io.h>
    #include <avr/delay.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    
    
    // Delay Funktion
    void delay_ms (uint16_t delay_time)
    {
    	uint16_t k=0;
    	while (k++<delay_time) {}
    
    }
    
    
    // Initialisierung der PWM
    static void enable_pwm(void)
    {
       TCCR1A = 0x00;  //Timer auf 0
       TCCR1B = 0x00;
       
       // PWM: 8-bit, phasenkorrekt 
       TCCR1A |= (1<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<WGM10);  //Timer einstellen
       //TCCR1B |= (1<<CS10) | (1<<CS12);
       //TCCR1B |= (1<<CS10) | (1<<CS11) | (1<<CS12); 
       TCCR1B |= (1<<CS10);  //kein Prescaling
    
    }
    
    
    // Initialisierung UART
    void uart_init (void)
    {
    /* USART-Init 38400 Baud bei 8MHz für Mega32 */
      UCSRB = (1<<RXEN) | (1<<TXEN);
    /* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
      UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
      UBRRH  = 0;                                   // Highbyte ist 0
      UBRRL  = 12;                                  // Lowbyte ist 51 ( dezimal )
    
    }
    
    
    // Zeichen senden
    int uart_putc(unsigned char c)
    {
        while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich */
        UDR = c;                      /* sende Zeichen */
        return 0;
    }
    
    
    // String senden
    void uart_puts (char *s)
    {
        while (*s)
        {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
            uart_putc(*s);
            s++;
        }
    }
    
    
    // Zeichen empfangen 
    uint8_t uart_getc (void)
    {
        while (!(UCSRA & (1<<RXC)));  // warten bis Zeichen verfuegbar
        return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
    }
    
    // Zeichen empfangen
    int uart_getc_nowait (void)
    {
        if (!(UCSRA & (1<<RXC)))  // warten bis Zeichen verfuegbar
            return  -1;
        return (int) UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
    } 
    
    int main(void)
    {
    	uint16_t status=0;
      	uint8_t var;
    
    	DDRA=0;     //PORTA as Input
      	PORTA=255;
      	
      	DDRD |= (1 << PD4);
       	DDRD |= (1 << PD5);
      	
    	uart_init();
    	enable_pwm();
    	
    	
    	/* Loop forever */
    	while (1)
    	{
    	    var = uart_getc();  /// AN DIESER STELLE KOLLIDIERT ES MIT DER PWM
    	    uart_putc(var);
    	    
    	    //... wenn ich ein "a" sende
    	    if (var=='a')
    	    {
    	    	status=status+1;	
    	    	}
    	    //... wenn ich ein "b" sende
    	    if (var=='b')
    	    {
    	    	status=status-1;
    	    	}	
    	    // Ansonsten sende ich Werte von 0-255 (z.B. var=94) 
    	    if ((var!='a') & (var!='b'))
    	    {	
    		OCR1BL = var;  // Kanal 1: direkte Wertzuweisung vom PC aus
    		}
       		
       		OCR1AL = status;  // Kanal 2: Wert von "status"
    
    	}
    }
    Muss ich die Werte erst in einen anderen Datentyp konvertieren? Wenn ja, wie genau muß ich "var" verändern das ich es direkt zuweisen kann? Vielleicht habt Ihr ja eine Idee?

  3. #13
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    1. Die Warteschleife geht so nicht, siehe auch Warteschleife.
    2. Es muss heissen if (...&& ...), siehe auch Bitweise vs._Logische Operatoren.
    3. Konvertieren musst du je nachdem, was du schickst . "255" ist etwas anderes als 255. Ersteres sind 3 oder 4 Byte (4, falls noch ein Endezeichen): 0x32, 0x35, 0x35, 0x00, letzteres ist 0xff. Welche Konvertierungs-Funktionen es gibt, findest du in deiner Doku zur avr-libc (WIN_AVR/doc/avr.libs oder so) oder im Net.
    Disclaimer: none. Sue me.

Seite 2 von 2 ErsteErste 12

Berechtigungen

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

12V Akku bauen