Relais mittels ATmega8515 und RS232 schalten

OP #790529
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
#790737
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren