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

Delphi Sources



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

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

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

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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 байт? Ну тогда можно попробовать так:
Код:
1
StaticText1.Caption:=inttohex(int64(ab));
Если не прокатит - то
Код:
1
StaticText1.Caption:=inttohex(int64((@ab)^));

Но это далеко не самое лучшее. Намного лучше будет если побайтово вывести:
Код:
1
2
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
По умолчанию

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

Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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, время: 17:20.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

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