- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 5 von 5

Thema: EasyRadio Atmega128

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    09.11.2006
    Ort
    Köln
    Beiträge
    19

    EasyRadio Atmega128

    Anzeige

    Praxistest und DIY Projekte
    Hi,

    habe zwei RN-Mega128Funk-Board und möchte diese über ihr Funkmodul (EasyRadio ER400TRS) miteinander kommunizieren lassen. Leider scheitere ich schon beim senden.
    Muss ich das Funkmodul, wie eine RS232-Schnittstelle, über den UART ansprechen, oder gibt es (wie in Bascom) eine einfache print-Funktion?

    Wäre prima, wenn mir jemand ein bißchen auf die Sprünge helfen kann.

    Gruß Matthias

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.09.2005
    Ort
    Osnabrücker Land
    Alter
    62
    Beiträge
    534
    Das easyfunkmodul wird an die serielle angeschlossen 19200 Baud und gut is ... testen kannst Du es, in dem Du bei einem Modul TXd und Txd verbidnest, dann weißt Du schon mal, ob es funktioniert, wenn Du mit einem Terminal auf der einen Seite probierst .. beachte auf PC-Seite muß ein MAX232 dran .. beachte auch, daß Du es richtig anschließt ... (drum mein Tipp mit dem Echo-Test) ...

    ICh habg hier Module im EInsatz gehen prima .. auch via USB-Adapter ...
    Viel Erfolg,
    Vajk
    Ich kann mir keine Signatur leisten - bin selbständig!

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    09.11.2006
    Ort
    Köln
    Beiträge
    19
    Die Module funktionieren. Da der MAX232 schon auf dem Board vorhanden ist, habe ich das mit nem Bascom-Beispielprogramm schon ausprobiert.
    Mein Problem ist nur die Umsetzung in C. Mit Bascom reicht ne Print #2 Anweisung, doch wie bekomme ich das unter C hin?

    Gruß Matthias

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.09.2005
    Ort
    Osnabrücker Land
    Alter
    62
    Beiträge
    534
    Ach so - o.k. Nun Du mußt entsp. die RS232 - Schnittstelle aktiveren .. wenn Du nur Testdaten in eine Richtung übermitteln willst, reicht es, eine einfache Sendroutine zu definieren ... es gibt auch Biliotheken für C, ich mache sowas aber lieber selber.
    Hier die Codeschnippsel ich gehe davon aus, daß Du Dich in C etwas mehr auskennst, auch wenn Du bisher nix mit der seiellen gemacht hast :

    Du "nur" InitUart aufrufen, neben sonstigen Initialisierungen.

    Code:
    Hier meine Uart.h
    
    #ifndef _uart_h_
    #define _uart_h_
    
    #define TXRXBUFFERMAX 64
    
    #define SlaveUnitID   80
    #define MasterUnitID  110
    
    
    #ifdef _uart_intern_
    
    // private:
    
    volatile byte UART0_rx_byte_flag	= 0;
    volatile byte UART0_rx_byte			= 0;
    volatile byte UART0_transmitting    = 0;
    
    byte UART0_rx_a_pos					= 0;
    byte UART0_rx_array_tmp[TXRXBUFFERMAX + 1];
    
    byte UART0_tx_a_pos					= 0;
    byte UART0_tx_array_tmp[TXRXBUFFERMAX + 1];
    
    void ClearRX(void);
    void ClearRXtmpBuf(void);
    void ClearTransmitting(void);
    
    // public:
    
    byte UART0_rx_array[TXRXBUFFERMAX + 1];
    byte UART0_tx_array[TXRXBUFFERMAX + 1];
    
    // Prototyping
    
    void UART_Init(void);
    byte UART_rx_loop(void);
    void ClearRXBuf(void);
    void SendUart_tx_array(void);
    
    uint16_t crc(char *str);
    byte CheckSlashes(void);
    uint16_t crc_xmodem_update (uint16_t crc, const int8_t daten);
    
    
    #else
    
    // public:
    
    extern byte UART0_rx_array[TXRXBUFFERMAX + 1];
    extern byte UART0_tx_array[TXRXBUFFERMAX + 1];
    
    //extern volatile byte UART0_receiving;
    extern volatile byte UART0_transmitting;
    // Prototyping
    
    extern void UART_Init(void);
    extern byte UART_rx_loop(void);
    extern void ClearRXBuf(void);
    extern void SendUart_tx_array(void);
    
    extern uint16_t crc(char *str);
    extern byte CheckSlashes(void);
    
    
    #endif
    
    #endif
    Code:
    Hier meine Uart.c
    
    #include <inttypes.h>
    #include <avr/io.h>
    #include <avr/signal.h>
    #include <avr/interrupt.h>
    #include <avr/delay.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    //-------------------------------------------------------
    
    #include "basdef_h.h"
    #include "symtrm_h.h"
    
    //-------------------------------------------------------
    
    #define  _uart_intern_
    #include "uart.h"
    
    
    #define UNIT_ID 80
    
    //-------------------------------------------------------
    void UART_Init(void)
    {
    	// Init UART 0
    	//  0 für UART 0
    	
    	/*
    	UCSR0A  = 0x00; // Control und Status Register
    	UCSR0B |= (1 << TXEN)  | (1 << RXEN) | (1 << TXCIE) | (1 << RXCIE); // TXEN=TX an, RXEN=RX an, RXCIE=RXcomplete Int, TXCIE=TXdto.
    	UCSR0C |= (1 << USBS0) | (3 << UCSZ0);  // asyncron 8N1 -> siehe ATmega128.S.191
    	UBRR0H  = 0;
    	UBRR0L  = 25; // 103 für 9600 || 51 für 19200 || 25 für 38400 - alles bezogen auf 16 MHz
    	*/
    	// Ser.Ausgabe => UDR0  = 'a';
    	// Init UART 1
    	UCSR1A  = 0x00; // Control und Status Register
    	UCSR1B |= (1 << TXEN)  | (1 << RXEN) | (1 << TXCIE) | (1 << RXCIE); // TXEN=TX an, RXEN=RX an, RXCIE=RXcomplete Int, TXCIE=TXdto.
    	UCSR1C |= (1 << USBS0) | (3 << UCSZ0);  // asyncron 8N1 -> siehe ATmega128.S.191
    	UBRR1H  = 0;
    	UBRR1L  = 103; // 103 für 9600 || 51 für 19200 || 25 für 38400 || 16 für 57,6k || 12 für 76,8 || 8 für 115,2 - alles bezogen auf 16 MHz
    
    	DDRD |= (1 << DDD5);  // DDD5 als Schaltleitung für TX RS485
    
    	ClearRX();
    	ClearRXtmpBuf();
    }
    
    //-------------------------------------------------------
    void ClearRXtmpBuf(void)
    {
    	memset(UART0_rx_array,		0, TXRXBUFFERMAX + 1);
    	memset(UART0_rx_array_tmp,	0, TXRXBUFFERMAX + 1);
    }
    
    //-------------------------------------------------------
    void ClearRXBuf(void)
    {
    	memset(UART0_rx_array,		0, TXRXBUFFERMAX);
    }
    
    //-------------------------------------------------------
    SIGNAL(SIG_USART1_TRANS) // UART0 TX complete
    {
    	UART0_tx_a_pos++;
    	
    	if(UART0_tx_a_pos < TXRXBUFFERMAX)
    	{
    		if(UART0_tx_array_tmp[UART0_tx_a_pos] == '\0')
    		{
    			ClearTransmitting();
    		}
    		else // näcshtes zeichen senden
    		{
    			UDR1 = UART0_tx_array_tmp[UART0_tx_a_pos];
    		}
    	}
    	else
    		ClearTransmitting();
    }
    
    //-------------------------------------------------------
    void ClearTransmitting(void)
    {
    	UART0_transmitting	= 0;
    	UART0_tx_a_pos		= 0;
    	
    	// switch off the RS485-FLAG
    	PORTD &=~ (1 << DDD5);
    }
    
    //-------------------------------------------------------
    void SendUart_tx_array(void) // sende gefülltes array, \0 muß diesen beenden !!!
    {
    	while(UART0_transmitting);
    	
    	UART0_transmitting	= 1;
    	
    	// switch on the RS485-FLAG
        PORTD |= (1 << DDD5);
    
    	// durch die Übertragung in einen temporären Übertragungspuffer
    	// ist die nächste Füllung schon möglich
    	// mit +1 ist ein abschließendes \0 sichergestellt
    	
    	memset(UART0_tx_array_tmp,	0,				TXRXBUFFERMAX + 1);
    	memcpy(UART0_tx_array_tmp,	UART0_tx_array,	TXRXBUFFERMAX);
    	memset(UART0_tx_array,		0,				TXRXBUFFERMAX + 1);
    	
    	UART0_tx_a_pos		= 0;
    	
    	UDR1			= UART0_tx_array_tmp[UART0_tx_a_pos];
    }
    
    //-------------------------------------------------------
    SIGNAL(SIG_USART1_RECV) // UART0 RX complete
    {
        UART0_rx_byte_flag = 1;
    	UART0_rx_byte      = UDR1;
    	
    	// if(!UART0_receiving)
    	//	UART0_receiving = 1;
    }
    
    //-------------------------------------------------------
    void ClearRX(void)
    {
    	UART0_rx_byte_flag = 0;
    	UART0_rx_byte      = 0;
    }
    
    //-------------------------------------------------------
    byte UART_rx_loop(void)
    {
    	byte rxok    = 0;
    	byte lastrxb = 0;
    
    	if(UART0_rx_byte_flag)
    	{
    		// ankommen Zeichen in puffer schreiben
    		
    		if(UART0_rx_a_pos < TXRXBUFFERMAX)
    		{
    			lastrxb = UART0_rx_byte;
    			
    			UART0_rx_array_tmp[UART0_rx_a_pos] = UART0_rx_byte;
    			UART0_rx_a_pos++;
    			UART0_rx_array_tmp[UART0_rx_a_pos] = 0;
    		}
    		
    		ClearRX();
    	}
    	
    	if((UART0_rx_a_pos >= TXRXBUFFERMAX) || (lastrxb == '>')) // Endezeichen oder Pufferüberschrietung
    	{
    		memset(UART0_rx_array, 0, TXRXBUFFERMAX);
    		memcpy(UART0_rx_array, UART0_rx_array_tmp, UART0_rx_a_pos + 1);
    		
    		UART0_rx_a_pos  = 0;
    		
    		memset(UART0_rx_array_tmp,	0, TXRXBUFFERMAX);
    		
    		rxok = 1;
    	}
    
    	return(rxok);
    }
    Du mußt dann nur einfach ins UART0_tx_array

    Code:
    Zum Datensenden:
    
    			sprintf(UART0_tx_array, "</%03d/%03d/%03d/%03d/%05d/", (int)SlaveUnitID, (int)MasterUnitID, (int)sequenzid, Hold_type, Hold_val);
    			uint16_t crc_ist = crc(UART0_tx_array);
    			sprintf(strchr(UART0_tx_array, 0), "%05u/>", crc_ist);
    			SendUart_tx_array();

    In der Hauptschleife von main erfolgt dann noch ein

    Code:
    			if(UART_rx_loop())
    			{
    				UART_DATA_Auswertung();
    			}		
    
    mit entsprechender Datenstringauswertung:
    
    void UART_DATA_Auswertung(void)
    {
    	if(UART0_rx_array[0] == '<') // Startzeichen
    	{
    ...
    	}
    	ClearRXBuf();
    }
    Ich benütze gerne sprintf - funktionen, wenn es weder Zeit- noch Platzkritisch ist ....



    Was auch geht - zum Einseitigen senden:
    in main gleich am Anfang:

    fdevopen(uart_putchar, NULL, 0); // 4 debugging -> use printf

    die Initialsieriung der Baudrate:

    Code:
    	// Init UART 0
    
    	UCSRA  = 0x00; // Control und Status Register
    	// UCSRB |= (1 << TXEN) | (1 << RXEN) | (1 << TXCIE) | (1 << RXCIE); // TXEN=TX an, RXEN=RX an, RXCIE=RXcomplete Int, TXCIE=TXdto.
    	UCSRB |= (1 << RXEN) | (1 << RXCIE); // | (1 << TXEN) | (1 << TXCIE)  // TXEN=TX an, RXEN=RX an, RXCIE=RXcomplete Int, TXCIE=TXdto.
    	UCSRC |= (1 << USBS) | (3 << UCSZ0);  // asyncron 8N1 -> siehe ATmega128.S.191
    	UBRRH  = 0;
        #define USART_BAUD_RATE		19200
    	#define USART_BAUD_SELECT	(F_CPU/(USART_BAUD_RATE*16l)-1)  
    	UBRRL = (unsigned char) USART_BAUD_SELECT;
    	// UBRRL  = 51; // 103 für 9600 || 51 für 19200 || 25 für 38400 || 16 für 57,6k || 12 für 76,8 || 8 für 115,2 - alles bezogen auf 16 MHz
    und irgendwo noch ein
    Code:
    //-------------------------------------------------------
    int uart_putchar(char c)
    {
      if (c == '\n')
        uart_putchar('\r');
      loop_until_bit_is_set(UCSRA, UDRE);
      
      UDR = c;
      
      return 0;
    }

    und dann eben ein printf() .. da ja die Ausgabe an die stdout umgelenkt wird ...

    sind alles Codeschnippsel aus funktionierenden Programmen heraus ...
    .. ich verwende inzwischen immer die Baudrateninit via dem
    #define USART_BAUD_SELECT ....
    so muß man weniger Datenblattnachschlagen

    Hoff DU kommst damit zurecht und findest Dich rein ..

    Liebe Grüße
    Vajk
    Ich kann mir keine Signatur leisten - bin selbständig!

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    09.11.2006
    Ort
    Köln
    Beiträge
    19
    Hallo Vajk,

    vielen Dank schon mal für deine Hilfe. So ganz fit bin ich in C noch nicht, da ich mich noch nicht so lange damit beschäftige. Aber ich denke deine Codes helfen mir schon einmal weiter. Muss mich halt erst einmal einlesen...

    Gruß Matthias

Berechtigungen

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

Solar Speicher und Akkus Tests