Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/272: Рейтинг темы: голосов - 272, средняя оценка - 4.83
2 / 2 / 0
Регистрация: 07.12.2010
Сообщений: 21

Программирование Com порта в Microsoft Visual Studio 9.0 C++

07.12.2010, 13:11. Показов 52205. Ответов 84
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Имеется микроконтроллер AVR ATmega128, на борту которого имеется UART. Требуется написать приложение для Win32 принимающее с МК по RS-232 информацию. Интерфейс 3-х проводной. TxD, RxD и GND. Подключение ПК к МК осуществляется через виртуальный COM8 порт, тоесть через преобразователь USB в COM. В МК зашита программа тупого посыла символа "$" в цикле. Все работает прекрасно(данные приходят). Проверял программой Terminal v1.9b

Имеется куча примеров, но не один не работает, нет опыта в программировании на C++. То отсутствует какая то библиотека, то непонятная ошибка. Я понимаю что это просто для знающего, но увы я только знакомлюсь с языком Microsoft Visual Studio 9.0 C++. если на нем этого сделать не возможно, посоветуйте тот на котором это возможно.

Подскажите с чего начать, как инициализировать порт, как подключиться, как получить байт?
Да, кол-во получаемых байтов неизвестно, точнее пока оно бесконечно. Для начала хотелось бы чтобы программа тупо принимала все что передается в порт и выводила на экран.

Добавлено через 20 минут
Кто нибудь... помогите подключить C++ к внешнему устройству!!!!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.12.2010, 13:11
Ответы с готовыми решениями:

Отличие между Microsoft Developer Studio и Microsoft Visual Studio?
Здравствуйте, объясните чем отличается Microsoft Developer Studio и Microsoft Visual Studio ?

Как с сайта Microsoft скачать Microsoft Visual Studio 2005 Express Edition?
На сайте Microsoft вроде бы можно скачать Microsoft Visual Studio 2005 Express Edition, но отдаётся оттуда только файл vcsetup.exe размером...

Вылетает Visual Studio 2008 из-за системы управления версиями Microsoft Visual SourceSafe.
Всем здравствуйте. Недавно установил VS 2008 sp1 rus. Хочу создать проект на VC++ (делаю всё подобно как в VS 6.0). Файл - Создать...

84
2 / 2 / 0
Регистрация: 07.12.2010
Сообщений: 21
28.02.2011, 08:32  [ТС]
Студворк — интернет-сервис помощи студентам
Добрый вечер Bedouin! (раз уж вы заходите по вечерам)))
Цитата Сообщение от Bedouin Посмотреть сообщение
1) Почему ты сделал два раздельных файла CPort и ComPort (честно говоря,я сначала предполагал, что один из них будет классом, а второй файлом с кодом)?
- Ты понял правильно. Один файл это описание класса, а второй это код программы которая использует класс объявленный в первом файле.

Цитата Сообщение от Bedouin Посмотреть сообщение
2) Форма программы (кнопки, меню и проч.) реализована в тексте CPort.cpp, хотя отдельно в Solution Explorer я файл формы с расширением *.cs (условно говоря Form1.cs) я не вижу. Я не там ищу или через код удобнее реализовывать? (просто возникает вопрос, как это отредактировать)
- Все верно, код по созданию формы находится в файле CPort.cpp. Это язык программирования С++ здесь не создается форма как в C#. здесь приходится все делать вручную.
- Для редактирования создаваемых элементов окна используй функцию OnCreate. В ней происходит создание всего что ты видишь на форме, и изменить что либо можешь только в ней.

Цитата Сообщение от Bedouin Посмотреть сообщение
3) Функцию обработки сигналов с СОМ-порта и сохранение их на жесткий диск лучше реализовать отдельным файлом *.срр и потом присоединить к проекту или добавить в существующий текст программ?
- на этот вопрос я думаю ответить ты должен сам. Просто если ты планируешь написать единственную программу которая будет делать сохранение на HDD, то можешь писать прямо в коде программы. Если же ты планируешь потом использовать этот код в других программах, то лучше написать в отдельном файле.

По сути Sudoki сделал второе. Он отделил работу с сом портом в отдельный файл и оформил это как класс. То же само можешь сделать и ты. Только ты должен знать как написать свой класс. Мне помогал и помогает Sudoki. Он же дал мне книжку замечательную, если изявишь желание, то я с тобой ей подклюсь.
Удачи тебе Bedouin!

Если где что не так написал, Sudoki поправит!
1
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
28.02.2011, 10:00
Доброе утро всем!
Наконец-то удалось зайти утром, а то в основном приходится работать (вернее подрабатывать) по вечерам.
Большое спасибо, Aspiring, за исчерпывающий ответ.
Предлагаю в дальнейшем (если вы конечно не против) перейти на ты .
Если можно, то поделись, пожалуйста, книжкой. Было бы очень интересно ее почитать.
А то, по правде говоря, по многим вопросам вакуум.
По поводу создания формы хотел бы все-таки внести дополнительную ясность.
Насколько я помню, в Visual Studio (и в частности, в Visual C++) есть инструментарий (Toolbox) для создания и редактирования форм. И создавать/редактировать формы можно через него.
Или я ошибаюсь?
1
2 / 2 / 0
Регистрация: 07.12.2010
Сообщений: 21
28.02.2011, 10:14  [ТС]
Цитата Сообщение от Bedouin Посмотреть сообщение
Насколько я помню, в Visual Studio (и в частности, в Visual C++) есть инструментарий (Toolbox) для создания и редактирования форм. И создавать/редактировать формы можно через него.
Или я ошибаюсь?
Я особо в этом не разбираюсь. Я так сказать на этапе обучения по данному языку. Думаю Sudoki ответит на этот вопрос лучше меня.

Что касается перехода на ты, так это без проблем. Так удобней и проще.
Книжку сейчас выложу. Книга замечательная, только сразу предупрежу, книга написана давно, и некоторые конструкции не проходят в текущих версиях языка. Рекомендую установить MSDN. В свое время отмахивался от него, но со временем понял что без него трудней. В этом благодарен Sudoki! В общем ставь MSDN и то что не получается при написании из книги, ищи в MSDN. Ну а что уж и там не найдешь, пиши сюда, мы тебе постараемся помочь!
0
125 / 65 / 9
Регистрация: 19.04.2010
Сообщений: 196
28.02.2011, 10:23
Цитата Сообщение от Bedouin Посмотреть сообщение
Насколько я помню, в Visual Studio (и в частности, в Visual C++) есть инструментарий (Toolbox) для создания и редактирования форм. И создавать/редактировать формы можно через него.
В основном это используется для диалоговых окон, меню и т.д.
На прямую создать форму в нем не получится.
1
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
01.03.2011, 09:55
Привет, Aspiring!
Мой e-mail: bedouin@inbox.ru.
Заранее спасибо за книгу.
0
2 / 2 / 0
Регистрация: 07.12.2010
Сообщений: 21
01.03.2011, 11:04  [ТС]
Все готово, отправил тебе на мыльницу книжку. Довольно полезная книга. помню что мне Sudoki давал еще одну книжку, но чет не могу ее найти. Но та была по чистому Си. Эта мне кажется полезней. а с самим си по ходу познакомишься, да и по языку полно информации в сети. Так же рекомендую сайт. много полезной информации http://www.firststeps.ru/ Если возникают вопросы, пиши сюда. Мы постараемся помочь!
0
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
01.03.2011, 11:40
Спасибо за книжку, Aspiring!
А на сайте http://www.firststeps.ru/ я и сам пасусь.
Действительно, много полезного материала, но иногда возникают вопросы, выходящие за рамки изложенного. Поэтому и иду на форум.
0
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
02.03.2011, 19:27
Добрый вечер!
Пожалуйста, можете мне объяснить по шагам, как мне создать отдельно класс (*.срр и *.h файлы) и вставить в уже существующий проект для следующей задачи:
Есть процедура обрабатывающая побайтно поток, поступающий через СОМ-порт (ее ранее приводил Sudoki):
C++
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
DEV_FRAME frame;
unsigned char buf_frame[31]; //буфер для фрейма
int index_frame = 0; //сколько в буфере лежит
 
void CWorkCtrl::convBBufToDFrame(const unsigned char *buf, DEV_FRAME &df)
{
//  USHORT temp;
    USHORT t;
    t = buf[0];
    t=buf[1];
    t=buf[2];
    df.RegN[0] = ((USHORT)buf[3]) | (((USHORT)buf[4]) << 8) ;
    df.Tail[0] = ((USHORT)buf[5]) | (((USHORT)buf[6]) << 8) ;
    df.RegN[1] = ((USHORT)buf[7]) | (((USHORT)buf[8]) << 8) ;
    df.Tail[1] = ((USHORT)buf[9]) | (((USHORT)buf[10]) << 8) ;
    df.RegN[2] = ((USHORT)buf[11]) | (((USHORT)buf[12]) << 8) ;
    df.Tail[2] = ((USHORT)buf[13]) | (((USHORT)buf[14]) << 8) ;
    df.RegN[3] = ((USHORT)buf[15]) | (((USHORT)buf[16]) << 8) ;
    df.Tail[3] = ((USHORT)buf[17]) | (((USHORT)buf[18]) << 8) ;
    df.RegN[4] = ((USHORT)buf[19]) | (((USHORT)buf[20]) << 8) ;
    df.Tail[4] = ((USHORT)buf[21]) | (((USHORT)buf[22]) << 8) ;
    df.RegN[5] = ((USHORT)buf[23]) | (((USHORT)buf[24]) << 8) ;
    df.Tail[5] = ((USHORT)buf[25]) | (((USHORT)buf[26]) << 8) ;
    df.RegWind[0] = buf[27];
    df.RegWind[1] = buf[28];
    df.RegWind[2] = buf[29];
    df.RegWind[3] = buf[30];
}
Я создаю с ней *.срр файл:
C++
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
//////////////////////////////////////////////////////////////////////
 
