· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Ребята, выручайте!!! Проблема с СОМ-портом

<< . 1 . 2 .

Посл.отвђт Сообщенiе


Дата: Май 22, 2004 13:13:23

Asterix
Если б я помнил, откуда я его дернул.....


Дата: Май 22, 2004 13:16:34

Quantum и Asterix, ребят, а у Вас нет случайно исходника такого, чтобы можно было глянуть как реагирует модем на посыл ему комманды АТ??? т.е. Чтобы например в PORTMON-е можно было увидеть что послано в порт "АТ" и в ответ получено "ОК" ???


Дата: Май 22, 2004 21:04:48

HyperTerminal рулез!


Дата: Май 24, 2004 13:43:00

Quantum

HyperTerminal рулез!

Я согласен полностью, вот только как мне повторить процесс терминала ?? :о((


Дата: Май 25, 2004 13:13:03

НАШЕЛ!!!!!!!!
вот енто файло....
// comportDlg.cpp : implementation file
//

#include "stdafx.h"
#include "comport.h"
#include "comportDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

////////////////////////////////////////////////////////////////////// ///////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

////////////////////////////////////////////////////////////////////// ///////
// CComportDlg dialog

CComportDlg::CComportDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CComportDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CComportDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CComportDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CComportDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CComportDlg, CDialog)
	//{{AFX_MSG_MAP(CComportDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

////////////////////////////////////////////////////////////////////// ///////
// CComportDlg message handlers

BOOL CComportDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	bIniError = FALSE;
	//Считываем данные из INI-файла
	CString sBaudRate=ReadIni("settings","BaudRate");
	CString sByteSize=ReadIni("settings","ByteSize");
	CString sReadIntervalTimeout=ReadIni("settings","ReadIntervalTimeout");
	CString sReadTotalTimeoutConstant=ReadIni("settings","ReadTotalTimeoutConstant ");
	CString sReadTotalTimeoutMultiplier=ReadIni("settings","ReadTotalTimeoutMultip lier");
	CString sWriteTotalTimeoutConstant=ReadIni("settings","WriteTotalTimeoutConsta nt");
	CString sWriteTotalTimeoutMultiplier=ReadIni("settings","WriteTotalTimeoutMult iplier");
	sFirstCommand=ReadIni("settings","FirstCommand");
	sSecondCommand=ReadIni("settings","SecondCommand");
	if(bIniError)
	{
		AfxMessageBox("Ошибка в INI-файле!", MB_OK | MB_ICONSTOP, 0);
		OnOK();
		return FALSE;
	}
	//Если все нормально, переводим строки в числовые выражения
	nBaudRate=atoi(sBaudRate);
	nByteSize=atoi(sByteSize);
	nReadIntervalTimeout=atoi(sReadIntervalTimeout);
	nReadTotalTimeoutConstant=atoi(sReadTotalTimeoutConstant);
	nReadTotalTimeoutMultiplier=atoi(sReadTotalTimeoutMultiplier);
	nWriteTotalTimeoutConstant=atoi(sWriteTotalTimeoutConstant);
	nWriteTotalTimeoutMultiplier=atoi(sWriteTotalTimeoutMultiplier);
	SetModem(); //Настраиваем модем
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CComportDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CComportDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CComportDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

CString CComportDlg::ReadIni(CString strSect, CString strKey)
{
	//Считываем значение из INI-файла
	GetCurrentDirectory(MAX_BUF,(char*)sBuffer);
	CString strIniPath=(CString)sBuffer+"\\comport.ini";
	GetPrivateProfileString(strSect,strKey,"inifile_error",sBuffer,sizeof (sBuffer),strIniPath);
	CString strIniString=(CString)sBuffer;
	if(strIniString=="inifile_error") bIniError=TRUE;
	return strIniString;
}

void CComportDlg::SetModem() //Настраиваем модем
{
	BOOL bResult = TRUE;
	m_sComPort = "Com1";
	m_hCom = CreateFile(m_sComPort, 
		GENERIC_READ | GENERIC_WRITE,
		0, // эксклюзивный доступ
		NULL, // никакой безопасности :-)
		OPEN_EXISTING,
		0,
		NULL);

	m_bPortReady = SetupComm(m_hCom, 128, 128); // установка размера буфера
	m_bPortReady = GetCommState(m_hCom, &m_dcb);
	m_dcb.BaudRate = nBaudRate; //38400
	m_dcb.ByteSize = nByteSize; //8
	m_dcb.Parity = NOPARITY;
	m_dcb.StopBits = ONESTOPBIT;
	m_dcb.fAbortOnError = TRUE;
	m_bPortReady = SetCommState(m_hCom, &m_dcb);

	m_bPortReady = GetCommTimeouts (m_hCom, &m_CommTimeouts);
	m_CommTimeouts.ReadIntervalTimeout = nReadIntervalTimeout; //50
	m_CommTimeouts.ReadTotalTimeoutConstant = nReadTotalTimeoutConstant; //50
	m_CommTimeouts.ReadTotalTimeoutMultiplier = nReadTotalTimeoutMultiplier; //10
	m_CommTimeouts.WriteTotalTimeoutConstant = nWriteTotalTimeoutConstant; //50
	m_CommTimeouts.WriteTotalTimeoutMultiplier = nWriteTotalTimeoutMultiplier; //10
	m_bPortReady = SetCommTimeouts (m_hCom, &m_CommTimeouts);
	sFirstCommand+="\r"; //AT&ATQ0
	sSecondCommand+="\r"; //ATS7=20

	//Первая команда
	bWriteRC = WriteFile(m_hCom, (LPCVOID) sFirstCommand, 8, &iBytesWritten, NULL);
	ReadPortData(); //Считываем ответ
	if(sPortValue.Find("OK", 0) != -1) //Если вернулось "ОК" или "0"
	{
		//Вторая команда (тоже самое)
		bWriteRC = WriteFile(m_hCom, (LPCVOID) sSecondCommand, 8, &iBytesWritten, NULL);
		ReadPortData();
		if(sPortValue.Find("OK", 0) == -1) bResult = FALSE;
	}
	else bResult = FALSE;
	//Результат обеих команд
	if(bResult) dlgRep.m_RepString="Modem initialization is OK";
		else dlgRep.m_RepString="Modem initialization error occur";
	
	CloseHandle(m_hCom);
	m_uTimerID = SetTimer(0x451,1000,NULL);
	dlgRep.DoModal(); //Окно с сообщением о результате
}

void CComportDlg::ReadPortData()
{
	//Считываем данные из порта
	Sleep(100);
	bReadRC = ReadFile(m_hCom, &sBuffer, 8, &iBytesRead, NULL);
	bReadRC = ReadFile(m_hCom, &sBuffer, 8, &iBytesRead, NULL);
	sPortValue = (CString) sBuffer;
}

void CComportDlg::OnTimer(UINT nIDEvent)
{
	//Убиваем окно с сообщением
	CDialog::OnTimer(nIDEvent);
	KillTimer(m_uTimerID);
	CDialog::OnOK();
	dlgRep.CloseWindow();
	dlgRep.OnButtonexit();
}

там еще файлы есть, но они вроде бесполезные :о)


