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
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
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
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.
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
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
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
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:
// 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
//-------------------------------------------------------
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
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
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.