#include "stdafx.h"
#include "WorkCtrl.h"
 
 
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
 
DEV_FRAME frame;
unsigned char buf_frame[31]; //буфер для фрейма
int index_frame = 0; //сколько в буфере лежит
 
void CWorkCtrl::convBBufToDFrame(const unsigned char *buf, DEV_FRAME &df)
{
//  USHORT temp;
    USHORT t;
    t = buf[0];
    t=buf[1];
    t=buf[2];
    df.RegN[0] = ((USHORT)buf[3]) | (((USHORT)buf[4]) << 8) ;
    df.Tail[0] = ((USHORT)buf[5]) | (((USHORT)buf[6]) << 8) ;
    df.RegN[1] = ((USHORT)buf[7]) | (((USHORT)buf[8]) << 8) ;
    df.Tail[1] = ((USHORT)buf[9]) | (((USHORT)buf[10]) << 8) ;
    df.RegN[2] = ((USHORT)buf[11]) | (((USHORT)buf[12]) << 8) ;
    df.Tail[2] = ((USHORT)buf[13]) | (((USHORT)buf[14]) << 8) ;
    df.RegN[3] = ((USHORT)buf[15]) | (((USHORT)buf[16]) << 8) ;
    df.Tail[3] = ((USHORT)buf[17]) | (((USHORT)buf[18]) << 8) ;
    df.RegN[4] = ((USHORT)buf[19]) | (((USHORT)buf[20]) << 8) ;
    df.Tail[4] = ((USHORT)buf[21]) | (((USHORT)buf[22]) << 8) ;
    df.RegN[5] = ((USHORT)buf[23]) | (((USHORT)buf[24]) << 8) ;
    df.Tail[5] = ((USHORT)buf[25]) | (((USHORT)buf[26]) << 8) ;
    df.RegWind[0] = buf[27];
    df.RegWind[1] = buf[28];
    df.RegWind[2] = buf[29];
    df.RegWind[3] = buf[30];
}
(дальнейшие операции с данными я пока не рассматриваю)
А что писать в заголовочном файле?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// WorkCtrl.h: interface for the CWorkCtrl class.
//
 
#pragma once
 
 
class CWorkCtrl  
{
public:
char *buf; 
DEV_FRAME m_df;
void convBBufToDFrame(const unsigned char *buf, DEV_FRAME &df)
private:
 
};
Первая же ошибка, которую я получаю - это:
error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "m_df"

В чем я не прав?
Если можно, то объясните мне, пожалуйста, подход создания класса по шагам. А то в литературе вроде бы и все понятно, но когда пытаешься реализовать сам, упираешься в массу ошибок при отладке.
Заранее спасибо.
1
2 / 2 / 0
Регистрация: 07.12.2010
Сообщений: 21
03.03.2011, 06:08  [ТС]
Хороший вопрос!
Сам я честно говоря еще не создал ни одного класса. но прочитал не мало литературы по языку.
Чтобы создать класс необходимо сделать 2 файла. один cpp, другой h. имена их вроде должны совпадать. В файле заголовков (h) ты должен написать прототипы всех функций которые описаны в cpp, все константы которые будет использовать cpp файл(сам класс). в общем файл заголовкой содержит описание всех констант, переменных и функций для класса, которые будут доступны только для класса.

У тебя есть пример.
ComPort.h - файл заголовков
ComPort.cpp - сам класс

затем просто инклудишь ComPort.h в самом начале файла ComPort.cpp. А затем описываешь все функции которые описал в файле заголовке. давай разберем файл ComPort.h
C++
1
2
3
4
5
#pragma once
//http://britter.ru/index.php?docindex=4&offset=14900
#include <windows.h>
#include <string>
using namespace std;
1 строчка
В языках программирования Си и C++ #pragma once — нестандартная, но широко распространенная препроцессорная директива, разработанная для контроля за тем, чтобы конкретный исходный файл при компиляции подключался строго один раз. То есть, #pragma once применяется для тех же целей, что и include guard, но требует меньше кода и не допускает возможности коллизии имен

2 и 3 это подключение необходимых заголовочных файлов
windows.h - для работы с типами windows
string - наверное содержит какие то функции по работе с текстом.(главный учитель поправит если что ))
4 указывает на то что мы будем использоать пространство имен std. чтобы постоянно не писать "std::***"

едем дальше
C++
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
enum CBaudrate  //скорости
{
    cbr110    = CBR_110,
    cbr300    = CBR_300,
    cbr600    = CBR_600,
    cbr1200   = CBR_1200,
    cbr2400   = CBR_2400,
    cbr4800   = CBR_4800,
    cbr9600   = CBR_9600,
    cbr14400  = CBR_14400,
    cbr19200  = CBR_19200,
    cbr38400  = CBR_38400,
    cbr56000  = CBR_56000,
    cbr115200 = CBR_115200,
    cbr128000 = CBR_128000,
    cbr256000 = CBR_256000
};
 
enum CParity //четность
{
    paEven = EVENPARITY,
    paMark = MARKPARITY,
    paNone = NOPARITY,
    paOdd  = ODDPARITY,
    paSpace= SPACEPARITY
};
 
enum CStopbits //кол стоп бит
{
    sb1   = ONESTOPBIT,
    sb1p5 = ONE5STOPBITS,
    sb2   = TWOSTOPBITS
};
 
enum CDatabits //кол бит данных
{
    db4 = 4, db5, db6, db7, db8
};
 
//перечисляет все события
//так чтобы никуда не лазить
enum CCommEvents
{
    CEV_BREAK  = EV_BREAK,
    CEV_CTS    = EV_CTS,
    CEV_DSR    = EV_DSR,
    CEV_ERR    = EV_ERR,
    CEV_RING   = EV_RING,
    CEV_RLSD   = EV_RLSD,
    CEV_RXCHAR = EV_RXCHAR,
    CEV_RXFLAG = EV_RXFLAG,
    CEV_TXEMPTY= EV_TXEMPTY
};
 
//Это для событий
#define WM_COMPORT WM_USER+1
 
//сообщения от порта
//у всех событий wParam - указатель на класс порта ComPort*
//передается HIWORD(lParam)
#define CP_BASE     0
#define CP_BREAK   (CP_BASE+1)  //
#define CP_CTS     (CP_BASE+2)  //
#define CP_DSR     (CP_BASE+3)  //
#define CP_ERR     (CP_BASE+4)  //
#define CP_RING    (CP_BASE+5)  //
#define CP_RLSD    (CP_BASE+6)  //
#define CP_RXCHAR  (CP_BASE+7)  //LOWORD(lParam) - количество байт
#define CP_RXFLAG  (CP_BASE+8)  //
#define CP_TXEMPTY (CP_BASE+9)  //
здесь идет описание всех констант которые буде использовать класс. может даже некоторые и не использует. Просто описаны для полноты.

самое главное тут:
C++
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
class ComPort
{
public:
    ComPort(HWND parent);          //порт нельзя создать без родителя, родителю мы и будем отсылать сообщения
    ComPort(HWND parent, string name);
    virtual ~ComPort(void); //
 
    BOOL Open();  //открыть порт 0 - не открылся 1-открылся
    BOOL Close(); //закрыть порт 1 - все нормально
 
    BOOL IsOpened() const {return bOpened;};     
 
    string GetDeviceName() const {return sName;};   //имя порта
    void SetDeviceName(string name);             //задать имя порта
 
    int  GetBaudRate() const {return iBaudRate;};
    BOOL SetBaudRate(CBaudrate br);
    BOOL SetBaudRate(int br);
    CParity GetParity() const {return Parity;};
    BOOL SetParity(CParity pa);
    CStopbits GetStopBits() const {return StopBits;};
    BOOL SetStopBits(CStopbits sb);
    CDatabits GetDataBits() const {return DataBits;};
    BOOL SetDataBits(CDatabits db);
    BOOL SetInputBufferSize(unsigned int size);
    unsigned int GetInputBufferSize() const; 
    BOOL SetOutputBufferSize(unsigned int size);
    unsigned int GetOutputBufferSize() const; 
 
    //нам надо задавать маски
    BOOL SetMaskEvent(unsigned int mask); //задает маску CCommEvents
    unsigned int GetMaskEvent();          //читаем маску порта CCommEvents
 
    unsigned int InCount();  //сколько байт во входном буфере
    unsigned int OutCount(); //сколько байт в выходном буфере
 
    BOOL PurgeIn();  //очищаем входной буфер
    BOOL PurgeOut(); //очищаем выходной буфер
 
    //интерфейс чтение
    bool ReadByte(unsigned char &byte);
    unsigned short ReadByts(void* buffer, unsigned short cnt);  //выделить достаточно места под буффер перед вызовом
    unsigned short ReadBytsEx(void* buffer, unsigned short cnt, unsigned int timeout); //если метод не воплнился до 
                                                                                       //конца за время timeout происходит 
                                                                                       //выход из функции
 
    //интерфейс запись
    bool SendByte(unsigned char byte);
    unsigned short SendByts(const void* buffer, unsigned short cnt);
    unsigned short SendBytsEx(const void* buffer, unsigned short cnt, unsigned int timeout);
protected:
    HANDLE hHandle;  //дискриптор порта
    string sName;    //имя
    HWND hParent;    //родитель
 
    int iBaudRate;      //
    CBaudrate BaudRate; //скорость
    CParity Parity;
    CStopbits StopBits;
    CDatabits DataBits;
    unsigned int uEventMask;  //маска прерываний порта
    //Размеры принимающего и отправляющего буффера
    unsigned int uInputBuffSize;
    unsigned int uOutputBuffSize;
 
    BOOL bOpened;    //1-открыт 0-закрыт
 
    //настройка порта
    BOOL UpdateDCB();  
    BOOL UpdateTimeouts();
    BOOL UpdateBuffers();
 
    //
    unsigned int GetCount(int i);  //выдает количество байт в буфере 0 -входной, 1-выходной
 
    //Это вызывается для обработки событий порта
    void PreEvent(unsigned int e);  //в ней мы обрабатываем все события 
 
    //чтение и запись в порт
    unsigned int Send(const void* buffer, unsigned short cnt);  //возвращает кол-во отправленных байт
    unsigned int Read(void* buffer, unsigned short cnt);  //возвращает кол-во прочитанных байт
 
    //Поток
    /*
      Поток понадобится для сигнала что во входном буфере есть данные для чтения
    */
    HANDLE hThread;    //дискриптор потока
       //так как функция является статической она будет единой для всех классов
       //в общем если интересно почитай про статические функции класса
       //в общем это необычная функция класса
    static DWORD WINAPI ComPortProc(LPVOID lParam);  //функция потока
    HANDLE hEventStop; //событие завершения потока
    OVERLAPPED overlapped; //структура испол. в потоке
    //для данной структуры надо создать событие поле hEvent
    DWORD uMaskEvent;  //Используется в WaitComEvent 
    DWORD uResult;     //результат функции WaitForMultipleObjects
    DWORD uBytesTrans; //нужно для GetOverlappedResult
    
    HANDLE hEvent[2];  //просто массив, нужен для WaitForMultipleEvent
};
Здесь как раз таки и описано "все" - что: может, должен и будет делать класс. Все это должно быть реализовано в cpp файле. Ну можешь и наоборот, так мне даже кажется удобней будет. сначала класс написать, потом вынести все в заголовочный файл. А правильней будет выносить в заголовочный вайл заголовок функции сразу после ее реализации.

Сейчас я попробую создать тебе шаблон класса. Тока за правильность не отвечаю, пусть сначала sudoki подтвердит что все нормально, потом юзай на здоровье.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ИмяТвоегоКласса.h
#pragma once
 
// здесь описываешь все свои константы
 
class ИмяТвоегоКласса
{
public: //то что описываешь тут доступно для всего проекта в котором использован класс
 
    ИмяТвоегоКласса(HWND parent);                       //конструктор с одним аргументом
    ИмяТвоегоКласса(HWND parent, string name);      //конструктор с двумя аргументами
    virtual ~ComPort(void);                                     //деструктор 
/*имя конструктора и деструктора всегда совпадает с именем класса
   деструктор отличается от конструктора тильдой "~"
   конструкторов может быть несколько. Какой вызовется будет зависеть от количества 
   передаваемых аргуметов*/
 
protected: //все что описываешь здесь, доступно только внутри класса(с о своей программы ты к 
               //этим описаниям обратиться уже не сможешь
};
Теперь файл самого класса
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "ИмяТвоегоКласса.h" //подключаешь файл заголовков своего класса
 
ИмяТвоегоКласса::ИмяТвоегоКласса(HWND parent) : //описание конструктора с один аргументом
{
}
 
ComPort::ComPort(HWND parent, string name) : //описание конструктора с двумя аргументами
{
}
 
ИмяТвоегоКласса::~ИмяТвоегоКласса(void) //деструктор 
{
    if(bOpened)
        Close();
}
//до этой строки все что обязательно должно быть...
 
// далее реализация - ""ВсеГо" - что: может, должен и будет делать класс"
Ввроде как то так. Если сам ничего не напутал... Удачи в кодинге. Своими кодами тоже делись... У меня тоже такая задача как у тебя. Но пока нету времени ей заниматься.
Вообще я пишу драйвер для ЩПТ(эт типа большой УПС на подстанции и электростанции). И этот код был написан sudoki для помощи мне в этом не легком деле. Пользуйся сам и дай другим! Ну где аж очень секретно, то не давай, а остальное....
Ладно удачи. Работа ждет...

Добавлено через 5 минут
кстати об ошибке!
Цитата Сообщение от Bedouin Посмотреть сообщение
DEV_FRAME m_df;
А что это вообще?! в мсдн я не нашел такой тип. Скорее всего ты не подключил заголовочный файл с описанием этого типа и компилятор не знает что такое DEV_FRAME... ну здесь тебе поможет наш великий sudoki!!!
1
125 / 65 / 9
Регистрация: 19.04.2010
Сообщений: 196
03.03.2011, 09:56
Зачем делать класс, для одной структуры DEV_FRAME и функции convBBufToDFrame?
0
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
03.03.2011, 10:38
Aspiring!
Большое спасибо за развернутый ответ. Информация потихоньку начинает в мозгу устаканиваться.
И сразу вопрос к Sudoki!
Почему для структуры DEV_FRAME и функции convBBufToDFrame нет смысла создавать отдельный класс?
И вообще, что такое структура (в данном случае DEV_FRAME)?
И как тогда ее лучше реализовать? Включить предложенный ранее код для обработки битов СОМ-порта в текст файла CPort.cpp?
0
125 / 65 / 9
Регистрация: 19.04.2010
Сообщений: 196
03.03.2011, 11:04
приведи кусок программы где объявлен DEV_FRAME
скорее всего это будет так

