RS 232 pod DOS

Forum dotyczące ogólnie pojętego programowania - algorytmów, struktur danych, narzędzi programistycznych, itp - głównie w kontekście komputerów PC.
ODPOWIEDZ
Awatar użytkownika
c4v2
Użytkownik
Posty: 426
Rejestracja: 22 lis 2005, 15:14
Lokalizacja: z przed monitora

RS 232 pod DOS

Post autor: c4v2 » 16 sty 2006, 18:35

Napisałem program który wysyła i odbiera dane z RS232 (czyli com-a). Program został napisany na podstawie przykładów z książki: „RS 232 Praktyczne programowanie Od Pascala i C++ do Delphi i Buildera” autorstwa Andrzeja Daniluka. Problem polega na tym że po uruchomieniu systemu operacyjnego (w moim przypadku WinMe) program nie działa tzn. nie wysyła ani nie odbiera znaków (ASCII). Aplikacja działa dopiero po uruchomieniu co najmniej raz programu który korzysta z portów szeregowych com (np.BascomAvr, HyperTerminal). Co gorsza przykładowe programy dla DOS z wyżej wymienionej pozycji wydawniczej zachowują się tak samo. Sprawdzałem również pracę mojego programu a także książkowych aplikacji pod Dos’em (uruchomionym z dyskietki startowej) i rezultat był taki sam. Może trzeba ustawić jeszcze jakieś inne rejestry? Poniżej prezentuję kod źródłowy w turbo Pascalu mojego programu:

program Rs;
uses Dos,Crt;
var Done :Boolean;
Txd :Char;
Rxd :Word;
Regs :Registers;
{---------------------------------------------------------------------------}
function BiosCom(Cmd,Data,Pcom:Byte):Word;
begin
Regs.AH:=Cmd;
Regs.AL:=Data;
Regs.DX:=Pcom;
Intr($14,Regs);
BiosCom:=Regs.AH
end;
{---------------------------------------------------------------------------}
function RsInit(Pcom,Data:Byte):Word;
begin
RsInit:=BiosCom($00,Data,Pcom)
end;
{---------------------------------------------------------------------------}
function RsSend(Pcom,Data:Byte):Word;
begin
RsSend:=BiosCom($01,Data,Pcom)
end;
{---------------------------------------------------------------------------}
function RsReceive(Pcom:Byte):Word;
begin
Regs.AH:=$02;
Regs.DX:=Pcom;
Intr($14,Regs);
RsReceive:=Regs.AL
end;
{---------------------------------------------------------------------------}
function RsStatus(Pcom:Byte):Word;
begin
RsStatus:=BiosCom($03,$00,Pcom)
end;
{---------------------------------------------------------------------------}
begin
ClrScr;
Done:=False;
RsInit($00,$E3);
repeat
repeat
Rxd:=RsReceive($00); { Odbiór }
if Rxd<>RsStatus($00) then
begin
TextColor(White);
Write(Chr(Rxd))
end;
until KeyPressed;
Txd:=ReadKey;
TextColor(LightGreen);
Write(Txd);
if Txd=#13 then
WriteLn;
if Txd=#27 then
Done:=True { Esc - zakończ program }
else
RsSend($00,Ord(Txd)) { Nadawanie }
until Done;
TextColor(LightGray);
end.

Pozdrawiam
Załączniki
Rs232.zip
Kod źródłowy w Turbo Pascalu i program po kompilacji
(3.89 KiB) Pobrany 801 razy
Ostatnio zmieniony 16 sty 2006, 23:20 przez c4v2, łącznie zmieniany 1 raz.

Awatar użytkownika
gaweł
Użytkownik
Posty: 651
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 16 sty 2006, 19:58

Czy dobrze widzę, że ten program do obsługi transmisji szeregowej opiera się o funkcje BIOS'a?
Obsługa transmisji szeregowej w BIOS'ie w komputerach PC poczynając od PC-XT poprzez PC-AT była żle zrobiona. Z tego powodu programiści wypracowali własną obsługę transmisji w swoich programach pomijając BIOS'a i chyba z tego powodu nikt nie poprawił tego do dzisiaj. W systemach windozowych robi się to inaczej a w DOS inaczej.
Nie bardzo mam czas na analizowanie przykładu, ale mogę pokazać jak to się robi w DOS'ie w C.

Awatar użytkownika
c4v2
Użytkownik
Posty: 426
Rejestracja: 22 lis 2005, 15:14
Lokalizacja: z przed monitora

Post autor: c4v2 » 16 sty 2006, 20:51

Witam

Zgadza się, program korzysta z czterech funkcji przerwania 14h BIOS'u. Funkcja 00h służy do konfiguracji i inicjalizacji portu com. Funkcja 01h wysyła znak do skonfigurowanego wcześniej portu, 02h odbiera znak a 03h zwraca status portu. Jeżeli nie da się poprawnie skonfigurować portu korzystając z funkcji BIOS’u, to jakie są sposoby obejścia tego problemu w programie dla DOS?

W C++ dla DOS obsługa RS jest realizowana w ten sam sposób, przez odwołania do funkcji BIOS'u. Natomiast nie mam pojęcia jak to jest w C z obsługą transmisji szeregowej?
Będę bardzo wdzięczny za wskazówki! Może uda mi się C „przetlumaczyć” na Pascala.

Pozdrawiam

Awatar użytkownika
gaweł
Użytkownik
Posty: 651
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 16 sty 2006, 22:36

Podaj mi swój e-mail.
Mój adres to: an177@poczta.fm

Awatar użytkownika
c4v2
Użytkownik
Posty: 426
Rejestracja: 22 lis 2005, 15:14
Lokalizacja: z przed monitora

Post autor: c4v2 » 16 sty 2006, 22:46

Proszę, oto mój adres email:

Ok
Ostatnio zmieniony 18 sty 2006, 22:37 przez c4v2, łącznie zmieniany 2 razy.

Awatar użytkownika
gaweł
Użytkownik
Posty: 651
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 17 sty 2006, 0:23

Coś podeślę.

Awatar użytkownika
c4v2
Użytkownik
Posty: 426
Rejestracja: 22 lis 2005, 15:14
Lokalizacja: z przed monitora

Post autor: c4v2 » 17 sty 2006, 12:07

Witam

Po raz kolejny dało o sobie znać moje roztargnienie. Program był uruchamiamy na PC a, do com podłączona była płytka uruchomieniowa z mikrokontrolerem AVR. Mikrokontroler już na starcie nie mógł się chyba poprawnie wyzerować i nie pomagało naciskanie przycisku „reset” na płytce. Uruchomienie BascomAvr powodowało ustawienie odpowiednich stanów na porcie Lpt komputera a, w konsekwencji ustawienie stanów logicznych na wyjściu programatora umożliwiających poprawną pracę mikrokontrolera AVR. Ku przestrodze innych elektroników-programistów: zapomniałem o odłączeniu programatora ISP. Dopiero gdy odłączyłem programator, program zaczął funkcjonować jak należy bezpośrednio po starcie systemu operacyjnego na PC. Straciłem przez moje roztargnienie kilka cennych godzin i zawracam głowę Forumowiczów, ale nie myli się ten, co nic nie robi!!!

Dziękuję Gawle za chęć pomocy i poświęcony mojemu problemowi czas!

Pozdrawiam

Awatar użytkownika
gaweł
Użytkownik
Posty: 651
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 17 sty 2006, 12:20

Czyli już nie muszę grzebać po archiwalnych CD'ach by znaleźć odpowiedni kawałek programu.

Awatar użytkownika
c4v2
Użytkownik
Posty: 426
Rejestracja: 22 lis 2005, 15:14
Lokalizacja: z przed monitora

Post autor: c4v2 » 17 sty 2006, 12:35

Nie musisz tracić czasu, ponieważ problem rozwiązał się w momencie odłączenia programatora ISP, a napisanie potrzebnych mi procedur na odbiór i wysyłanie łańcucha znaków to „bułka z masłem”. Uparłem się na Pascala ponieważ moduł do transmisji szeregowej chcę dołączyć do większej aplikacji już przeze mnie napisanej właśnie w Pascalu a korzystającej do tej pory z Lpt.

Pozdrawiam

[ Dodano: 26-01-2006, 11:52 ]
Witam

:arrow: Gawle

Czy mogłbyś „pogrzebać po archiwalnych CD'ach by znaleźć odpowiedni kawałek programu w C”. Napisałem procedurę na wysyłanie łańcucha znaków z sumą kontrolną i choć działa to nie jestem zadowolony z jej działania. Żeby przesłać łańcych muszę pomiędzy wysłaniem każdego pojedyńczego znaku wstawiać instrukcję Delay(40) co znacznie spowalnia transmisję. Dodam że sprawdzanie statusu portu (czy rejestr przesówny i bufor nadajnika są puste) nie przyniosło zadowalających rezultatów.

Pozdrawiam

ODPOWIEDZ