hamradioshop.ro
Articole > Software pentru radioamatori Litere mici Litere medii Litere mari     Comentati acest articol    Tipariti

Programarea porturilor seriale sub Windows API

Bernardt Huth YO2CMI

Porturile seriale ( COM ) pot fi folosite in aplicatiile radioamatorilor ca comanda PTT, interfata CW, interfata CAT, comanda rotor e.t.c.
1. PTT & CW
La portul serial este vorba de standardul RS232, deci e nevoie de o mica interfata pentru a conecta portul cu transceiverul.
Interfata cea mai simpla consta dintr-un transistor de tip npn plus doua rezistente.
Mai indicat este desigur folosirea unui optocuplor.
De obicei se foloseste semnalul RTS pentru a actiona PTT-ul respectiv semnalul DTR pentru telegrafie.
Daca portul are o mufa de tip DB-9 atunci DTR este pe pinul 4, RTS pe pinul 7 , ground pe pinul 5.
Majoritatea PC-urilor moderne nu mai sunt dotate ca hardware cu un port serial, in acest caz fiind nevoie de un convertor USB / serial. Aceste interfete au de obicei atasat si un program cu care se poate crea un port serial virtual.
Din punct de vedere al programarii in C++ ca la orice interfata ( video, imprimanta e.t.c.) trebuie aflat intai contextul dispozitiv ( device context ).

hCom = CreateFile("COM1",
GENERIC_READ | GENERIC_WRITE,
0, NULL,
OPEN_EXISTING,
0, NULL)

De asemenea trebuie initializata structura de date afiliata acestui context.

GetCommState(hCom, &dcb)

Aceasta structura are denumirea DCB si contine elementele necesare pentru comunicatia seriala.
Pentru a seta semnalul DTR sau RTS folosim comenzile:

dcb.fDtrControl = DTR_CONTROL_ENABLE
dcb.fRtsControl = RTS_CONTROL_ENABLE

Pentru a dezactiva aceste semnale folosim comanda:

dcb.fDtrControl = DTR_CONTROL_DISABLE
dcb.fRtsControl = RTS_CONTROL_DISABLE

Aceste setari devin active abia dupa comanda:

SetCommState(hCom, &dcb)

Programul demonstrativ atasat comanda separat PTT-ul si portul de telegrafie.
Programul are inclusa si o mica subrutina de CW care transmite TEST.
Pentru temporizare am folosit TIMER-ul pus la dispozitie de Windows.
Timerele se programeaza cu comanda:

SetTimer (hwnd, 1, 1000, NULL)

Unde 1 reprezinta primul TIMER si 1000 unitatile de timp in ms.
Windows va genera la intervale regulate mesajul WM_TIMER.
Acest mesaj se foloseste pentru a sincroniza transmisia CW.

2. CAT ( computer aided transceivercontrol )
Aici lucrurile se complica fiindca pe langa legatura fizica ( nivelul 1 ) intre PC si transceiver avem si comenzi specifice de transmis / receptionat ( protocol ).
La nivel fizic ( RS232 ) trebuie sa programam viteza de trasnmisie, marimea byte-ului, paritatea e.t.c.
Pentru transceiverul meu , un ICOM IC-736 secventa de program arata in felul urmator:

SetupComm(hCom, 128, 128); // buffer sizes
dcb.BaudRate = 1200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = TWOSTOPBITS;
dcb.fAbortOnError = TRUE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
SetCommState(hCom, &dcb);

Problema ce am avut-o la ICOM IC-736 e ca in manualul de utilizare nu scrie nimic despre protocolul folosit. HI.
A trebuit sa pornesc de la premiza ca acest protocol seamana de la un ICOM la altul.
Asa am gasit spre exemplu pentru un IC-7000 ca daca vreau sa aflu frecventa actuala trebuie sa transmit urmatoarea secventa ( in format hexa ):

0xFE, 0xFE, 0x04, 0xE0, 0x03, 0xFD

unde 04 este adresa de la transceiverul IC-736, E0 adresa de la controlerul CI-V, 03 comanda specifica pentru aflarea frecventei, FD sfarsitul comenzii.
Scrierea in bufferul de transmisie se face cu comanda:

WriteFile(hCom, secventa_de_comanda, 6, &iBytesWritten, NULL)

Din diferite motive s-ar putea sa apara time-out-uri ( intreruperi in procesul de transmisie / receptie ). Din aceasta cauza in program compar intotdeauna numarul de octeti ce trebuie transmis cu numarul de octeti efectiv transmis.

Citirea bufferului de intrare se face cu comanda ReadFile.
La progamul demonstrativ citirea se efectueaza octet cu octet.

Ca raspuns la comanda WriteFile am gasit in buffer-ul de intrare urmatoarea secventa ( in format hexa ):

FE FE 4 E0 3 FD FE FE E0 4 3 90 17 25 14 0 FD

Analizand mai atent acest sir si comparandu-l cu ce am avut afisat pe displayul de la transceiver nu am putut exclama decat Evrika.
Pe display era afisat 1425179.

Transmisia frecventei intre PC si transceiverul ICOM se face in format BCD ! Pe fiecare 4 biti dintr-un byte este memorata o cifra.
De asemenea se transmite mai intai byte-ul cu zecile de Hz.
Asta se intampla si in cazul cand vrem sa modificam frecventa de la transceiver printr-o comanda de la PC ( comanda 0x05 ).
Pentru a afla modul de lucru folosim secventa:

0xFE, 0xFE, 0x04, 0xE0, 0x04, 0xFD

Raspuns: FE FE E0 4 4 0 1 FD

Cifra din byte-ul nr. 6 are urmatoarea semnificatie:
00 - LSB, 01-USB, 03-CW.

Desigur ca la alte tipuri de transceivere va trebui adaptat totul incepand cu viteza de transmisie, adresa si terminand cu secventele de comanda.
Pentru IC-7000 nu trebuie schimbata viteza deoarece transceiverul isi adapteaza automat rata la cea a PC-ului, adresa initiala ( 70 hexa ) poate fi schimbata la transceiver in 04 hexa sau in program.
La transceiverul deja devenit clasic FT-1000MP Mark V viteza de comunicatie este de 4800. La acest transceiver nu este nevoie de un controler ca la ICOM, el fiind dotat direct cu o iesire de tip RS232.
Fiind alta firma protocolul folosit arata complet altfel.
Secventa de comanda consta din cinci octeti. Comanda propriu zisa se afla in ultimul octet, primii patru octeti fiind folositi pentru transmiterea de date suplimentare.
Daca vrem sa aflam frecventa VFO-ului A secventa de comanda va arata in felul urmator:

0x00 0x00 0x00 0x02 0x10

unde 10 hexa este comanda specifica pentru aflarea frecventei.
In acest caz vom primi ca raspuns de la transceiver un sir de 16 octeti.
Pentru a calcula frecventa ne intereseaza doar octetul 2, 3, 4 si 5. Desigur ca si aici cifrele sunt memorate pe cate 4 biti.
Frecventa = 1048576*octet2 + 65536*octet3_H + 4096*octet3_L + 256*octet4_H + 16*octet4_L + octet5_H
H-cei patru biti ( Nibble ) superiori, L-cei patru biti inferiori
Pe primul octet al sirului receptionat este codat segmental de banda iar pe octetul opt se afla modul de lucru. El este codat pe ultimii trei biti.
Pentru editare, compilare, link folosesc ca program de baza Code::Blocks care la randul sau apeleaza la Microsoft Visual C++ Toolkit 2003 si Microsoft Platform SDK.

Fisiere care se pot descarca:

  • cat_ic_736.cpp
  • cat_ic_736.exe
  • serialport_com1.cpp
  • serialport_com1.exe

    Bernardt Huth YO2CMI

    Articol aparut la 7-1-2008

    12827

    Inapoi la inceputul articolului
  • Comentarii (2)  

  • Postat de TAMAS Cosmin - YO4HSP la 2008-01-07 12:48:01 (ora Romaniei)
  • interesant articol.
    am studiat mult problema programarii porturilor, mai ales cand a fost facuta trecerea de la win 98 la win xp in urma cu 4-5 ani. folosind mediul c++ (dos) sau c builder (windows poo) porturile (serial sau paralel) nu pot fi accesate de catre windows. sunt necesare programe add-on la softul scris de noi sau tip *.dll care permit accesul acestor resurse chiar de sub mediul win xp, vista, 2000.
    sub win api se poate scrie un soft complet pentru a accesa aceste resurse. am realizat tot felul de comenzi folosind portul paralel si serial. pentru cei interesati de c builder, c++ sau interfete , va pot sta la dispozitie cu informatii practice.

    inca o data ma bucur ca sunt abordate si astfel de articole, chiar ar putea fi scrise si legat de microcontrolere sau FPGA-uri..

    cu respect, tamas cosmin - yo4hsp

  • Postat de Cristian - YO4UQ la 2008-01-09 07:31:58 (ora Romaniei)
  • Foarte frumoasa si competenta disectie... Precum si rezultatul operatiei! Felicitari!

    Scrieti un mic comentariu la acest articol!  

    Opinia dumneavoastra va aparea dupa postare sub articolul "Programarea porturilor seriale sub Windows API"
    Comentariul trebuie sa se refere la continutul articolului. Mesajele anonime, cele scrise sub falsa identitate, precum si cele care contin (fara a se limita la) atac la persoana, injurii, jigniri, expresii obscene vor fi sterse.
    Comentariu *
     
    Trebuie sa va autentificati pentru a putea adauga un comentariu.


    Opiniile exprimate în articole pe acest site aparţin autorilor şi nu reflectă neapărat punctul de vedere al redacţiei.

    Copyright © Radioamator.ro. Toate drepturile rezervate. All rights reserved
    Articole | Concursuri | Mica Publicitate | Forum YO | Pagini YO | Call Book | Diverse | Despre Radioamator.ro | Contact