C++
1
2
3
4
typedef struct _DEV_FRAME
{
//....
}DEV_FRAME;
0
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
03.03.2011, 18:38
Спасибо!
Вечером попробую!

Добавлено через 5 часов 47 минут
Добрый вечер!
Чувствую, что у меня не получается правильно сформулировать вопрос, чего я хочу, поэтому не могу приблизиться к конечному результату и ввожу в заблуждение всех остальных.
К сообщению я приложил пару файлов, которые входят в общий проект и которые мне надо переделать.
Эти файлы отвечают за расшифровку входящего через СОМ-порт потока. Поток состоит из кадров по 32 байта.
На данном этапе, чтобы глубоко не зарываться, мне надо сделать выборку байтов, упорядочить их и вставить в форму Edit.
Насколько я понимаю,в файле СPort.cpp за вывод данных в форму Edit отвечает фрагмент:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LRESULT CALLBACK OnComPort(ComPort* p, unsigned int Event, unsigned short arg)
{
    int length;
    switch(Event)
    {
    case CP_RXCHAR: //это событие что есть байты во входном буфере читаем
        //кол-во байт занесено в arg
        BufferCount = p->ReadByts(Buffer, arg);
        length = ::GetWindowTextLength(hEditRecieved) + 1;
        
        char* text = new char[length+BufferCount];
        ::GetWindowText(hEditRecieved, text, length);
        memmove(&text[length-1], Buffer, BufferCount);
        text[length+BufferCount-1] = 0;
        ::SetWindowText(hEditRecieved, text);
 
        delete [] text;
        break;
    }
    return 0;
}
Если я правильно понял, то входной поток данных присваивается переменной Buffer;
объем входных данных - BufferCount;
текст, выводимый в поле Edit - text.
В тексте исходника обработка кадра реализована следующим образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void CWorkCtrl::convBBufToDFrame(BYTE *buf, DEV_FRAME &df)
{
//  USHORT temp;
    USHORT t;
    t = buf[0];
    t=buf[1];
    t=buf[2];
    df.RegN[0] = ((USHORT)buf[3]) | (((USHORT)buf[4]) << 8) ;
    df.Tail[0] = ((USHORT)buf[5]) | (((USHORT)buf[6]) << 8) ;
    df.RegN[1] = ((USHORT)buf[7]) | (((USHORT)buf[8]) << 8) ;
    df.Tail[1] = ((USHORT)buf[9]) | (((USHORT)buf[10]) << 8) ;
    df.RegN[2] = ((USHORT)buf[11]) | (((USHORT)buf[12]) << 8) ;
    df.Tail[2] = ((USHORT)buf[13]) | (((USHORT)buf[14]) << 8) ;
    df.RegN[3] = ((USHORT)buf[15]) | (((USHORT)buf[16]) << 8) ;
    df.Tail[3] = ((USHORT)buf[17]) | (((USHORT)buf[18]) << 8) ;
    df.RegN[4] = ((USHORT)buf[19]) | (((USHORT)buf[20]) << 8) ;
    df.Tail[4] = ((USHORT)buf[21]) | (((USHORT)buf[22]) << 8) ;
    df.RegN[5] = ((USHORT)buf[23]) | (((USHORT)buf[24]) << 8) ;
    df.Tail[5] = ((USHORT)buf[25]) | (((USHORT)buf[26]) << 8) ;
    df.RegWind[0] = buf[27];
    df.RegWind[1] = buf[28];
    df.RegWind[2] = buf[29];
    df.RegWind[3] = buf[30];
}
Если я правильно понял назначение переменной Buffer, то подскажите, пожалуйста, как от "цельного" потока в виде переменной Buffer мне перейти к "отдельным" байтам, чтобы их можно было затем обработать?
Заменить переменную исходного файла buf[] на Buffer[]?
0
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
03.03.2011, 18:41
Что-то с вложениями с первого раза не получилось
Вложения
Тип файла: zip Downloads.zip (1.6 Кб, 94 просмотров)
0
125 / 65 / 9
Регистрация: 19.04.2010
Сообщений: 196
03.03.2011, 21:17
Вот кусок кода который делает выборку кадров из массива байт Buffer.
Также обрабатывает потом кадр с помощью твоего класса.
Класс CWorkCtrl менять не надо.
C++
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
//Добавляем в наш проект
#include "WorkCtrl.h"
 
 
//Создаем экземпляр класса
CWorkCtrl workCtrl;
 
//Это для выделения фрейма из потока
unsigned char buf_frame[31]; //буфер для фрейма
int index_frame = 0; //сколько в буфере лежит
 
