Теперь, как кормитьваши данные из решателя (предполагается, что Windows PC) в MCU?
Самый простой способ - использовать RS232 , но для этого вам нужен преобразователь напряжения, например MAX232 (вашПлата MCU , вероятно, имеет ее или использует какой-либо чип USB в качестве USB2RS232 преобразователя в TTL напряжениях типа FTDI илиеще один маленький MCU ).
Итак, вам нужно написать парсер, который будет принимать ваш файл (или поток или что-то еще) на стороне ПК (может быть тем же исполняемым файлом, где вырешить) преобразовать команды в один тип char U,D,L,R,F,B
и отправить их в RS232 .
То же самое можно сделать с USB , но это намного сложнее из-занужно для драйверов и многое другое на стороне ПК и MCU , что не очень хорошоИдея начать с новичка.
В Windows вы просто открываете файл, например COM1
, задаете его свойства и читаете / записываете свои вещи из / в него (так же, как это будет файл).Вот небольшой Win32 C ++ / VCL lib port.h
, который я написал давным-давно для таких вещей:
//---------------------------------------------------------------------------
//--- port class ver: 2.0 ------------------------------------------------
//---------------------------------------------------------------------------
#ifndef _port_h
#define _port_h
//---------------------------------------------------------------------------
class port
{
public: HANDLE hnd;
DWORD error;
DWORD rlen,wlen;
DCB rs232_state;
COMMPROP properties;
COMMTIMEOUTS timeouts;
COMSTAT stat;
port();
~port();
int open(AnsiString name);
void close();
int get_stat(); // err,stat
int get_timeouts(); // timeouts
int set_timeouts();
int get_properties(); // properties
int get_rs232_state(); // rs232_state
int set_rs232_state();
void rst_rs232_state();
void out(BYTE data) { WriteFile(hnd,&data,1,&wlen,NULL); }
void in (BYTE *data) { ReadFile (hnd, data,1,&rlen,NULL); }
void in (char *data) { ReadFile (hnd, data,1,&rlen,NULL); }
void out(BYTE *data,DWORD len) { WriteFile(hnd,data,len,&wlen,NULL); }
void in (BYTE *data,DWORD len) { ReadFile (hnd,data,len,&rlen,NULL); }
};
//---------------------------------------------------------------------------
port::port()
{
rlen=0;
wlen=0;
error=0;
hnd=(void*)0xFFFFFFFF;
rst_rs232_state();
}
//---------------------------------------------------------------------------
port::~port()
{
close();
}
//---------------------------------------------------------------------------
int port::open(AnsiString name)
{
close();
error=0;
rlen=0;
wlen=0;
hnd=CreateFile( name.c_str(),GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
error=GetLastError();
if ((DWORD)hnd==0xFFFFFFFF) return 0;
get_timeouts();
get_properties();
get_rs232_state();
timeouts.ReadIntervalTimeout;
timeouts.ReadTotalTimeoutMultiplier;
timeouts.ReadTotalTimeoutConstant;
timeouts.WriteTotalTimeoutMultiplier;
timeouts.WriteTotalTimeoutConstant;
properties.wPacketLength;
properties.wPacketVersion;
properties.dwServiceMask;
properties.dwReserved1;
properties.dwMaxTxQueue;
properties.dwMaxRxQueue;
properties.dwMaxBaud;
properties.dwProvSubType;
properties.dwProvCapabilities;
properties.dwSettableParams;
properties.dwSettableBaud;
properties.wSettableData;
properties.wSettableStopParity;
properties.dwCurrentTxQueue;
properties.dwCurrentRxQueue;
properties.dwProvSpec1;
properties.dwProvSpec2;
properties.wcProvChar[1];
return 1;
}
//---------------------------------------------------------------------------
void port::close()
{
if ((DWORD)hnd==0xFFFFFFFF) return;
CloseHandle(hnd);
error=GetLastError();
hnd=(void*)0xFFFFFFFF;
}
//---------------------------------------------------------------------------
int port::get_stat()
{
if ((DWORD)hnd==0xFFFFFFFF) return 0;
DWORD err;
if (ClearCommError(hnd,&err,&stat)) return 1;
error=GetLastError();
return 0;
}
//---------------------------------------------------------------------------
int port::get_timeouts()
{
if ((DWORD)hnd==0xFFFFFFFF) return 0;
if (GetCommTimeouts(hnd,&timeouts)) return 1;
error=GetLastError();
get_stat();
return 0;
}
//---------------------------------------------------------------------------
int port::set_timeouts()
{
if ((DWORD)hnd==0xFFFFFFFF) return 0;
if (SetCommTimeouts(hnd,&timeouts)) return 1;
error=GetLastError();
get_stat();
return 0;
}
//---------------------------------------------------------------------------
int port::get_properties()
{
if ((DWORD)hnd==0xFFFFFFFF) return 0;
if (GetCommProperties(hnd,&properties)) return 1;
error=GetLastError();
get_stat();
return 0;
}
//---------------------------------------------------------------------------
int port::get_rs232_state()
{
if ((DWORD)hnd==0xFFFFFFFF) return 0;
if (GetCommState(hnd,&rs232_state)) return 1;
error=GetLastError();
get_stat();
return 0;
}
//---------------------------------------------------------------------------
int port::set_rs232_state()
{
if ((DWORD)hnd==0xFFFFFFFF) return 0;
if (SetCommState(hnd,&rs232_state)) return 1;
error=GetLastError();
get_stat();
return 0;
}
//---------------------------------------------------------------------------
void port::rst_rs232_state()
{
rs232_state.BaudRate = CBR_9600;
rs232_state.ByteSize = 8;
rs232_state.Parity = NOPARITY;
rs232_state.StopBits = ONESTOPBIT;
rs232_state.fOutxCtsFlow= FALSE;
rs232_state.fOutxDsrFlow= FALSE;
rs232_state.fOutX = FALSE;
rs232_state.fInX = FALSE;
rs232_state.fBinary = FALSE;
rs232_state.fRtsControl = RTS_CONTROL_DISABLE;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
Единственный материал, который он использует из VCL , этоAnsiString
, который является строковым типом данных с индексным доступом, индексированным с 1
вместо 0
.AnsiString s; s.c_str();
просто возвращает указатель char*
, так что вы можете напрямую перенести все это на char*
или тип строки, который есть в вашем распоряжении.
При работе с RS232 вы должны принятьИмейте в виду, что вам нужна какая-то синхронизация, потому что другая сторона никогда не узнает, получает ли она данные с начала или некоторые данные были отправлены уже до инициализации.Поэтому вы должны добавить некоторые команды начала / окончания в ваш поток решателя.
Вы также можете одновременно читать и записывать RS232 , но вам нужно использовать потоки для правильной реализации.Вот как я обычно это делаю:
#include <windows.h>
//typedef uint32_t DWORD; // uncomment this if no DWORD type is present
//typedef uint16_t WORD; // uncomment this if no WORD type is present
//typedef uint8_t BYTE; // uncomment this if no BYTE type is present
#include "port.h"
port com;
const int _timeout=1;
const BYTE _id_timeout=0;
unsigned char q;
// init or reconnect
com.open("COM1"); // use number of your COM port to use can be different than 1 especially for USB converters see device manager)
com.timeouts.ReadIntervalTimeout =_timeout;
com.timeouts.ReadTotalTimeoutMultiplier =_timeout;
com.timeouts.ReadTotalTimeoutConstant =_timeout;
com.timeouts.WriteTotalTimeoutMultiplier=_timeout;
com.timeouts.WriteTotalTimeoutConstant =_timeout;
com.set_timeouts();
com.rs232_state.BaudRate=CBR_9600;
com.set_rs232_state();
// write
q='L';
com.out(q);
// read (this can freeze if no data in RS232 and timeout set too big)
q=_id_timeout;
com.in (&q);
if (q==_id_timeout) /* do something if timeout*/ ;
else /* handle valid data*/ ;
// exit
com.close();
Если ваша среда не знает BYTE, WORD, DWORD
, измените их с помощью uint8_t, uint16_t, uint32_t
или используйте typedef
. WinAPI функции должны включать windows.h
.
. Как я уже говорил, помните, что чтение порта COM без фактической отправки данных с другой стороны может заморозить ваш код, так чтоЛучше разделять операции чтения и записи на потоки или иметь короткие тайм-ауты и учитывать потерю данных из-за зависаний.
Перед переходом на MCU вам следует проверить, является ли ваш ПККод стороны работает (так как вы можете гораздо легче отладить сторону PC , чем сторону MCU ).Итак, кодовый эмулятор вашего MCU , который будет читать RS232 фид из вашего решателя и печатать его где-нибудь как консоль или что-то еще, чтобы вы могли видеть, верны ли данные.Затем подключите RS232 по шлейфу (контакты RxD и Txd по короткому замыканию проводом) ...