Дата: Май 25, 2004 20:22:55

Так вот оно:
void CComportDlg::ReadPortData()
{
	//Считываем данные из порта
	Sleep(100);
	bReadRC = ReadFile(m_hCom, &sBuffer, 8, &iBytesRead, NULL);
	bReadRC = ReadFile(m_hCom, &sBuffer, 8, &iBytesRead, NULL);
	sPortValue = (CString) sBuffer;
}
Мне не нравится Sleep и двойной ReadFile, но если так оно работает (?), то Вам тоже следует задействовать этот код.


Дата: Май 25, 2004 21:19:44

Для верности можно ещё пару-тройку ReadFile добавить ;-)))


Дата: Май 26, 2004 13:17:58

Ребят, да понятно что читаем из порта данные...

bReadRC - вот это что не ясно
ReadFile - это обычная функция ...
(m_hCom, - порт
&sBuffer, - буфер
8, - сколько прочитать
&iBytesRead, - сколько прочитано
NULL); - оверлаппед (неисп.)

sPortValue = - сюда передаются данные из буфера (зачем только?)
(CString) - строкка
sBuffer; - сам буфер



Но проблема то в том, что я не получаю "ОК" или ERROR :о((

а если добавить, как говорит Астерикс, еще пару-тройку ReadFile, то либо таймауты менять (увеличивать) либо времени не хватит на чтение ...

Я уже голову поломал себе напрочь :о(

Вот что еще. В МСДН написано, что ReadFile возвращает не"0" или ошибку, а как же увидеть этот злощастный не"0" ???, т.е. как например просто выкинуть все содержимое буфера например в какое нибудь поле (например Edit или List Box) диалога.


Дата: Май 26, 2004 18:36:52

> а если добавить, как говорит Астерикс, еще пару-тройку ReadFile

Не, ну это я просто пошутил, т.к. не понимаю зачем там два ReadFile :-)


Дата: Май 27, 2004 02:23:21

Asterix
а там читается по 8мь байт за раз (я тож не знаю зачем) :о)) но видимо есть смысл.

Может Quantum подскажет?


Дата: Май 27, 2004 02:52:29

Stenton
bReadRC - вот это что не ясно
Это значение true/false, т.е. '0' и не-'0'.
test eax,eax
jz @true ; или jnz @false


т.е. как например просто выкинуть все содержимое буфера например в какое нибудь поле (например Edit или List Box) диалога.
Здравая мысля! Только для этого я и предлагал использовать HyperTerminal. Например:
1. Открываю HT
2. Создаю соединение на 3й ком-порт (там у меня самопальный девайс, понимающий AT-команды)
3. Печатаю "AT" (без кавычек)
4. Жму на клавишу ввода
5. Получаю "OK" (тоже без кавычек)

Теперь можно спокойно садиться за асм. Если бы я не получил "OK", то пришлось бы проверить конфигурацию UART (parity, stop bits, baudrate, ...) Кстати, Вы это вообще настроили в своём коде? Кхм... Теперь допустим, что в HT всё работает, а в нашей программе ничего :-( Вместо Edit или List Box следует использовать отладчик! OllyDbg rulez! Вот так я всегда пишу свои проги для работы с COM-портом.


Дата: Май 27, 2004 07:00:29

Quantum
Настроил (вот:
invoke CreateFile,addr comX,GENERIC_READ or GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL
	mov hcomm,eax

	invoke SetupComm,hcomm,128,128; // óñòàíîâêà ðàçìåðà áóôåðà
	
	invoke GetCommState,hcomm,addr m_dcb
	;mov m_dcb.DCBlength,eax
	mov m_dcb.BaudRate,115200;offset nBaudRate; //38400
	mov m_dcb.ByteSize,8;offset nByteSize; //8
	mov m_dcb.Parity,NOPARITY;
	mov m_dcb.StopBits,ONESTOPBIT;
	mov m_dcb.XonChar,11h
	mov m_dcb.XoffChar,13h
	mov m_dcb.XonLim,180
	mov m_dcb.XoffLim,200
	;mov m_dcb.AbortOnError,TRUE;

	invoke SetCommState,hcomm,addr m_dcb

	invoke GetCommTimeouts,hcomm,addr m_CommTimeouts
	mov m_CommTimeouts.ReadIntervalTimeout,50;offset nReadIntervalTimeout; //50
	mov m_CommTimeouts.ReadTotalTimeoutConstant,50;offset nReadTotalTimeoutConstant; //50
	mov m_CommTimeouts.ReadTotalTimeoutMultiplier,10;offset nReadTotalTimeoutMultiplier; //10
	mov m_CommTimeouts.WriteTotalTimeoutConstant,50;offset nWriteTotalTimeoutConstant; //50
	mov m_CommTimeouts.WriteTotalTimeoutMultiplier,10;offset nWriteTotalTimeoutMultiplier; //10

	invoke SetCommTimeouts,hcomm,addr m_CommTimeouts


А на счет ГиперТерминала. так в нем то у меня все работает...
Сейчас пойду найду отладчик....


Дата: Май 27, 2004 11:18:28

нашел отладчик... смотрю и ниче особенного не вижу...
точнее как в поговорке - смотрю в книгу - вижу ... :о))

<< . 1 . 2 .


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.046