Avatar billede snixi Nybegynder
01. maj 2006 - 13:14 Der er 10 kommentarer og
1 løsning

Kvaler med RS-232C

Hej. Jeg har skrevet et stykke kode i C++ som efter min egen overbevisning skulle kunne åbne, lukke, læse og skrive til/fra en com port.
Jeg har testet programmet efter kompilering og har herefter konkluderet at mit program kan åbne, lukke og læse, men ikke skrive til en com port.
Jeg har brugt hyperterminal da jeg skulle teste om der blev skrevet noget til com porten. Portene på de to PC'er kører samme hastighed, ingen paritetsbit, 1 stop bit og sender/modtager 8 bit per dataforsendelse. Endvidere er der ingen hardwarekontrol eller handshake om man vil.

Angiveligt er det min funktion send_com der er noget i vejen med. Er der nogen der kan fortælle mig hvad?

På forhånd tak, hilsen René

--- Min kode er her:

//kompiles i Bloodsheet Dev-C++ 4.9.9.2 eller nyere
#include <stdio.h>
#include <windows.h>

HANDLE hCom;
DWORD dwOldBaudRate;
BYTE cOldByteSize,cOldParity,cOldStopBits;
OVERLAPPED ol;

BOOL open_com(LPCSTR szComName,DWORD dwBaudRate,BYTE cByteSize,BYTE cParity,BYTE cStopBits) { // Typisk: "com1",CBR_9600,8,NOPARITY,ONESTOPBIT
//Åbner porten Com X.
//LPCSTR szComName er den com port der ønskes åbnet. Eksempel: "Com5" ikke 10 og opefter!
//DWORD dwBaudRate indikerer kommunikationshastigheden, eksempel: CBR_9600
//BYTE cByteSize er størrelsen af de strenge der sendes. Eksempel: 8 (Byte)
//BYTE cParity bruges til at sættes paritetsbit op med. Hvis ingen paritetbit --> NOPARITY. Hvis paritetbit --> antal, eksempelvis: 2
//BYTE cStopBits bestemmer antallet af stop bit. Typisk 1
//**************************************************************
  DCB dcb;
  COMMTIMEOUTS cto;
  int i;
  char *c;
  c=(char *)&ol;
  for (i=0; i<sizeof(ol); i++) c[i]=0;
  hCom=CreateFile(szComName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING,NULL);
  if (hCom==INVALID_HANDLE_VALUE) return FALSE;
  if (!GetCommState(hCom,&dcb)) return FALSE;
  dwOldBaudRate=dcb.BaudRate;
  cOldByteSize=dcb.ByteSize;
  cOldParity=dcb.Parity;
  cOldStopBits=dcb.StopBits;
  dcb.BaudRate=dwBaudRate;
  dcb.ByteSize=cByteSize;
  dcb.Parity=cParity;
  dcb.StopBits=cStopBits;
  if (!SetCommState(hCom,&dcb)) return FALSE;
  cto.ReadIntervalTimeout=MAXDWORD;
  cto.ReadTotalTimeoutMultiplier=MAXDWORD;
  cto.ReadTotalTimeoutConstant=1;
  cto.WriteTotalTimeoutMultiplier=0;
  cto.WriteTotalTimeoutConstant=0;
  if (!SetCommTimeouts(hCom,&cto)) return FALSE;
  return TRUE;
}

BOOL read_com(LPSTR lpData,DWORD dwNumber)
//Læser hvad der på porten com X.
//LPSTR lpData bestemmer hvor læste data skal gemmes --> vælges vilkårligt i main.
//DWORD dwNumber er antallet af chars der læses og gemmes ad gangen.
//****************************************************
{
  DWORD dwMask=0,dwRead;
  ol.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
  if (ol.hEvent==INVALID_HANDLE_VALUE) return FALSE;
  if (!SetCommMask(hCom,EV_RXCHAR)) return FALSE;
  Sleep(100);
  WaitCommEvent(hCom,&dwMask,&ol);
  if (dwMask & EV_RXCHAR) if (!ReadFile(hCom,lpData,dwNumber,&dwRead,&ol)) return FALSE;
  if (dwRead!=dwNumber) return FALSE;
  if (!CloseHandle(ol.hEvent)) return FALSE;
  return TRUE;
}

BOOL close_com()
// luk porten efter brug.
//argumenter behøves ikke i main.
{
  DCB dcb;
  if (!GetCommState(hCom,&dcb)) return FALSE;
  dcb.BaudRate=dwOldBaudRate;
  dcb.ByteSize=cOldByteSize;
  dcb.Parity=cOldParity;
  dcb.StopBits=cOldStopBits;
  if (!SetCommState(hCom,&dcb)) return FALSE;
  if (!CloseHandle(hCom)) return FALSE;
  return TRUE;
}

