Forum: PC-Programmierung Serielle Schnittstelle CreateFile


von Bernd.H (Gast)


Lesenswert?

Hallo,
ich versuche ein Programm zu schreiben
mit dem ich ein INT-Wert abfagnen kann, der von einem Atmega gesendet 
wurde.
Das ganze versuche ich mit Createfile
1
#include <iostream>
2
#include <Windows.h>
3
4
using namespace std;
5
6
HANDLE hSerial;
7
8
bool init_com();
9
10
int main()
11
{
12
  DWORD  iBytesWritten;
13
    DWORD  iBytesReceived;
14
  int i = 0;
15
  unsigned char ucMsg = 0x24;
16
  char daten[10000];
17
    int j = 0;
18
  i = init_com();
19
  if(i == 1)
20
  {
21
    cout << "Initalisierung erfolgreich\n";
22
  }
23
24
  if(i == 0)
25
  {
26
    cout << "Initalisierung fehlgeschlagen\n";
27
  }
28
29
  
30
31
  system("pause");
32
  return 0;
33
}
34
35
bool init_com()
36
{
37
  DCB dcb;
38
  WCHAR* portname = L"COM3";
39
40
  hSerial = CreateFile(portname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
41
  
42
43
  GetCommState (hSerial, &dcb);    
44
  dcb.BaudRate  = 9600;        
45
  dcb.ByteSize  = 8;        
46
  dcb.Parity    = NOPARITY;    
47
  dcb.StopBits  = ONESTOPBIT; 
48
  SetCommState (hSerial, &dcb);  
49
50
  if(hSerial == INVALID_HANDLE_VALUE)
51
  {
52
    return false;
53
  }
54
  else
55
  {
56
    return true;
57
  }
58
}

Als Nachricht bekomme ich erfolgreich verbunden. Aber wie kann ich jetzt 
daraus Werte lesen ?
Kann man das überhaubt mit Createfile machen oder musst ich QT o.ä. 
benutzen?

von Timmo H. (masterfx)


Lesenswert?

Na wie bei CreateFile üblich mit ReadFile.
Also z.B.
1
char ucMsg[64] = {0};
2
DWORD iBytesRead;
3
4
....
5
6
if(!ReadFile(hSerial, ucMsg, 64, &iBytesRead, NULL)){
7
      printf("ERROR");
8
      CloseHandle (hSerial);
9
      return 0;
10
}
11
if(iBytesRead >= 1){
12
  //mach was mit ucMsg
13
}

Steht ja auch alles hier: 
http://msdn.microsoft.com/en-us/library/ff802693.aspx

von Bernd.H (Gast)


Lesenswert?

Okay jetzt, werden immer 4 Werte erfolgrech empfangen
danach kommen komische strichförmige Zeichen:
1
while(1)
2
  {
3
     if(!ReadFile(hSerial, ucMsg, 64, &iBytesRead, NULL)){
4
     cout << "ERROR!";
5
           CloseHandle (hSerial);
6
           return 0;
7
           }
8
           if(iBytesRead >= 1){
9
           cout << ucMsg;
10
           }
11
12
        }

von Peter II (Gast)


Lesenswert?

Bernd.H schrieb:
> Okay jetzt, werden immer 4 Werte erfolgrech empfangen
> danach kommen komische strichförmige Zeichen:

klar, weil ucMsg nicht 0 terminiert ist.

von bluppdidupp (Gast)


Lesenswert?

Du solltest vllt. iBytesRead auch beachten und vor der Ausgabe als 
Zeichenkette an entsprechender Stelle ein Nullterminierungszeichen 
einfügen.
In iBytesRead steht nach dem Aufruf von ReadFile() drin wieviele Bytes 
in den Puffer ucMsg geschrieben wurden. In den übrigen ungenutzten Bytes 
im Puffer könnte irgendwelcher Blödsinn stehen.

Achtung: Wenn der µC 4 Bytes gesendet hat, können die auf PC-Seite auch 
fragmentiert eintrudeln, z.B. so:
1. ReadFile()-Aufruf: iBytesRead=1
2. ReadFile()-Aufruf: iBytesRead=1
3. ReadFile()-Aufruf: iBytesRead=2

von Bernd.H (Gast)


Lesenswert?

Ok wie kann ich das jetzt so umschreiben, das immer genau ein Wert 
gesendet wird.
Hier ein Beispiel was ich senden möchte und zwar sende ich den ADC Wert 
eines Fotosensor das sieht dan z.B.: so aus:
1
ADC-Wert: 665

Ich möchte diesen Wert einzelnd ausgeben

von Timmo H. (masterfx)


Lesenswert?

Ja dann packe die beiden empfangenen bytes (sofern du sie als int 
sendest) entsprechend in einen int auf dem pc und gib es aus. Wenn du es 
vom uC schon als ascii sendest dann würde ich dem uc auch gleich die 
nullterminierung schicken lassen (auf länge und nullterminierung prüfen 
solltest du aber trotzdem)

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.