//Вот как должна выглядеть функция в таком случае
LRESULT CALLBACK OnComPort(ComPort* p, unsigned int Event, unsigned short arg)
{
        switch(Event)
        {
        case CP_RXCHAR: //это событие что есть байты во входном буфере читаем
                //кол-во байт занесено в arg
                BufferCount = p->ReadByts(Buffer, arg);
                for( int i = 0; i< BufferCount; i++){
                        if( Buffer[i] == 0xE6 && (index_frame <= 1) )
                                buf_frame[index_frame++] = Buffer[i];
                        }else {
                                if( index_frame <= 1 ){
                                        index_frame = 0; continue;
                                }
                                buf_frame[index_frame++] = Buffer[i];
                                if( index_frame >= 31 ){
                                        //
                                        //Тут у тебя уже в массиве buf_frame
                                        //лежит кадр тот который нужен
                                        
                                        workCtrl.convBBufToDFrame(buf_frame, m_dfCurFrame);
                                        
                                        //
                                        //
                                        index_frame = 0;                                        
                                }
                        }
                }
                break;
        }
        return 0;
}
1
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
03.03.2011, 21:43
ОЧЕНЬ БОЛЬШОЕ СПАСИБО, Sudoki, за информацию!
Единственный вопрос, я вижу, что мы добавляем в проект файл WorkCtrl.h.
А файл WorkCtrl.cpp создавать не надо? За все "отвечает" файл CPort.cpp?
0
125 / 65 / 9
Регистрация: 19.04.2010
Сообщений: 196
03.03.2011, 22:26
я вижу, что мы добавляем в проект файл WorkCtrl.h.
Да.
А файл WorkCtrl.cpp создавать не надо?
Надо.
За все "отвечает" файл CPort.cpp?
Этот файл отвечает только за интерфейс пользователя и обработку потока данных с последовательного порта.

За работу с самим портом отвечают файлы ComPort.h ComPort.cpp

Добавлено через 7 минут
Это просто пример, как реализовать класс для работы с последовательным портом. В нем много чего нет. Некоторые настройки порта задаются жестко. Нет нормальной обработки ошибок. Использовать его все равно можно. ))