BOOL send_com(char *sendPtr,int antal)
// send et antal karaktere på en seriel port.
// Husk porten skal være åben inden send kan bruges
// Input:
// *sendPtr : Er en pointer til den char string der skal sendes
// antal : Er det antal char der skal sendes
// Output:
// retunere true : Hvis afsendels gik godt
// retunere false : Hvis der ikke blev sendt noget. Når der retuneres false skyldes
// det ofte at porten ikke er åbnet
//*************************************************
{
    DWORD dwBytesWritten;

    if (WriteFile(hCom,sendPtr,antal,&dwBytesWritten,0))
        return TRUE;
    else
        return FALSE;
    if (antal!=dwBytesWritten)
    return FALSE;
}

//********************MAIN******MAIN******MAIN********************
WINAPI WinMain(HINSTANCE h,HINSTANCE hInst,LPSTR s,int q){
  int i;
//  int a;
  BOOL bOK;
  char sendPtr=9;
//  char c=9; //* bruges når jeg vil læse fra en port
//  int a, b;
//  a=7;
  bOK=open_com("com2",CBR_9600,8,NOPARITY,ONESTOPBIT);
  if (!bOK) {
      printf("Kunne ikke åbne porten");
      return 1;
  }
  else {
      printf("Porten blev åbnet \n");
  }
  for (i=0; i<2; i++){
      send_com(&sendPtr,1); //sender det sendPtr peger på
//      if (read_com(&c,1)) {
//        printf("%d ",(int)c); /* Udskriver den som en int */
//      }
      //if (c!=124){
    //          printf("DER ER SENDT NOGET PÅ DIN COM PORT!");
  //system("PAUSE");
  printf("%d sendt paa %d \n", sendPtr, hCom);
  }
 
  close_com();
}
Avatar billede htm Nybegynder
01. maj 2006 - 13:22 #1
prøv og brug GENERIC_WRITE i stedet for GENERIC_READ i din CreateFile...
Avatar billede snixi Nybegynder
01. maj 2006 - 13:30 #2
#htm
Jeg har nu rettet GENERIC_READ til GENERIC_WRITE i min CreateFile, men igen sker der intet på modtagers hyperterminalen
Avatar billede htm Nybegynder
01. maj 2006 - 14:01 #3
ok, den skal i hvert fald være GENERIC_WRITE for at kunne skrive til porten. evt. GENERIC_READ | GENERIC_WRITE for både at kunne læse og skrive.

Jeg har ikke lige tid nu til at kigge på din kode, men prøv og send noget andet end 9, det er decimal 9 og dermed et tegn du ikke kan se i hyperterminal.

Lav gerne din sendPtr om til et char array som eks.

char sendPtr[] = "test";

lav så også send_com om til send_com(&sendPtr,strlen(sendPtr));

Vær desuden også sikker på at hyperterminal er connectet.
Avatar billede snixi Nybegynder
01. maj 2006 - 14:07 #4
#htm
Jeg prøver igen. Tusind tak for hjælpen så langt! Jeg svarer lige tilbage når jeg har testet om det virker.

Venlig hilsen René
Avatar billede snixi Nybegynder
01. maj 2006 - 14:41 #5
#htm
Jeg har taget dine rettelser til efterretning. Derefter har jeg først brugt hyperterminal på begge computer for lige at tjekke at der er "hul" igennem. Det er der!
Men det vil bare ikke virke. *snøft*
Avatar billede htm Nybegynder
01. maj 2006 - 15:11 #6
Prøv og fjern
FILE_FLAG_OVERLAPPED|FILE_FLAG_NO_BUFFERING og erstat det med 0

Nu er kablet tilsluttet til com2 ikke?
Avatar billede snixi Nybegynder
01. maj 2006 - 16:31 #7
Nu kan jeg skrive til porten, men jeg har været nødsaget til at skrive programmet så jeg læser en karakter af gangen og sender den i en while løkke.

Hvorfor nu det?
Avatar billede htm Nybegynder
01. maj 2006 - 17:35 #8
Det er ikke nødvendigt når du bruger WriteFile, med mindre du har angivet en længde på 1.
Brug strlen(sendPtr) som argument...
Avatar billede snixi Nybegynder
02. maj 2006 - 14:01 #9
Hejsa.

Det hele virker nu. Jeg kan sende strings, modtage strings og endvidere hoppe og danse. Tak for hjælpen. Smid et svar og du får pointene :o)

Med venlig hilsen René
Avatar billede htm Nybegynder
02. maj 2006 - 17:33 #10
Super det er jeg glad for at høre.

Men læg selv et svar og tag point. Jeg samler ikke på point.
Avatar billede snixi Nybegynder
04. maj 2006 - 09:57 #11
ok. Mange tak for hjælpen i hvert fald :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester