mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Relais mittels ATmega8515 und RS232 schalten


Autor: Holgi Gross (bigholgi5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich komme mit einem warscheinlich ganz einfachen Problem zu euch, ich 
möchte mit meinem ATMega128 über den Seriellen Port auf eine kleine 
Platine auf der ein Max223 und ein ATmega 8515 drauf ist zugreifen und 
dieser 8515 soll mir dann 12 relais schalten. 4 der Pins sollen noch zur 
adress eingabe mittels DIP swich benutzt werden.
Hat jemand von euch einen code der die Seriellen Daten empfängt, den 
stream mit der eingestellten Adresse vergleicht und gegebenenfalls die 
entsprechenden Bits am Ausgang aktiviert? Währe über jeden Tip froh.
Danke euch vielmals.
LG
Holgi

Autor: Kai Hofmann (avrickeler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also für Dein Problem gibt's wahrscheinlich keine fertige 
maßgeschneiderte Lösung, da das Problem zu benutzerspezifisch ist.

Hast Du denn schon die Kommunikation zwischen den beiden µC überprüft, 
so dass die Kommunikation stabil und (wenigstens das Empfangen) im 
Interrupt funktioniert?

Das wäre der erste Schritt. Danach kannst Du auf diese Funktionen ein 
eigenes Transport-Protokoll aufsetzen. Mit Start/Stop/CRC-Zeichen, je 
nach Anforderung an Datensicherheit etc.

Wahrscheinlich ist das was hiernachkommt für 12 Relais total 
überdimensioniert, aber ich hab's halt noch hier ;-)
Fürs reine Transport-Protokol ein Ausschnitt (für signed 16-Bit Worte), 
mehr zum Ansatz für ein eigenes Protokoll...

Features:
- komplettes Variablenarray kann gesendet werden
- Handshake
- Timeout mit Variablenrücksetung
- gleichberechtigte Kommunikation (nicht Master/Slave)
  (fernes Gerät sollte nach Erhalt seine VariablenListe schicken, also 
fürs  Handshake)
- beide Kommunikationspartner müssen die gleiche Arraylänge senden, 
dafür kann aber der Code gemeinsam verwendet werden.

Bemerkung:
Die SB_Structure ist nur reine u08-Pufferverwaltung mit fester Größe: 
Zeichen ans Ende anfügen, Counter erhöhen, am Ende des Puffers erstes 
Zeichen löschen und Neues am Ende einfügen etc.

//----------------------------------
//----------------------------------
//Communication
//----------------------------------
#define STAT_HANDSHAKE    0
#define PROC_RESERVED_0    1
#define PROC_RESERVED_1    2
//(Main->Extension)
#define PROC_DIGITALOUT    3
#define PROC_PWM0    4
#define PROC_PWM1    5
#define PROC_PWM2    6
#define PROC_PWM3    7
#define PROC_PWM4    8
#define PROC_PWM5    9
#define PROC_PWMFREQ    10
//----------------------------------
//----------------------------------
#define VARCOUNT16  11

u08 Loc_RS232TimeOut=0;
s16 Loc_Vars16[VARCOUNT16];
s16 Far_Vars16[VARCOUNT16];

#define UART1_RXDSIZE 80
#define UART1_TXDSIZE 80
u08 UART1_RXD_BUF[UART1_RXDSIZE];
u08 UART1_TXD_BUF[UART1_TXDSIZE];
//----------------------------------
#define UART1_PROM_SIZE 3+2*VARCOUNT16
u08 UART1_PROM_Data[UART1_PROM_SIZE];

SB_Structure Uart1Buf;

//---------------------------------------------------------
//
u08 SeroutStr[UART1_PROM_SIZE];
void sendSerialStream(void) {
  u08 i=0;  
  SeroutStr[0]='S';
  SeroutStr[1]='1';
  while (i<VARCOUNT16) {
    //alle 16ner Variablen
    SeroutStr[(i*2)+2]=(Loc_Vars16[i]>>8);
    SeroutStr[(i*2)+3]=(Loc_Vars16[i]&0xFF);
    i++;
  }
  SeroutStr[UART1_PROM_SIZE-1]=0;//CRC
  i=0;
  while (i<UART1_PROM_SIZE-1) {
    SeroutStr[UART1_PROM_SIZE-1]^=SeroutStr[i];   
    i++;    
  }
  uart1_send(SeroutStr,UART1_PROM_SIZE);
}

//---------------------------------------------------------
//---------------------------------------------------------
//RS232
u08 parseSerialStream(SB_Structure *SB) {
  u08 Result=0;
  if ((SB->Buffer[0]=='S')&&(SB->Buffer[1]=='1')) {
    if (Loc_Vars16[STAT_HANDSHAKE]<2) //debug
      Loc_Vars16[STAT_HANDSHAKE]=2;
    u08 CRCOrg=SB->Buffer[UART1_PROM_SIZE-1];
    u08 CRCact=0;
    u08 i=0;
    while (i<UART1_PROM_SIZE-1) {
      CRCact^=SB->Buffer[i];
      i++;
    }
    if (CRCOrg==CRCact) {
      //CRC OK
      i=0;      
      while (i<VARCOUNT16) {
  //übertragung auf die Variablen
  Far_Vars16[i] =(SB->Buffer[(i*2)+2])<<8;
  Far_Vars16[i]|=(SB->Buffer[(i*2)+3]);
  i++;
      }
      Loc_RS232TimeOut=0;
      Loc_Vars16[STAT_HANDSHAKE]=3;   //wichtig!
      Result=1;
    }
  }
  return Result;
}

//---------------------------------------------------------
u08 recvRS232Comm(void) {
  u08 Result=0;
  u08 c=0;
  u08 cnt=0;
  while ((uart1_receive(&c))&&(cnt++<130)) {
    if (Loc_Vars16[STAT_HANDSHAKE]<1) //debug
      Loc_Vars16[STAT_HANDSHAKE]=1;
    SB_insertToBuffer(&Uart1Buf,c);
    Result=parseSerialStream(&Uart1Buf);
  }
  return Result;
}

//---------------------------------------------------------
//call this one in a 100Hz Timer
void callForCommInTimer(void) {
  if (Loc_RS232TimeOut<50) //500 ms Timeout
    Loc_RS232TimeOut++;
  else {
    if ((Loc_Vars16[STAT_HANDSHAKE]&0x00FF)!=0) {
      u08 i=0;
      while (i<VARCOUNT16) {
  //Reset der Variablen
  Far_Vars16[i] =0;
  i++;
      }
    }
    Loc_Vars16[STAT_HANDSHAKE]=0;
  }
}


Autor: Holgi Gross (bigholgi5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WOW, saugeil :)
werde es mal leicht abändern (handshake brauche ich zur zeit nicht) und 
werde es mal auf der ersten Platine testen (später werden es dann mal 8 
parallel mit unterschiedlichen Adressen)
Danke dir vielmals
LG
Holgi

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.