-         

Ergebnis 1 bis 9 von 9

Thema: UART zwischen mega16 und mega48

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    10.02.2007
    Ort
    Brig-Glis
    Alter
    24
    Beiträge
    277

    UART zwischen mega16 und mega48

    Anzeige

    Nabend,

    Ich bin's mal wieder.... Ich bin echt am verzweifeln. Ich versuche nun schon seit Tagen, eine UART Kommunikation zwischen einem ATmega16 und einem ATmega48 zum Laufen zu kriegen....

    Zur Hardware:
    Ich habe die RxD und TxD der jeweiligen Kontrollern über Kreuz miteinander verbunden. Soweit sollte das stimmen.
    Der ATmega16 läuft mit einem externen 16MHz Quarz, der ATmega48 mit einem internen 8MHz Quarz.


    Zur Software:
    Ich verwende die Peter Fleury Libary. Jedoch funtzt garnix. Ich nutze das AVRStudio 4. Die .c und .h sind im selben ordner der jeweiligen Programme, MCU und Freq. sind richtig eingestellt.

    Hier mal die Programme:

    ATmega16 (sender)
    Code:
    #include <stdlib.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include "uart.h"
    
    #ifndef F_CPU
    #define F_CPU 16000000UL
    #endif
    
    #define UART_BAUD_RATE      9600      
    
    
    uint16_t readADC(uint8_t channel)
    {
       uint16_t result;
    
       ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1); // ADC einschalten, prescal /64
       ADMUX = channel; // Kanal wählen
       ADMUX |= (1<<REFS1) | (1<<REFS0); // + interne 2,56V-Referenz
       ADCSRA |= (1<<ADSC); // Konvertierung starten
       while(ADCSRA & (1<<ADSC)); // warten bis Wandlung abgeschlossen
    
       result= ADC; // Ergebnis zwischspeichern
    
       ADCSRA &= ~(1<<ADEN); // ADC ausschalten
    
       return(result); // Ergebnis abliefern
    }
    
    
    
    int main(void)
    {
        unsigned int c;
        char buffer[7];
        int  num=134;
    
    	DDRC = 0x00;
        uint16_t result0 = 0;
       	uint16_t result1 = 0;
        /*
         *  Initialize UART library, pass baudrate and AVR cpu clock
         *  with the macro 
         *  UART_BAUD_SELECT() (normal speed mode )
         *  or 
         *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
         */
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
        
        /*
         * now enable interrupt, since UART library is interrupt controlled
         */
        sei();
        
    
        itoa( num, buffer, 10);   // convert interger into string (decimal format)         
        uart_puts(buffer);        // and transmit string to UART
    
    	while(1)
    	{
    
    		uart_putc('A');
    
    	}
    }

    ATmega48(empfänger)
    Code:
    #include <stdlib.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    
    #include "uart.h"
    
    
    /* define CPU frequency in Mhz here if not defined in Makefile */
    #ifndef F_CPU
    #define F_CPU 8000000UL
    #endif
    
    /* 9600 baud */
    #define UART_BAUD_RATE      9600      
    
    
    int main(void)
    {
        unsigned int c;
        char buffer[7];
        int  num=134;
    
        
        /*
         *  Initialize UART library, pass baudrate and AVR cpu clock
         *  with the macro 
         *  UART_BAUD_SELECT() (normal speed mode )
         *  or 
         *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
         */
        uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
        
        /*
         * now enable interrupt, since UART library is interrupt controlled
         */
        sei();
    
        
    
    	while(1)
        {
    
            c = uart_getc();
            if (c =='A')
            {
               PORTB |= (1<<PB4);
            }
            else
            {
               PORTB &=~ (1<<PB4);   
            }
        }
    }

    Die ADC Initialisierung könnte man auch weglassen, ich habe sie einfach mal da gelassen, weil ich später mit Sharp Sensoren arbeiten möchte.... sollte ja soweit nicht stören.


    Danke im Voraus!

    Mfg JeyBee

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Soweit ich weiss gibt es keine µCs mit internem Quarz. Die AVRs haben einen internen RC oszillator. Die Genauigkeit reicht aber nicht immer für eine zuverlässige UART aus. Gerade bei den neueren µCs ist die Frequenztolleranz größer geworden, bei den alten wie AT90S2313 hats noch fast immer funktioniert.

    Laufen die µCs denn wirklich mit der Gewünschten Frequenz ?

    Ein Test wäre einen Pegelwandler zu nutzen um mit einer bekannt funktionierenden RS232 einen Test durchzuführen um zu sehen welche Seite nicht geht.

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.11.2008
    Ort
    Kapfenberg
    Beiträge
    628
    Fahr mal mit der Baudrate runter auf 2400Baud. Vielleicht hilft das was.

    Grüße
    Thomas

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    10.02.2007
    Ort
    Brig-Glis
    Alter
    24
    Beiträge
    277
    Nabend,

    @Besserwessi: Sry, ich meinte auch einen Internen RC-Oszi
    ist ein externer Quarz nötig?


    @TomEdl: Ich habe die Baud nun auf 2400 runtergeschraubt... aber selbes Ergebnis.


    Ich habe die Hardwareverbingungen nochmal ausgemessen, da stimmt alles. Auch GND wurde zusammengelegt.

    Ich habe nun beide Kontroller (einzeln) eine LED im 1sec. Takt blinken lassen, um zu testen, ob die Taktraten stimmen. -> Die LEDs blinkten im 1Sekunden Takt -> alles I.O.

    Ich weiss echt nicht mehr weiter....


    Mgf JeyBee

  5. #5
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Es wird einfacher wenn man weiss welche Hälfte nicht geht. Deshalb der Tip mit dem Pegelwandler und PC.

    Es kann sein das der interne RC Oszillator zu weit daneben ist für eine UART. Kommt eher selten vor, ist aber bei den tolleranzen möglich. Ein externer Quarz wäre eventuell sinnvoll, vor allem wenn die Temperatur oder Versorgungsspannung nicht stabil sind.

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Von der Oszillator-Problematik mal abgesehen, produziert der Code im Empfänger auch nur ein sehr kurzes Aufblitzen der LED, denn uart_getc wartet nicht auf ein Zeichen. Zusammen mit dem dauernden Senden des 'A' ergibt sich somit nur ein ganz schwaches Glimmen der LED, was vermutlich nur im Dunkeln zu sehen sein wird (wenn überhaupt).

    PS: Ich bin jetzt einfach mal von einer LED an PB4 ausgegangen.
    MfG
    Stefan

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    10.02.2007
    Ort
    Brig-Glis
    Alter
    24
    Beiträge
    277
    Hallo sternst,

    Wie kann ich denn das ändern? Mit einem Delay beim Sender/Empfänger?

    Ich werde heute mal dem ATMega48 auch ein 16MHz Quarz, oder einen RC-Oszillator schenken.

    Mfg JeyBee

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von JeyBee
    Wie kann ich denn das ändern? Mit einem Delay beim Sender/Empfänger?
    Zunächst einmal würde ich den Code im Empfänger ändern. Zum Beispiel:
    Code:
    while(1) {
    
            while ((c = uart_getc()) & UART_NO_DATA);   // warte auf ein Zeichen
    
            switch (c)  {
    
                case 'A':
                    PORTB |= (1<<PB4);
                    break;
    
                case 'B':
                    PORTB &= ~(1<<PB4);
                    break;
            }
    }
    So kannst du die LED mit A ein und mit B ausschalten (oder umgekehrt, je nach dem, wie die LED angeschlossen ist).
    Wenn du jetzt im Sender abwechselnd A und B sendest, blinkt die LED bei 2400 Baud mit 120 Hz. Das sollte dir als halbe Helligkeit erscheinen. Wenn du das Blinken sehen willst, musst du dann noch ein Delay beim Sender einbauen.
    MfG
    Stefan

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    10.02.2007
    Ort
    Brig-Glis
    Alter
    24
    Beiträge
    277
    Nabend,

    Also jetzt funktionierts!

    Vielen Dank an alle!

    Und noch frohe Ostern


    Mfg JeyBee

Berechtigungen

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