Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.03.2011, 12:57
AnderoN AnderoN вне форума
Прохожий
 
Регистрация: 18.02.2011
Сообщения: 31
Репутация: 10
По умолчанию СОМ порт прием информации от микроконтроллера

Здравствуйте, помогите пожалуйста.
Есть программа, которая по СОМ порту принимает информацию от часов и в соответствующие statictext записывает число, месяц, год, час, минуту и секунду. Вот код этой программы

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Ariphm, ExtCtrls,DateUtils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    StaticTextDate: TStaticText;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    StaticTextMonth: TStaticText;
    StaticTextYear: TStaticText;
    StaticTextHour: TStaticText;
    StaticTextMin: TStaticText;
    StaticTextSek: TStaticText;
    Label7: TLabel;
    ComboBox1: TComboBox;
    Label8: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Select(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hCOM:hFile=0;
  pDCB:TDCB;
  comtime:TCOMMTIMEOUTS;
  xb:byte;
  xn:dword;
  ab: array[1..6] of byte;
  st,stcom:string;
  ttime,told:TDateTime;

implementation

{$R *.dfm}

procedure IniCOM;
var i:integer;
begin
{инициализация COM - номер с строке stcom}
  hCOM:=CreateFile(Pchar(stcom), GENERIC_READ+GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
  if (hCom = INVALID_HANDLE_VALUE) then
  begin
    st:=stcom+' не найден';
    Application.MessageBox(Pchar(st),'Error',MB_OK);
    exit;
  end;
  if GetCommState(hCOM,pDCB)
  then  st:=stcom+': baud=9600 parity=N data=8 stop=1';
  if BuildCommDCB(Pchar(st),pDCB) then SetCommState(hCOM,pDCB)
  else
  begin
    st:=stcom+' занят или заданы неверные параметры';
    Application.MessageBox(Pchar(st),'Error',MB_OK);
    exit;
  end;
  GetCommTimeouts(hCom,comtime); {устанавливаем задержки:}
  comtime.WriteTotalTimeoutMultiplier:=1;
  comtime.WriteTotalTimeoutConstant:=10;
  comtime.ReadIntervalTimeout:=10;
  comtime.ReadTotalTimeoutMultiplier:=1;
  comtime.ReadTotalTimeoutConstant:=2000; {ждем чтения 2 сек}
  SetCommTimeouts(hCom,comtime);
  ab[1]:=ord('A');  {будем посылать инициализацию модема}
  ab[2]:=ord('T');
  ab[3]:=13;{CR}
  ab[4]:=10;{LF}
  WriteFile(hCOM,ab,4,xn,nil);
  if ReadFile(hCOM,ab,10,xn,nil) then {ответ модема 10 знаков}
  begin
     st:='';
     for i:=1 to 10 do st:=st+chr(ab[i]);
     if pos('OK',st)<>0 then
     begin
       st:=stcom+' занят модемом';
       Application.MessageBox(Pchar(st),'Error',MB_OK);
       CloseHandle(hCOM);
       hCOM:=0;
       Form1.Label7.Caption:='COM?';
       exit;
     end;
  end;
  Form1.Label7.Caption:=stcom+' 9600';
end;


procedure TForm1.Button1Click(Sender: TObject);
begin    {запрос}
  if (hCOM=0) or (hCOM=INVALID_HANDLE_VALUE) then exit;
  {если порт еще не инициализирован - выход}
  PurgeComm(hCOM,PURGE_RXCLEAR); {очищаем буфер}
  xb:=$A2;
  WriteFile(hCOM,xb,1,xn,nil);
  told:=Time;
  if ReadFile(hCOM,ab,6,xn,nil) then {читаем 6 байт в массив ab}
  begin
    ttime:=Time;
    if SecondsBetween(told,ttime)>0 then
    begin
      Application.MessageBox('Устройство не обнаружено','Error',MB_OK);
      exit;
    end;
    if xn<>6 then
    begin
      Application.MessageBox('Неправильный формат данных','Error',MB_OK);
      exit;
    end;
    StaticTextYear.Caption:=hexb(ab[6]);
    StaticTextMonth.Caption:=hexb(ab[5]);
    StaticTextDate.Caption:=hexb(ab[4]);
    StaticTextHour.Caption:=hexb(ab[3]);
    StaticTextMin.Caption:=hexb(ab[2]);
    StaticTextSek.Caption:=hexb(ab[1]);
  end else {не сработало}
  begin
    Application.MessageBox('СОМ сломался','Error',MB_OK);
    exit;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
{инициализация COM1 при запуске}
  stcom:='COM1';
  IniCOM;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin {уничтожаем COM}
    CloseHandle(hCOM);
end;

procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  CloseHandle(hCOM); {закрываем старый СОМ}
  stcom:=ComboBox1.Text;  {устанавливаем порт COM1,2,3,4}
  IniCOM;
end;

end.

Мне же необходимо написать программку, которая будет по СОМ порту принимать информацию от микроконтроллера, для начала хотя бы 8 байт.
В принципе мне кажется, что программа будет аналогичной, только мне не понадобится столько полей statictext, а можно обойтись одним. Я написал код, он идентичен предыдущему, только массив ab не от 1 до 6, а от 1 до 8 (так как принять надо 8 байт). У меня возникла проблема при программировании кнопки button1, как мне записать чтобы вся информация вывелась в statictext1?

Я пробовал написать

StaticText1.Caption:=hexb (ab[1..8]), но выдает ошибку.

В программе с часами там в каждое поле, если я правильно понял, выводится по одному байту, которые и несут в себе информацию о числе, месяце и т.д., а мне надо чтобы в одно поле вошла вся информация с микроконтроллера. Помогите пожалуйста разобраться.
Ответить с цитированием
  #2  
Старый 12.03.2011, 19:31
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

8 байт? Ну тогда можно попробовать так:
Код:
StaticText1.Caption:=inttohex(int64(ab));
Если не прокатит - то
Код:
StaticText1.Caption:=inttohex(int64((@ab)^));

Но это далеко не самое лучшее. Намного лучше будет если побайтово вывести:
Код:
for i:=0 to 7 do
 StaticText1.Caption:=StaticText1.Caption+inttohex(ab[i])+' ';
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #3  
Старый 17.03.2011, 21:34
AnderoN AnderoN вне форума
Прохожий
 
Регистрация: 18.02.2011
Сообщения: 31
Репутация: 10
По умолчанию

Я написал программу, вот код

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,StdCtrls,Ariphm,DateUtils;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    ComboBox1: TComboBox;
    StaticText1: TStaticText;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ComboBox1Select(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  hCOM:hFile=0;
  pDCB:TDCB;
  comtime:TCOMMTIMEOUTS;
  xb:byte;
  xn:dword;
  ab:array[1..8] of byte;
  st,stcom:string;
  ttime,told:TDateTime;

implementation

{$R *.dfm}


procedure IniCOM;
var i:integer;
begin
  hCOM:=CreateFile(Pchar(stcom),
  GENERIC_READ+GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
  if (hCom=INVALID_HANDLE_VALUE) then
    begin
      st:=stcom+' не найден';
      Application.MessageBox(Pchar(st),'Error',MB_OK);
      exit;
    end;
  if GetCommState(hCOM,pDCB) then
    st:=stcom+': baud=2400 parity=N data=8 stop=1';
  if BuildCommDCB(Pchar(st),pDCB) then
    SetCommState(hCOM,pDCB)
  else
    begin
      st:=stcom+' занят или заданы неверные параметры';
      Application.MessageBox(Pchar(st),'Error',MB_OK);
      exit;
    end;
  GetCommTimeouts (hCom,comtime);
  comtime.WriteTotalTimeoutMultiplier:=1;
  comtime.WriteTotalTimeoutConstant:=10;
  comtime.ReadIntervalTimeout:=10;
  comtime.ReadTotalTimeoutMultiplier:=1;
  comtime.ReadTotalTimeoutConstant:=2000;
  SetCommTimeouts(hCom,comtime);
  ab[1]:=ord('A');
  ab[2]:=ord('T');
  ab[3]:=13;
  ab[4]:=10;
  WriteFile(hCOM,ab,4,xn,nil);
  if ReadFile (hCOM,ab,10,xn,nil) then
    begin
      st:='';
      for i:=1 to 10 do st:=st+chr(ab[i]);
      if pos('OK',st)<>0 then
        begin
          st:=stcom+' занят модемом';
          Application.MessageBox(Pchar(st),'Error',MB_OK);
          CloseHandle(hCOM);
          hCOM:=0;
          Form1.Label2.Caption:='COM?';
          exit;
        end;
    end;
  Form1.Label2.Caption:=stcom+' 2400';
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  stcom:='COM1';
  IniCOM;
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseHandle(hCOM);
end;


procedure TForm1.ComboBox1Select(Sender: TObject);
begin
  CloseHandle(hCOM);
  stcom:=ComboBox1.Text;
  IniCOM;
end;


procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
  if (hCOM=0) or (hCOM=INVALID_HANDLE_VALUE) then
    exit;
  PurgeComm(hCOM,PURGE_RXCLEAR);
  xb:=$A2;
  WriteFile(hCOM,xb,1,xn,nil);
  told:=Time;
  if ReadFile(hCOM,ab,8,xn,nil) then
    begin
      ttime:=Time;
      if SecondsBetween(told,ttime)>0 then
        begin
          Application.MessageBox('Устройство не обнаружено','Error',MB_OK);
          exit;
        end;
      if xn<>8 then
        begin
          Application.MessageBox('Неправильный формат данных','Error',MB_OK);
          exit;
        end;
      for i:=0 to 7 do
        StaticText1.Caption:=hexb(ab[i])+'';
    end else
    begin
      Application.MessageBox('COM сломался','Error',MB_OK);
      exit;
    end;
end;

end.


Она принимает информацию от микроконтроллера, правда только один байт, вместо задуманных мной 8, может ли быть такое из-за того, что микроконтроллер посылает информацию с некоторой задержкой?

И подскажите пожалуйста, если нетрудно, как реализовать так, чтобы программа без кнопки запуска просто принимала информацию от микроконтроллера беспрерывно, т.е. все что он шлет, чтобы отображалось в поле statictext? Если кто знаком с программой СОМ2000, то мне вот нужно, чтобы на подобии как там было, подключаешь микроконтроллер и выдается вся передаваемая информация.
Ответить с цитированием
  #4  
Старый 18.03.2011, 02:52
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Можно запустить стандартный HyperTerminal и посмотреть что и как идет на порт.
Ответить с цитированием
  #5  
Старый 18.03.2011, 20:36
AnderoN AnderoN вне форума
Прохожий
 
Регистрация: 18.02.2011
Сообщения: 31
Репутация: 10
По умолчанию

Я понимаю это), но мне необходимо программу написать, которая будет принимать с СОМ порта информацию
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:33.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter