Använda seriall port i C

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Använda seriall port i C

Inlägg av net4all »

Hej!
Jag jobbar på att kunna ansluta en PIC till en PC för att bla styra en robot.
All hårdvara fungerar, det är bara mjukvaran till datorn som inte är klar.

Jag har försökt att lära mig hur man ska ta kontroll över serieporten i C, men inte lyckats. Jag vill gärna att det ska fungera på båda tex WinXP och Win98, vilket gör att det blir lite svårare att hitta kod.

Så om någon kunde ge mej en länk eller lite fungerande C-kod så skulle det vara jättebra!

Hittils är det här allt jag lyckats få fram, den lyckas skriva till porten men inte läsa..
(Synpunkter på koden i allmänhet mycket välkommna)

Kod: Markera allt

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
    system("mode com2: baud=9600 parity=n data=8 stop=1");  //COM2 baud-rate och lite annat
    char data_ut='3'; //data att skicka ut till PICen via COM2

    FILE *ut; //Skapa en .... FILE
    ut=fopen("COM2:", "w"); //Öppna COM2

    if(ut==NULL) //Lyckades vi öppna COM2 ?
    {
        printf("FEL: kan inte öppna COM2 för skrivning!");
        exit(0);
    }
    fprintf(ut,"%c", data_ut); //Skriv data till COM2
    close(ut); //Stäng COM2


    FILE *in; //Skapa ny FILE/stream eller vad man nu ska kalla det...
    in=fopen("COM2:", "r"); //Öppna COM2 igen, men nu för läsning

    if(in==NULL) //Lyckades vi öppna COM2 ?
    {
        printf("FEL: kan inte öppna COM2 för läsning!"); //Här går det fel, dvs porten öppnas inte....
        exit(0);
    }

    fscanf(in,"%c", &data_ut); //Ta emot ett tecken från PICen
    printf("%c",data_ut); //Skriv ut till skärmen

    close(in); //Stäng COM2

    return 0; //slut...
}

Användarvisningsbild
strombom
Inlägg: 3305
Blev medlem: 27 maj 2003, 10:50:20
Ort: Västra Götaland
Kontakt:

Inlägg av strombom »

Här är ett program jag gjort för att skicka över en hex-fil till en mikrokontroller:

http://paste.cplusplus.se/paste.php?id=8900

Vet inte om den funkar på win98...
Användarvisningsbild
Icecap
Inlägg: 26612
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Kod: Markera allt

  // Check out COM1 - COM20 if they are available
  for(Counter = 1;Counter <= 20;Counter++)
    {
    sprintf(Text,"COM%u",Counter);
    Handle = CreateFile(Text,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,0,0); // Opens the COMx-port
    if(Handle != INVALID_HANDLE_VALUE)
      {
      cbbCOMport->Items->Add(Text);
      PurgeComm(Handle,PURGE_RXABORT);
      CloseHandle(Handle);
      }
    else
      {
      if(GetLastError() == 5)
        {
        cbbCOMport->Items->Add(Text);
        }
      }
    }
Koden kollar COM1 - COM20 och lägger till en "välj-en"-ruta. När filen väl är öppnat (t.ex. filen "COM3") kan man ställa in alla parameter.

Detta exempel är från Borland C Builder 6 och till det brukar jag använda TpaPro Asynk som är en gratis komponent till serieport.
Användarvisningsbild
Jeppsson
EF Sponsor
Inlägg: 810
Blev medlem: 3 oktober 2005, 18:00:43
Ort: Karlskrona

Inlägg av Jeppsson »

Eftersom du skriver C så har du redan valt kompilator misstänker jag.

Annars kan jag rekommendera C# (C Sharp) där är det busenkelt att få igång serielporten och det finns många exemepl att hitta på både microsofts hemsida och andra sidor på nätet.
Jag har skapat flera program i C# för PCn och i mikroC för PICen som snackar med varandra utan problem via serielporten.

Vet dock inte om de programmen du skapar fungerar i Win98.

Microsoft Visual C# 2008 Express kan laddas ner gratis från microsofts hemsida. :D
Muppis
Inlägg: 275
Blev medlem: 15 februari 2007, 10:26:28
Ort: Halmstad

Inlägg av Muppis »

Angående TS kod, borde det inte fungera med att öppna porten för både skriv och läsning? Ex:

Kod: Markera allt

FILE *com = fopen("COM2:", "r+");
r+ både skriv och läs, w+ är samma sak i detta fall antar jag, annars skapar w+ filen om den inte redan finns.
I windows kan det vara lämpligt att ha med b som tredje bokstav i mode. den öppnar comporten för binär läsning enligt ISO/IEC 9899:1990 (``ISO C90'').
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg av BEEP »

