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


von Holgi G. (bigholgi5)


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

von Kai H. (avrickeler)


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.
1
//----------------------------------
2
//----------------------------------
3
//Communication
4
//----------------------------------
5
#define STAT_HANDSHAKE    0
6
#define PROC_RESERVED_0    1
7
#define PROC_RESERVED_1    2
8
//(Main->Extension)
9
#define PROC_DIGITALOUT    3
10
#define PROC_PWM0    4
11
#define PROC_PWM1    5
12
#define PROC_PWM2    6
13
#define PROC_PWM3    7
14
#define PROC_PWM4    8
15
#define PROC_PWM5    9
16
#define PROC_PWMFREQ    10
17
//----------------------------------
18
//----------------------------------
19
#define VARCOUNT16  11
20
21
u08 Loc_RS232TimeOut=0;
22
s16 Loc_Vars16[VARCOUNT16];
23
s16 Far_Vars16[VARCOUNT16];
24
25
#define UART1_RXDSIZE 80
26
#define UART1_TXDSIZE 80
27
u08 UART1_RXD_BUF[UART1_RXDSIZE];
28
u08 UART1_TXD_BUF[UART1_TXDSIZE];
29
//----------------------------------
30
#define UART1_PROM_SIZE 3+2*VARCOUNT16
31
u08 UART1_PROM_Data[UART1_PROM_SIZE];
32
33
SB_Structure Uart1Buf;
34
35
//---------------------------------------------------------
36
//
37
u08 SeroutStr[UART1_PROM_SIZE];
38
void sendSerialStream(void) {
39
  u08 i=0;  
40
  SeroutStr[0]='S';
41
  SeroutStr[1]='1';
42
  while (i<VARCOUNT16) {
43
    //alle 16ner Variablen
44
    SeroutStr[(i*2)+2]=(Loc_Vars16[i]>>8);
45
    SeroutStr[(i*2)+3]=(Loc_Vars16[i]&0xFF);
46
    i++;
47
  }
48
  SeroutStr[UART1_PROM_SIZE-1]=0;//CRC
49
  i=0;
50
  while (i<UART1_PROM_SIZE-1) {
51
    SeroutStr[UART1_PROM_SIZE-1]^=SeroutStr[i];   
52
    i++;    
53
  }
54
  uart1_send(SeroutStr,UART1_PROM_SIZE);
55
}
56
57
//---------------------------------------------------------
58
//---------------------------------------------------------
59
//RS232
60
u08 parseSerialStream(SB_Structure *SB) {
61
  u08 Result=0;
62
  if ((SB->Buffer[0]=='S')&&(SB->Buffer[1]=='1')) {
63
    if (Loc_Vars16[STAT_HANDSHAKE]<2) //debug
64
      Loc_Vars16[STAT_HANDSHAKE]=2;
65
    u08 CRCOrg=SB->Buffer[UART1_PROM_SIZE-1];
66
    u08 CRCact=0;
67
    u08 i=0;
68
    while (i<UART1_PROM_SIZE-1) {
69
      CRCact^=SB->Buffer[i];
70
      i++;
71
    }
72
    if (CRCOrg==CRCact) {
73
      //CRC OK
74
      i=0;      
75
      while (i<VARCOUNT16) {
76
  //übertragung auf die Variablen
77
  Far_Vars16[i] =(SB->Buffer[(i*2)+2])<<8;
78
  Far_Vars16[i]|=(SB->Buffer[(i*2)+3]);
79
  i++;
80
      }
81
      Loc_RS232TimeOut=0;
82
      Loc_Vars16[STAT_HANDSHAKE]=3;   //wichtig!
83
      Result=1;
84
    }
85
  }
86
  return Result;
87
}
88
89
//---------------------------------------------------------
90
u08 recvRS232Comm(void) {
91
  u08 Result=0;
92
  u08 c=0;
93
  u08 cnt=0;
94
  while ((uart1_receive(&c))&&(cnt++<130)) {
95
    if (Loc_Vars16[STAT_HANDSHAKE]<1) //debug
96
      Loc_Vars16[STAT_HANDSHAKE]=1;
97
    SB_insertToBuffer(&Uart1Buf,c);
98
    Result=parseSerialStream(&Uart1Buf);
99
  }
100
  return Result;
101
}
102
103
//---------------------------------------------------------
104
//call this one in a 100Hz Timer
105
void callForCommInTimer(void) {
106
  if (Loc_RS232TimeOut<50) //500 ms Timeout
107
    Loc_RS232TimeOut++;
108
  else {
109
    if ((Loc_Vars16[STAT_HANDSHAKE]&0x00FF)!=0) {
110
      u08 i=0;
111
      while (i<VARCOUNT16) {
112
  //Reset der Variablen
113
  Far_Vars16[i] =0;
114
  i++;
115
      }
116
    }
117
    Loc_Vars16[STAT_HANDSHAKE]=0;
118
  }
119
}

von Holgi G. (bigholgi5)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.