Forum: Mikrocontroller und Digitale Elektronik Kommandos elegant auswerten, aber wie?


von Elias B. (bouni)


Lesenswert?

Hallo allerseits,

ich habe ein Programm geschrieben um einen Getränkeautomaten über die 
Serielle Schnittstelle anzusprechen um ihn Getränke ausgeben zu lassen.
Das funktioniert auch schön, der Code gefällt mir aber nicht.

Ich werte fortlaufend ein Byte aus dem Ringpuffer aus, bis ein Kommando 
kommt das für mich bestimmt ist. Dann springe ich in die entsprechende 
Funktion und werte die nächsten paar Bytes aus die laut Spezifikation 
des MDB Protokolls kommen sollten und bile die Checksumme.

Hier am Beispiel der Reset Funktion
1
/*
2
 * MDB Setup Function
3
 */ 
4
uint8_t mdb_setup(void){                 
5
  //wait until data is in buffer
6
  while(mdb_read_buffer() != 1);  
7
  // read subcommand
8
  uint8_t subcmd = mdb_data;
9
  // Subcommand is Setup data
10
  if(subcmd == 0x00){
11
    uint8_t checksum = 0;
12
    checksum += MDB_SETUP;
13
    checksum += subcmd;
14
        
15
    while(mdb_read_buffer() != 1);  
16
    vmc_cfg_data.feature_level = mdb_data;
17
    checksum += mdb_data;
18
  
19
    while(mdb_read_buffer() != 1);  
20
    vmc_cfg_data.display_cols = mdb_data;
21
    checksum += mdb_data;
22
    
23
    while(mdb_read_buffer() != 1);  
24
    vmc_cfg_data.display_rows = mdb_data;
25
    checksum += mdb_data;
26
27
    while(mdb_read_buffer() != 1);  
28
    vmc_cfg_data.display_info = mdb_data;
29
    checksum += mdb_data;
30
31
    while(mdb_read_buffer() != 1);  
32
    if(checksum != mdb_data){
33
      vmc_cfg_data.feature_level  = 0;    
34
      vmc_cfg_data.display_cols   = 0;    
35
      vmc_cfg_data.display_rows   = 0;    
36
      vmc_cfg_data.display_info   = 0;  
37
      return 0;    
38
      }
39
40
    mdb_usart_send_char(0x01,0x00);     // Send Cashless Device SETUP data
41
    mdb_usart_send_char(0x01,0x00);     // Send Cashless Device Feature Level
42
    mdb_usart_send_char(0x19,0x00);     // Send Cashless Device Country Code Highbyte
43
    mdb_usart_send_char(0x78,0x00);     // Send Cashless Device Country Code Lowbyte
44
    mdb_usart_send_char(0x05,0x00);     // Send Cashless Device Scale Factor
45
    mdb_usart_send_char(0x02,0x00);     // Send Cashless Device Decimal Places
46
    mdb_usart_send_char(0x05,0x00);     // Send Cashless Device App max Response Time (10sec)
47
    mdb_usart_send_char(0x00,0x00);     // Send Cashless Device Misc Options
48
    mdb_usart_send_char(0x9F,0x01);     // Send checksum
49
50
    while(mdb_read_buffer() != 1);  
51
    // If ACK is received
52
    if(mdb_data == 0x00){ return 1; }
53
    return 0;
54
  }
55
56
/*
57
 * Weiterer Code . . .
58
 */
59
  return 0;  
60
}

geht es nicht irgendwie schöner, als immer ein Byte zu lesen, es zu 
speichern und der Checksumme hinzuzuaddieren* und dan wieder das nächste 
Byte zu lesen?

Danke schon mal für die Antworten :)

Gruss Elias



* Die Cheksumme bildet sich bei MDB nur durch addition aller Bytes

von Peter D. (peda)


Lesenswert?

Ich würde fürs Empfangen und Senden einen FIFO einrichten.
Und den Empfang würde ich erst auswerten, nachdem ein komplettes Paket 
eingegangen ist. Dazu muß man aber das Protokoll kennen, wie ein Paket 
aufgebaut ist.
Dann kann man in der Zwischenzeit andere Tasks ausführen und die CPU 
bleibt nicht hängen, wenn der Empfang gestört ist.
Und man hat keinen unhandlichen Spaghetticode.


Peter

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.