Nu jag vet inte hur det fungerar i C men porten ska väl vara öppen hela tiden tills man stänger applicationen eller byter port. Att du inte kan öppna porten igen beror nog på att du öppnar för snabbt efter du har stängt den så Windows ligger lite efter och har inte stängt porten.
Muppis
Inlägg: 275
Blev medlem: 15 februari 2007, 10:26:28
Ort: Halmstad

Inlägg av Muppis »

När vi ändå pratar om stänga porten, borde det inte vara fclose() istället för close()? fclose() tar en FILE* och close tar en int.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Inlägg av mri »

Här finns ett mycket enkelt bibliotek (Sport.zip filerna sport.c och sport.h) för hantering av COM portar i C/C++ som jag brukar använda. http://www.lin.optimaedu.fi/~mats/misc/
Kompilerar och fungerar under DOS, Windows (95/98/Me/NT/2000/XP) och Linux.
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

Tackar för alla tips, har dock inte hunnit att testa något även om det troligtvis kommer att funger, har även fått hjälp av en kompis på skolan.

Helt plötsligt hade jag 4st uppsatser och ett spanskaprov om en vecka...
:(

(Mitt fel, dålig planering)
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Inlägg av mri »

Så är det ibland.

Ifall du väljer att titta på Sport senare, kommer här ett minimalistiskt exempel. Kan det bli enklare? :)

Kod: Markera allt

#include <stdio.h>
#include "sport.h"

int main()
{
    int i;

    if (SPortOpen(SPORT_COM1, 4, 0x3F8, 9600, 8, SPORT_PARITY_NONE, 1) != 0)
    {
        printf("Unable to open COM1\n");
        return -1;
    }

    // Vänta på att bokstaven 'A' mottas på COM1
    while (SPortReceive(SPORT_COM1) != 'A')
    {
        // Busy wait
    }

    // Skicka ut 100st 'B' på COM1
    for (i=0; i < 100; i++)
    {
        SPortSend(SPORT_COM1, 'B');
    }

    SPortClose(SPORT_COM1);

    return 0;
}
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

Äntligen!
Helt fri :)

Sorry att tråden blev "död" ett tag, men det fanns inte tid..

ON Topic:
Ok, jag har valt "Sport", mri's exempel verkar fungera, har inte testat än.
Men man ska väll inte behöva includera sport.c?
Fanns inte med i din(mri) kod, jag blev tvungen att lägga dit kodstycket "#include "sport.c" för att den skulle hitta ex SPortSend()

Header filen ska väll lägga till .c filen av sig självt, eller?
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Antingen får länkaren länka in sport.obj eller så får du ha
med c file i din källkod. Hur vet den annars att sport.c (eller obj)
ska vara med ?
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Inlägg av mri »

Som sodjan skriver.

Man kan #include'ra själva .c filen, men så brukar man inte göra. Vanligen gör du upp ett "projekt" för din kompilator, var du tar med de .c filer som skall kompileras. Hur man gör upp "projekt" varierar från kompilator till kompilator. Sen kompileras .c filerna separat till .obj filer, vanligen när du väljer "Build all" eller nåt i den stilen, och sen länkas altsammans ihop till en .exe fil av länkaren.

När man #include'rar en .h fil så får kompilatorn all nödvändig information om koden som ligger i den andra .c filen, så att länkaren kan göra sitt jobb senare och koppla ihop alla lösa trådar i .obj filerna.
net4all
Inlägg: 538
Blev medlem: 7 februari 2007, 12:06:34

Inlägg av net4all »

Ok, jag förstår.

Men det här med projekt ligger väll i utvecklingsmiljön och inte i själva kompiliatorn?

Har nu testat mri's exempel, fungerar perfekt :)

Däremot får jag inte exempelfilen "chat.c" att fungera, verkar vara endel funktioner som inte är definerade...
Men jag har includerat sport-filerna...
Förstår inte..
:?
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Däremot får jag inte exempelfilen "chat.c" att fungera, verkar vara endel funktioner som inte är definerade...

I 99 fall av 100 så har du missat att inkludera en h-fil.
Sök i alla h-filer efter den saknade funktionen.

> Men det här med projekt ligger väll i utvecklingsmiljön och inte i själva kompiliatorn?

Hm, "projektet" i utvecklingsmiljön är det som "styr" kompilator och *länkare*.
Eller hur menar du igentligen ?
Skriv svar