Добавлено через 1 минуту
Цитата Сообщение от Sudoki Посмотреть сообщение
workCtrl.convBBufToDFrame(buf_frame, m_dfCurFrame);
Замени на
workCtrl.convBBufToDFrame(buf_frame, workCtrl.m_dfCurFrame);
А то выдаст ошибку компиляции
1
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
04.03.2011, 19:04
Добрый день!
Продолжаю воевать с проектом.
Создал файлы WorkCtrl.h и WorkCtrl.срр. Присоединил их к проекту.
То что получилось, прилагаю.
Однако при компиляции повылазила масса ошибок.
Часть устранил, однако 9 штук осталось.
Лог файл с ошибками привожу ниже:
------ Построение начато: проект: CPort, Конфигурация: Debug Win32 ------
Компиляция...
CPort.cpp
d:\andrey\downloads\comport\cport.cpp(25 5) : error C2181: недопустимый else без парного if
d:\andrey\downloads\comport\cport.cpp(25 8) : error C2044: недопустимый continue
d:\andrey\downloads\comport\cport.cpp(26 0) : error C2065: i: необъявленный идентификатор
d:\andrey\downloads\comport\cport.cpp(26 6) : error C2065: m_dfCurFrame: необъявленный идентификатор
WorkCtrl.cpp
d:\andrey\downloads\comport\workctrl.cpp (17) : warning C4091: typedef : пропускается слева от 'DEV_FRAME', когда ни одна переменная не объявлена
d:\andrey\downloads\comport\workctrl.cpp (20) : error C2143: синтаксическая ошибка: отсутствие ";" перед "."
d:\andrey\downloads\comport\workctrl.cpp (20) : error C2182: workCtrl: недопустимое использование типа "void"
d:\andrey\downloads\comport\workctrl.cpp (20) : error C2371: workCtrl: переопределение; различные базовые типы
d:\andrey\downloads\comport\workctrl.cpp (11): см. объявление 'workCtrl'
d:\andrey\downloads\comport\workctrl.cpp (21) : error C2143: синтаксическая ошибка: отсутствие ";" перед "{"
d:\andrey\downloads\comport\workctrl.cpp (21) : error C2447: {: отсутствует заголовок функции (возможно, используется формальный список старого типа)
Создание кода...
Журнал построения был сохранен в "file://d:\Andrey\Downloads\ComPort\Debug\BuildL og.htm"
CPort - ошибок 9, предупреждений 1
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

Как я понимаю, главная ошибка, это неправильное определение функции.
Sudoki, подскажи, в каком направлении копать.
В чем я ошибаюсь?
Единственная просьба, не исправляй за меня ничего.
Очень хочется до всего дойти самому.
Заранее спасибо.
Вложения
Тип файла: zip ComPort.zip (4.46 Мб, 75 просмотров)
0
125 / 65 / 9
Регистрация: 19.04.2010
Сообщений: 196
04.03.2011, 22:34
Цитата Сообщение от Bedouin Посмотреть сообщение
d:\andrey\downloads\comport\cport.cpp(25 5) : error C2181: недопустимый else без парного if
Эта ошибка кроется в строке 252

Добавлено через 1 минуту
Цитата Сообщение от Bedouin Посмотреть сообщение
d:\andrey\downloads\comport\cport.cpp(26 6) : error C2065: m_dfCurFrame: необъявленный идентификатор
Про эту ошибку я уже писал посты выше читай

Добавлено через 32 секунды
Цитата Сообщение от Bedouin Посмотреть сообщение
d:\andrey\downloads\comport\cport.cpp(25 8) : error C2044: недопустимый continue
d:\andrey\downloads\comport\cport.cpp(26 0) : error C2065: i: необъявленный идентификатор
Эти исчезнут когда первую исправишь

Добавлено через 1 минуту
typedef struct DEV_FRAME;

Почитай про typedef в любом справочнике

Добавлено через 39 секунд
void workCtrl.convBBufToDFrame(buf_frame, workCtrl.m_dfCurFrame)

Это не правильно

Добавлено через 4 минуты
Программирование Com порта в Microsoft Visual Studio 9.0 C++
В этом посте был класс зачем что то еще выдумывать?

Добавлено через 40 секунд
CWorkCtrl класс не годиться

Добавлено через 2 минуты
В том виде в каком он написан в выложенном файле
1
2 / 2 / 0
Регистрация: 07.02.2011
Сообщений: 25
10.03.2011, 10:10
Добрый день, Sudiki!
Давай пройдем по моим ошибкам еще раз.
Главная для меня сложность - это понимание класса (что это такое).
Насколько я понял из литературы, новый класс - это по сути два файла: *.h и *.cpp.
В первом из них я глобально определяю переменные, а во втором - уже более детально "разжевываю" что к чему и почему, т.е. расписываю работу с байтами входного потока.
Класс, который ты расписал, приведен в одном листинге. Это и вызывает у меня ступор: а почему один файл? Ведь в учебниках говорится о двух: *.h и *.cpp!
Отсюда и недопонимание. Поэтому я и начинаю "городить огород", дерибаня исходный файл класса на два файла.
Если не тяжело, прокомментируй, пожалуйста, как понимать созданный файл. Что в нем есть что? Или где лучше почитать, а то у меня, к сожалению, сложилось такое впечатление о классах
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.03.2011, 10:10

Microsoft Visual Studio
Даны целые числа a1,...,a20. Наименьший член этой последовательности заменить целой частью среднего арифметического всех членов, остальные...

microsoft visual studio 2005
есть ли в природе документация по microsoft visual studio 2005 на русском языке?

Microsoft Visual Studio 2010
У меня проблеми со студиею... сначала она проект не компилировала а фатал ерор видавала а теперь на С# форматированее самой студии не...

Microsoft visual studio 2010
Скачал прогу после переустановки windows(прошло уже месяца два), открыл, выбрал создать проект, выбрал язык C++, дальше win 32. написал...

Чем отличается Microsoft Visual C++ 2010 Express от Visual Studio 2010 Ultimate
Подскажите пожалуйста, в чем разница Microsoft Visual C++ 2010 Express от Visual Studio 2010 Ultimate. Всем ответившим большое спасибо)))


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
сукцессия 6. Питон реализация энилоджиковской модели, картинка про Центральную часть будущей модели
anaschu 26.06.2026
Етить. ИИ мне на основе моего старого файла R создал вот эту вот хмерь на пайтоне. Это уже новая модель, модель сукцессии грибной. потоки фосфора, азота. Углерода. 5 видов организмов. Я даже. . .
Как замкнутый ядерный цикл решит проблему недостатки фосфора? Био миграция фосфора со дна океана
anaschu 26.06.2026
Биологический лифт: Концепция подъема фосфора со дна океана с помощью ЗЯТЦ Предлагаю на обсуждение альтернативу тяжелому промышленному бурению океанического дна. Вместо сложной инженерии мы можем. . .
сукцессия 5
anaschu 26.06.2026
ПЛАН РАЗРАБОТКИ математической модели сукцессии микоризных систем Переход AM → EcM (Endo + ErM) · Шумилов А. С. · ИФХиБПП РАН · Пущино · 2026 . . .
сукцессия 4
anaschu 25.06.2026
Более детализированный план разработки План доработки модели динамики микоризных симбиозов (EcM с гистерезисом) Цель: Реализовать логику переключения между эрикоидным (ErM) и эктомикоризным. . .
сукцессия 3
anaschu 25.06.2026
Примерный план работ по модели
сукцессия 2
anaschu 25.06.2026
параметризировочная калибровочная таблица будущей модели
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru