|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
СОМ порт прием информации от микроконтроллера
Здравствуйте, помогите пожалуйста.
Есть программа, которая по СОМ порту принимает информацию от часов и в соответствующие 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
|
||||
|
||||
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
|
|||
|
|||
Я написал программу, вот код
Код:
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
|
|||
|
|||
Можно запустить стандартный HyperTerminal и посмотреть что и как идет на порт.
|
#5
|
|||
|
|||
Я понимаю это), но мне необходимо программу написать, которая будет принимать с СОМ порта информацию
|