
- •Пояснительная записка к курсовой работе
- •Оглавление
- •1. Постановка задачи.
- •1.1. Стандартное задание
- •1.2. Индивидуальное задание
- •2. Техническое задание
- •3. Описание аппаратных и программных средств лабораторного комплекса
- •3.1. Структура аппаратных средств
- •3.1.1. Структурная схема лабораторного комплекса
- •3.1.2. Плата мк – системы
- •3.1.2.1. Конфигурируемые узлы мк c8051f064
- •Интерфейс прямого доступа к памяти (dma)
- •3.1.2.2. Внешняя память xram
- •3.1.2.3. Входные усилители
- •3.1.2.4. Микросхема моста uart-usb
- •3.1.2.5. Сопряжение платы с pc
- •3.1.2.6. Питание платы
- •3.1.3. Требования к pc
- •3.1.4. Осциген
- •. Перечень программных средств лабораторного комплекса
- •Средства программирования и отладки мк-системы
- •Интегрированная среда разработки фирмы SiLabs ide 2.0
- •3.2.1.2. Ассемблер, компилятор и линкер интегрированной среды разработки Keil
- •3.2.2. Средства разработки Windows-приложений
- •3.2.2.1. Среда разработки
- •3.2.2.2. Библиотека win32 api функций
- •3.2.3. Приложения для осцигеНа.
- •3.2.3.1. Драйвер конфигурируемого выносного блока
- •3.2.3.2. Windows-приложение ogView
- •3.2.4. Драйвер виртуального com-порта фирмы SiLabs
- •Организация бесконечного цикла встроенного приложения
- •Отключение сторожевого таймера
- •Переключение с внутреннего генератора на внешний
- •Конфигурирование портов ввода/вывода
- •Конфигурирование аналого-цифровых преобразователей adc
- •Конфигурирование интерфейса dma
- •Инициализация последовательного интерфейса uart
- •Выбор и инициализация таймера для установки скорости обмена данными по последовательному каналу
- •Инициализация таймера для установки времени дискретизации входного сигнала
- •Прием данных с pc
- •Другие используемые функции
- •Конфигурирование узлов мк с учетом данных, пришедших с pc
- •Разработка Windows-приложения
- •4.4.1. Особенности использования среды разработки
- •4.4.2. Описание файлов проекта
- •4.4.3. Обобщенная схема алгоритма многопоточного приложения
- •4.4.4. Внешний вид и описание графического интерфейса, принципы построения программы
- •Описание структуры и организация программы
- •4.4.5.1. Назначение подключаемых файлов
- •4.4.5.2. Описание прототипов функций
- •4.4.5.3. Функция WinMain()
- •4.4.5.4. Функция главного окна
- •4.4.5.5. Организация дополнительных потоков, их назначение
- •4.4.5.6. Рабочие функции дополнительных потоков
- •4.4.5.7. Синхронизация потоков
- •4.4.5.8. Особенности обработки сообщений Windows в программе
- •4.4.6.2. Организация настроек com-порта в графическом интерфейсе
- •4.4.6.3. Использование функций WaitCommEvent(), WaitForSingleObject(), WaitForMultiplyObject()
- •Работа оператора с приложением
- •4.4.7.1. Последовательность запуска приложения на мк и пк в лаборатории
- •4.4.7.2. Адаптация к спектру входного сигнала
- •Описание протокола rs-232
- •Список используемых источников информации
- •Приложения
- •Исходные тексты модулей программы для мк
- •Фрагменты листингов файлов мк-приложения, полученные в результате трансляций: map-file и др
- •Исходные тексты файлов Windows-приложения
Исходные тексты файлов Windows-приложения
#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include <math.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DiagramProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DiagramProc0(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI ThreadProcDraw(LPVOID param);
int power(int x,int y);
void demo();
bool scale(void);
int start();
int ConnectToCOM(HANDLE port);
int Get_Res(HANDLE port,unsigned char * res);
int pRead(HANDLE port,unsigned char * c);
int pWrite(HANDLE port,unsigned char c);
#define ID_Mode 15
#define ID_Port 55
#define ID_START 140
#define ID_KILL 666
#define ID_DEMO 500
#define ID_Samples 1000
#define ID_tmax 1001
#define ID_Umax 1002
HINSTANCE hInst_hWnd, hInst1, hInst0;
HWND hWnd, hGrWnd1, hGrWnd;
HWND hCombo, hCombo2, hComboCOM, startbut, exitbut, demobut, textbFreq, textbSample, Scale_t, Scale_U;
char ClassName[]="Window";
char AppTitle[]="Grapher";
int i = 0;
int height, width;
int graph_xsize = 340, graph_ysize = 290;
int dheight, dwidth, graph=0;
WORD buffer[32768];
BYTE Result[4000];
int Uscale=2200, Tscale=200, samp=10000, freq = 100;
char Uscalech[]="2200", Tscalech[]="200", sampch[]="1024", freqch[] = "5";
WORD EditULength = 4, EditTLength = 3, EditsampLength = 4, EditfreqLength = 1;
CHAR EditTLine[16], EditULine[16], EditsampLine[16], EditfreqLine[16];
bool IfData, flagCOM = false;
char ModeADC;
HANDLE DataProcess_Thread, COM;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
MSG msg;
WNDCLASS wc;
hInst_hWnd = hInstance;
//регистрация настроек главного окна
memset(&wc, 0, sizeof(wc));
wc.lpszClassName = ClassName;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.hInstance = hInst_hWnd;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(140,160,191));
wc.lpszMenuName=NULL;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
RegisterClass(&wc);
//создание главного окна
hWnd = CreateWindow(ClassName, AppTitle,WS_BORDER|WS_MINIMIZEBOX|WS_SYSMENU,120,120,640,430,NULL,NULL,hInst_hWnd, NULL);
if(!hWnd) //если окно не было создано
{
MessageBox(NULL,"Create:error",AppTitle,MB_OK|MB_ICONSTOP);//сообщение об ошибке
return FALSE;
}
ShowWindow(hWnd, nCmdShow);//показ окна
UpdateWindow(hWnd);//обновление окна
while(GetMessage(&msg, NULL, 0, 0))//бесконечный цикл обработки событий
{
graph = 1;
TranslateMessage(&msg);//перевод сообщения виртуальных клавиш в символьные сообщения.
DispatchMessage(&msg);//доставка сообщения, извлеченного функцией GetMessage
graph = 0;
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ //функция обработки событий главного окна
bool error_scale; //флаг ошибки введенных значений масштаба
switch(msg)
{
case WM_COMMAND: //используется для отслеживания нажатий на кнопки «Start», «Demo» и «Exit»
if (LOWORD(wParam) == ID_START){ // если нажата кнопка «Start»
error_scale = scale(); // проверка правильности введенного масштаба
if (error_scale == 0) // если при ввводе была допущена ошибка
break; // выход
start(); // функция, которая считывает введенные настройки, проверяет их,
// создает подключение к COM-порту, проверяет, готов ли порт к получению данных,
// создает поток для рисования графика.
}
if (LOWORD(wParam) == ID_KILL){ // если нажата кнопка «Exit»
DestroyWindow(hWnd); // уничтожение главного окна
PostQuitMessage(0); // отправка сообщения выхода
break; // выход
}
if (LOWORD(wParam) == ID_DEMO){ // если нажата кнопка «Demo»
error_scale = scale(); // проверка правильности введенного масштаба
if (error_scale == 0) // если при ввводе была допущена ошибка
break; // выход
demo(); // функция заполнения буфера значениями по умолчанию
}
break;
case WM_PAINT: // используется, когда необходимо перерисовать графические элементы в окне
DefWindowProc(hWnd, msg, wParam, lParam); // обеспечивает обработку по умолчанию любого сообщения окна,
// которые приложение не обрабатывает
break;
case WM_SIZE: // используется при изменении размеров окна
width = LOWORD(lParam);
height = HIWORD(lParam);
break;
case WM_SETFOCUS: // используется окном, когда оно получило фокус клавиатуры.
UpdateWindow(hWnd); // обновление окна
break;
case WM_DESTROY: // при закрытии окна
DestroyWindow(hWnd); // уничтожение главного окна
PostQuitMessage(0); // отправка сообщения выхода
break;
case WM_CREATE: // принимает это сообщение после того, как окно создано, но до того, как окно становится видимым.
//регистрация класса дочернего окна
WNDCLASS wc0;
memset(&wc0, 0, sizeof(WNDCLASS));
wc0.lpfnWndProc = DiagramProc0;
wc0.hInstance = hInst_hWnd;
wc0.lpszClassName = "ChildWClass0";
wc0.hbrBackground = CreateSolidBrush( RGB( 255,255,255 ) );
wc0.hCursor=LoadCursor(NULL,IDC_ARROW);
RegisterClass(&wc0);
WNDCLASS Gwc;
memset(&Gwc,0,sizeof(WNDCLASS));
Gwc.lpfnWndProc = DiagramProc;
Gwc.hInstance = hInst_hWnd;
Gwc.lpszClassName = "ChildWClass";
Gwc.hbrBackground = CreateSolidBrush( RGB( 255,255,255 ) );
Gwc.style = CS_HREDRAW|CS_VREDRAW;
Gwc.hCursor=LoadCursor(NULL,IDC_ARROW);
Gwc.lpszMenuName=NULL;
Gwc.cbClsExtra=0;
Gwc.cbWndExtra=0;
RegisterClass(&Gwc);
// построение окна графика
hGrWnd1 = CreateWindowEx(0,"ChildWClass0",(LPCTSTR) NULL,WS_CHILD | WS_VISIBLE ,180, 15, 440, 370, hWnd, NULL, hInst0, NULL);
hGrWnd = CreateWindowEx(0,"ChildWClass",(LPCTSTR) NULL,WS_CHILD | WS_VISIBLE,50, 55, graph_xsize, graph_ysize, hGrWnd1, NULL, hInst_hWnd, NULL);
// построение дочерних окон выбора масштаба
CreateWindow("STATIC","Scale",WS_CHILD|WS_VISIBLE,70,15,40,18, hWnd, 0,0,0);
CreateWindow("STATIC","tmax:",WS_CHILD|WS_VISIBLE,15,38,75,18, hWnd, 0,0,0);
Scale_t = CreateWindow("EDIT",Tscalech,WS_CHILD|WS_VISIBLE,95,38,77,18, hWnd,(HMENU)ID_tmax,0,0);
CreateWindow("STATIC","Umax:",WS_CHILD|WS_VISIBLE,15,61,75,18, hWnd, 0,0,0);
Scale_U = CreateWindow("EDIT",Uscalech,WS_CHILD|WS_VISIBLE,95,61,77,18, hWnd,(HMENU)ID_Umax,0,0);
// построение дочерних окон настройки конфигурации выборки
CreateWindow("STATIC","Configuration samples",WS_CHILD|WS_VISIBLE,19,104,148,18, hWnd, 0,0,0);
CreateWindow("STATIC","Frequency:",WS_CHILD|WS_VISIBLE,15,127,75,18, hWnd, 0,0,0);
textbFreq=CreateWindow("EDIT",freqch,WS_CHILD|WS_VISIBLE,95,127,77,18, hWnd,0,0,0);
CreateWindow("STATIC","Samples:",WS_CHILD|WS_VISIBLE,15,150,75,18, hWnd, 0,hInst_hWnd,0);
textbSample=CreateWindow("EDIT",sampch,WS_CHILD|WS_VISIBLE,95,150,77,18, hWnd,(HMENU)ID_Samples,hInst_hWnd,0);
// построение кнопки "Demo"
demobut=CreateWindow("BUTTON","Demo",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,15,193,157,18, hWnd,(HMENU)ID_DEMO,hInst_hWnd,0);
// построение дочерних окон настройки МК и СOM-порта
CreateWindow("STATIC","Configuration ADC",WS_CHILD|WS_VISIBLE,33,237,120,18, hWnd, 0,0,0);
CreateWindow("STATIC","Port:",WS_CHILD|WS_VISIBLE,15,262,75,21, hWnd, 0,0,0);
hComboCOM = CreateWindow(WC_COMBOBOX,0,WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,95,260,77,100, hWnd,(HMENU)ID_Port,hInst_hWnd,0);
SendMessage(hComboCOM,CB_ADDSTRING,0,(LPARAM)"Com1");
SendMessage(hComboCOM,CB_ADDSTRING,0,(LPARAM)"Com2");
SendMessage(hComboCOM,CB_ADDSTRING,0,(LPARAM)"Com3");
SendMessage(hComboCOM,CB_SETCURSEL,(WPARAM)2,0);
CreateWindow("STATIC","Mode:",WS_CHILD|WS_VISIBLE,15,290,75,21, hWnd, 0,0,0);
hCombo = CreateWindow(WC_COMBOBOX,0,WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST,95,288,77,100, hWnd,(HMENU)ID_Mode,hInst_hWnd,0);
SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)"ADC 0");
SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)"ADC 1");
SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)"ADC 0 Diff.");
SendMessage(hCombo,CB_SETCURSEL,(WPARAM)0,0);
// построение кнопки "Start" и "Exit"
startbut=CreateWindow("BUTTON","Start",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,15,336,157,18, hWnd,(HMENU)ID_START,hInst_hWnd,0);
exitbut=CreateWindow("BUTTON","Exit",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,15,370,70,18, hWnd,(HMENU)ID_KILL,hInst_hWnd,0);
InvalidateRect(hGrWnd, NULL, true); // перерисовка окна графика
SendMessage(hGrWnd, WM_PAINT, NULL, NULL); // отправка сообщения для перерисовки
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);// обеспечивает обработку по умолчанию любого сообщения окна,
// которые приложение не обрабатывает
}
return 0l;
}
void demo(){//функция записи в буффер демонстрационного варианта графика
graph=1;
for(i = 0; i < samp; i++)
buffer[i] = fabs(2200 * sin((double)i/30)); //запись в буффер демонстрационного варианта графика
InvalidateRect(hGrWnd, NULL, true);
InvalidateRect(hGrWnd1, NULL, true); // перерисовка окна графика из любого места программы
SendMessage(hGrWnd1, WM_PAINT, NULL, NULL);
SendMessage(hGrWnd, WM_PAINT, NULL, NULL); // отправка сообщения для перерисовки
}
LRESULT CALLBACK DiagramProc(HWND hGrWndtmp, UINT msg, WPARAM wParam, LPARAM lParam)
{//обработка событий дочернего окна построения графика
HDC hDC;
PAINTSTRUCT ps;
HPEN hPen;
switch(msg){
case WM_PAINT: // используется, когда необходимо перерисовать графические элементы в окне
hDC=BeginPaint(hGrWndtmp,&ps);
//оси координат
MoveToEx(hDC,1, 0,0);
LineTo(hDC, 1, dheight-2);
LineTo(hDC, dwidth, dheight-2);
LineTo(hDC, dwidth, dheight-1);
LineTo(hDC, 0, dheight-1);
LineTo(hDC, 0, 0);
//линии сетки
hPen = CreatePen(0,1,RGB(140,160,191));
SelectObject(hDC,hPen);
for(int i = 1; i < 10; i++){
MoveToEx(hDC,1,graph_ysize*i/10,NULL);
LineTo(hDC,graph_xsize,graph_ysize*i/10);
MoveToEx(hDC,graph_xsize*i/10,0,NULL);
LineTo(hDC,graph_xsize*i/10,graph_ysize-1);
if (i%2 == 0){
MoveToEx(hDC,1,graph_ysize*i/10+1,NULL);
LineTo(hDC,graph_xsize,graph_ysize*i/10+1);
MoveToEx(hDC,graph_xsize*i/10+1,0,NULL);
LineTo(hDC,graph_xsize*i/10+1,graph_ysize-1);
}
}
hPen = CreatePen(0,1,RGB(0,0,0));
SelectObject(hDC,hPen);
//линии отметки масштаба на осях графика
MoveToEx(hDC,0,0,NULL); LineTo(hDC,5,0);
MoveToEx(hDC,0,1,NULL); LineTo(hDC,5,1);
MoveToEx(hDC,graph_xsize-2,graph_ysize,NULL); LineTo(hDC,graph_xsize-2,graph_ysize-6);
MoveToEx(hDC,graph_xsize-1,graph_ysize,NULL); LineTo(hDC,graph_xsize-1,graph_ysize-6);
//рисование графика
if(graph == 1){
double U, T = 0, tmp = 0;
graph=0;
for (double i = 0; i < samp; i++){
T = i/freq;
if (T*graph_xsize/Tscale > dwidth)
i = samp;
else if (abs(T-tmp)>=1){
U = buffer[(int)tmp];
MoveToEx(hDC,tmp*graph_xsize/Tscale,-U*graph_ysize/Uscale + dheight,0);
U = buffer[(int)T];
LineTo(hDC, T*graph_xsize/Tscale, -U*graph_ysize/Uscale + dheight);
tmp = T;
}
}
}
EndPaint(hGrWndtmp,&ps);
break;
case WM_SIZE: // используется при изменении размеров окна
dwidth = LOWORD(lParam);
dheight = HIWORD(lParam);
break;
case WM_DESTROY: // при закрытии окна
PostQuitMessage(0); // отправка сообщения выхода
break;
default:
return DefWindowProc(hGrWndtmp, msg, wParam, lParam);
}
return 0l;
}
LRESULT CALLBACK DiagramProc0(HWND hGrWndtmp, UINT msg, WPARAM wParam, LPARAM lParam)
{ //дочернее окно подписи осей координат графика
HDC hDc;
PAINTSTRUCT ps;
switch(msg){
case WM_PAINT: // используется, когда необходимо перерисовать графические элементы в окне
hDc = BeginPaint(hGrWndtmp,&ps);
//заголовок графика
TextOut(hDc,graph_xsize/2-15,0,(LPCTSTR)"Current configuration",21);
TextOut(hDc,graph_xsize/2-50,18,(LPCTSTR)"Frequency:",10);
TextOut(hDc,graph_xsize/2+25,18,(LPCTSTR)freqch,EditfreqLength);
TextOut(hDc,graph_xsize/2+85,18,(LPCTSTR)"Samples:",8);
TextOut(hDc,graph_xsize/2+150,18,(LPCTSTR)sampch,EditsampLength);
//линии отметки масштаба по U
MoveToEx(hDc,51,55,NULL); LineTo(hDc,51,50);
MoveToEx(hDc,50,55,NULL); LineTo(hDc,50,50);
MoveToEx(hDc,47,55,NULL); LineTo(hDc,57,55);
MoveToEx(hDc,47,56,NULL); LineTo(hDc,57,56);
//подпись выбранного масштаба U на графике
TextOut(hDc,30-7*(EditULength-1),47,(LPCTSTR)Uscalech,EditULength);
TextOut(hDc,45,35,(LPCTSTR)"U, mV",5);
//линии отметки масштаба по t
MoveToEx(hDc,50+graph_xsize,53+graph_ysize,NULL); LineTo(hDc,55+graph_xsize,53+graph_ysize);
MoveToEx(hDc,50+graph_xsize,54+graph_ysize,NULL); LineTo(hDc,55+graph_xsize,54+graph_ysize);
MoveToEx(hDc,48+graph_xsize,54+graph_ysize,NULL); LineTo(hDc,48+graph_xsize,59+graph_ysize);
MoveToEx(hDc,49+graph_xsize,54+graph_ysize,NULL); LineTo(hDc,49+graph_xsize,59+graph_ysize);
//подпись выбранного масштаба t на графике
TextOut(hDc,graph_xsize+50-15,350,(LPCTSTR)Tscalech,EditTLength);
TextOut(hDc,400,336,(LPCTSTR)"t, sec",6);
//подпись начала координат на графике
TextOut(hDc,35,350,(LPCTSTR)"0",1);
EndPaint(hGrWndtmp,&ps);
break;
case WM_DESTROY: // при закрытии окна
PostQuitMessage(0); // отправка сообщения выхода
break;
default:
return DefWindowProc(hGrWndtmp, msg, wParam, lParam);
}
return 0l;
}
int power(int x,int y) //x в степени y
{
int rez;
rez = 1;
for(int i=0;i<y;i++)
rez = rez*x;
return rez;
}
bool scale(void){//функция проверки выбранных настроек масштаба
int a;
Uscale=0;
EditULength = (WORD)SendMessage(Scale_U,EM_LINELENGTH,(WPARAM)0,(LPARAM)0); //сохранение выбранного масштаба по оси U
if (EditULength==0){ //если ничего не введено
MessageBox(hWnd, TEXT("Проверьте настройки масштаба по U"), TEXT("Ошибка"), MB_OK); //сообщение об ошибке
return 0;
}
*((LPWORD)EditULine) = EditULength;
SendMessage(Scale_U,EM_GETLINE,(WPARAM)0,(LPARAM)EditULine);
for(int i=0;i<EditULength;i++){ //преобразование строки в число
Uscalech[i] = EditULine[i];
a = EditULine[EditULength-1-i]; //set current symbol
if (a == '.' || a == ','){//если строка содержит какие-либо символы, кроме цифр
MessageBox(hWnd, TEXT("Проверьте настройки масштаба. U должно быть целое."), TEXT("Ошибка"), MB_OK); //сообщение об ошибке
return 0;
}
if (a < '0' || a > '9'){//если строка содержит какие-либо символы, кроме цифр
MessageBox(hWnd, TEXT("Проверьте настройки масштаба. U должно содержать только цифры"), TEXT("Ошибка"), MB_OK); //сообщение об ошибке
return 0;
}
if (a>=48) a=a-48; //get integer by substracting ASCII code
Uscale += a*power(10,i); //Sum with value in right order
}
if(Uscale==0) {//если выбран масштаб 0 по оси U
MessageBox(hWnd, TEXT("Проверьте настройки масштаба. Напряжение U не может быть равно 0."), TEXT("Ошибка"), MB_OK); //сообщение об ошибке
return 0;
}
samp = 0;
EditsampLength = (WORD)SendMessage(textbSample,EM_LINELENGTH,(WPARAM)0,(LPARAM)0);
if (EditsampLength==0){
MessageBox(hWnd, TEXT("Проверьте настройки количества точек выборки"), TEXT("Ошибка"), MB_OK);
return 0;
}
*((LPWORD)EditsampLine) = EditsampLength;
SendMessage(textbSample,EM_GETLINE,(WPARAM)0,(LPARAM)EditsampLine);
for(int i=0;i<EditsampLength;i++){
sampch[i] = EditsampLine[i];
a = EditsampLine[EditsampLength-1-i]; //set current symbol
if (a == '.' || a == ','){
MessageBox(hWnd, TEXT("Проверьте настройки. Samples должно быть целое."), TEXT("Ошибка"), MB_OK);
return 0;
}
if (a < '0' || a > '9'){
MessageBox(hWnd, TEXT("Проверьте настройки. Samples должно содержать только цифры"), TEXT("Ошибка"), MB_OK);
return 0;
}
if (a>=48) a=a-48; //get integer by substracting ASCII code
samp += a*power(10,i); //Sum with value in right order
}
if(samp>2048) {
MessageBox(hWnd, TEXT("Проверьте настройки количества точек выборки. Должно быть менее 2048"), TEXT("Ошибка"), MB_OK);
return 0;
}
if(samp==0) {
MessageBox(hWnd, TEXT("Проверьте настройки. Samples не может быть равно 0."), TEXT("Ошибка"), MB_OK);
return 0;
}
freq = 0;
EditfreqLength = (WORD)SendMessage(textbFreq,EM_LINELENGTH,(WPARAM)0,(LPARAM)0);
if (EditsampLength==0){
MessageBox(hWnd, TEXT("Проверьте настройки частоты выборки"), TEXT("Ошибка"), MB_OK);
return 0;
}
*((LPWORD)EditfreqLine) = EditfreqLength;
SendMessage(textbFreq,EM_GETLINE,(WPARAM)0,(LPARAM)EditfreqLine);
for(int i=0;i<EditfreqLength;i++){
freqch[i] = EditfreqLine[i];
a = EditfreqLine[EditfreqLength-1-i]; //set current symbol
if (a == '.' || a == ','){
MessageBox(hWnd, TEXT("Проверьте настройки частоты выборки. Должно быть целое."), TEXT("Ошибка"), MB_OK);
return 0;
}
if (a < '0' || a > '9'){
MessageBox(hWnd, TEXT("Проверьте настройки частоты выборки. Должно содержать только цифры"), TEXT("Ошибка"), MB_OK);
return 0;
}
if (a>=48) a=a-48; //get integer by substracting ASCII code
freq += a*power(10,i); //Sum with value in right order
}
if(freq==0) {
MessageBox(hWnd, TEXT("Проверьте настройки. freq не может быть равно 0."), TEXT("Ошибка"), MB_OK);
return 0;
}
Tscale=0;
EditTLength = (WORD)SendMessage(Scale_t,EM_LINELENGTH,(WPARAM)0,(LPARAM)0);
if (EditTLength==0){
MessageBox(hWnd, TEXT("Проверьте настройки масштаба по t"), TEXT("Ошибка"), MB_OK);
return 0;
}
*((LPWORD)EditTLine) = EditTLength;
SendMessage(Scale_t,EM_GETLINE,(WPARAM)0,(LPARAM)EditTLine);
for(int i=0;i<EditTLength;i++){
Tscalech[i] = EditTLine[i];
a = EditTLine[EditTLength-1-i]; //set current symbol
if (a == '.' || a == ','){
MessageBox(hWnd, TEXT("Проверьте настройки. tmax должно быть целое."), TEXT("Ошибка"), MB_OK);
return 0;
}
if (a < '0' || a > '9'){
MessageBox(hWnd, TEXT("Проверьте настройки. tmax должно содержать только цифры"), TEXT("Ошибка"), MB_OK);
return 0;
}
if (a>=48) a=a-48; //get integer by substracting ASCII code
Tscale += a*power(10,i); //Sum with value in right order
}
if(Tscale==0) {
MessageBox(hWnd, TEXT("Проверьте настройки. tmax не может быть равно 0."), TEXT("Ошибка"), MB_OK);
return 0;
}
return 1;
}
int start(){//считывает введенные настройки, проверяет их, создает подключение к COM-порту
//проверяет, готов ли порт к получению данных, создает поток для рисования графика.
int a;
int k;
IfData=FALSE; //reset result receive flag
//считываем выбранный COM-порт
i=SendMessage(hComboCOM,CB_GETCURSEL,0,0);
if (flagCOM == FALSE)
{
if (i==0) COM=CreateFile((LPCSTR)L"COM1",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (i==1) COM=CreateFile((LPCSTR)L"COM2",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (i==2) COM=CreateFile((LPCSTR)L"COM3",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
flagCOM=TRUE;
}
//выбранный ADC
i=SendMessage(hCombo,CB_GETCURSEL,0,0); //send message to COMBOADC
//set ADC mode variable
if (i==0) ModeADC='s';
//if (i==1) ModeADC='s';
if (i==2) ModeADC='d';
SendMessage(hWnd,WM_PAINT,0,0); //send WM_PAINT message
if (COM == INVALID_HANDLE_VALUE)//проверяем COM-порт
{
MessageBox(hWnd, TEXT("Ошибка при открытии СОМ порта"), TEXT("Ошибка"), MB_OK);
return 0;
}
for (i=0;i<100;i++) buffer[i]=0; //clear buff with drawn results
//конфигурируем COM-порт
DCB dcbComm; //declare structure for configure COM port
BOOL fSuccess; //variable to check
fSuccess = GetCommState(COM, &dcbComm);//get current setting of COM port
PurgeComm(COM, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
//abort all COM port actions
dcbComm.fBinary=TRUE;
dcbComm.BaudRate = CBR_115200; //seet BaudRate
dcbComm.ByteSize = 8; //set size of bytes
dcbComm.fParity = NOPARITY; //turn off PARITY
dcbComm.StopBits = ONESTOPBIT; //set number of stopbits
COMMTIMEOUTS TimeOuts; //structure for setting timeouts of COM
TimeOuts.ReadTotalTimeoutMultiplier=1;
TimeOuts.ReadTotalTimeoutConstant=3000;
SetCommTimeouts(COM,&TimeOuts); //set timeouts
fSuccess = SetCommState(COM, &dcbComm);//set configuration of COM port
//end of Configure
if (fSuccess==0)//проверяем, прошла ли конфигурация
{
MessageBox(hWnd, TEXT("Ошибка при попытке настроить СОМ порт..."), TEXT("Ошибка"), MB_OK);
return 0;
}
if (ConnectToCOM(COM)==0)//функция установления связи
{
MessageBox(hWnd,TEXT("Не удалось установить соединение"), TEXT("Ошибка COM порта"), MB_OK);
return 0;
}
BYTE z;
z=0;
i=0;
//проверка, готов ли порт к получению данных с МК
while (z!='r')
{
pRead(COM,&z); //получать байт с МК
i++;
if (i==10)
{
MessageBox(hWnd,TEXT("СОМ порт не готов для получения данных"),TEXT("Ошибка"),MB_OK);
return 0;
}
}
k = Get_Res(COM,Result); //получать данные с МК
if (k==0)
{
MessageBox(hWnd,TEXT("Ошибка при получении данных"),TEXT("Ошибка"),MB_OK);
return 0;
}
//создание потока для рисования графика
DataProcess_Thread=CreateThread(NULL,0,ThreadProcDraw,NULL,CREATE_SUSPENDED,NULL);
ResumeThread(DataProcess_Thread); //execute thread
return 1;
}
int ConnectToCOM(HANDLE port) // функция соединения с COM портом
{
int i; //secondary variables
int a;
unsigned char b;
BYTE buf; //exchange buffer
PurgeComm(port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
//сбрасывает все символы из буфера вывода или ввода данных COM-порта.
buf='c';
pWrite(port,buf); //отправка символа 'c' на COM-порт
buf=0;
i=0;
int flag=0;
//while (buf!='p')
while(flag == 0)
{
flag = pRead(port,&buf);//получение символа 'p' от COM-порт
i++;
if (i==10) {return 0;} //если ответный символ не пришел, то выйти из функции (подключение не состоялось)
}
if (buf!='p') return 0; //если ответный символ не 'p', то выйти из функции (подключение не состоялось)
buf=ModeADC;
pWrite(port,buf); //отправка настройки режима ADC МК, используя COM-порт
a = samp>>8; // установить старший байт значения количества выборок для дальнейшей отправки
buf=(unsigned char)a;
pWrite(port,buf); // отправить старший байт значения количества выборок
b = (unsigned char)samp; // установить младший байт значения количества выборок для дальнейшей отправки
buf=b;
pWrite(port,buf); // отправить младший байт значения количества выборок
a = freq>>8; //установить старший байт значения частоты для дальнейшей отправки
b = (unsigned char)freq; //установить младший байт значения частоты для дальнейшей отправки
buf=(unsigned char)a;
pWrite(port,buf); // отправить старший байт значения частоты
buf=b;
pWrite(port,buf); // отправить младший байт значения частоты
return 1;
}
DWORD WINAPI ThreadProcDraw(LPVOID param) //функция-поток рисования графика
{
int k; //secondary variables
unsigned int i;
k=0; //zero counter of DrawBuffer
RECT rect; //struct with main window sizes
for (i=0;i<2*samp;i=i+2)
{
buffer[k]+=Result[i]; //запись в буфер старшего байта
buffer[k]=buffer[k]<<8; //сдвиг этого байта на один байт влево
buffer[k]+=Result[i+1]; //запись в буфер младшего байта
k++;
}
IfData=TRUE; //set flag that data processed
GetWindowRect(hWnd,&rect); //отыскивает размеры рамки ограничивающей прямоугольник определяемого окна
//update main window
SetWindowPos(hWnd,NULL,rect.left+1,rect.top,rect.right-rect.left+1,rect.bottom-rect.top,SWP_SHOWWINDOW);
SendMessage(hWnd, WM_PAINT,NULL,NULL);//send message to draw grafics
return (DWORD)1;
}
int Get_Res(HANDLE port,unsigned char * res)//функция получения данных от МК (отправленных на COM-порт)
//и сохранения их в буфер Result[4000]
//возвращает 1, если успешно, 0 - в противном случае
{
unsigned int i; //secondary variables
int k;
BYTE D;
if (!pWrite(port,'a')) return 0; //отправка байта 'a' МК - начало передачи
for (i=0;i<2*samp;i++)
{
k=pRead(port,&D); //получать байт данных от МК
Result[i]=D; //сохранение его в буфер
if (k==0) return 0; //если не успешно, то вернуть 0
}
return 1;
}
int pWrite(HANDLE port,unsigned char c) //функия записывает байт c в буфер COM-порта в
//асинхронном режиме, используя специальную структуру переполнения
//возвращает 1, если успешно, 0 - в противном случае
{
DWORD dwWritten;
int success= 0;
OVERLAPPED inf= {0}; //структура с информацией для передачи данных
inf.hEvent = CreateEvent( //inf.hEvent - сигнал окончания передачи
NULL, //handle не может быть унаследован
FALSE, //авто-перезагружаемые события
FALSE, //начальное состояние объекта события не сигнализируется
NULL); //событие без имени
if (!WriteFile(port,&c,1,&dwWritten, &inf)) //запись байта в буфер COM-порта в асинхронном режиме
{ //если не успешно
if (GetLastError() == ERROR_IO_PENDING) //проверить последнюю ошибку
//ждем сигнал обеъкта (COM port)
if (WaitForSingleObject(inf.hEvent, INFINITE) == WAIT_OBJECT_0)
//затем получаем результат переполнения операции с COM портом
//если все еще ждем, функция возвращает FALSE
if (GetOverlappedResult(port, &inf, &dwWritten, FALSE))
success = 1; //запись завершена
}
else
success = 1; //запись завершена
if (dwWritten != 1) success = 0; //проверка если количество байт для передачи = количеству переданных данных
CloseHandle(inf.hEvent); //удалить событие
return success;
return 1;
}
int pRead(HANDLE port,unsigned char * c) //function reads byte c from buffer of COM port in
//asynchronous mode using spesial OVERLAPPED struct
//return 1 if succeed, 0 otherwise
{
int success= 0; //check variable
DWORD dwRead; //bytes been read
//dwRead=0;
UINT timeout=0xFFFF;
OVERLAPPED inf= {0}; //struct with information for transmission data
inf.hEvent = CreateEvent( //inf.hEvent - signal of ending of transmission
NULL, //handle cannot be inherited
FALSE, //auto-reset event
FALSE, //initial state of the event object is nonsignaled
NULL); //no name of event
if (ReadFile(port, c, 1, &dwRead, &inf))//write byte to buffer of COM port in asynchronous mode
{
success = 1; //if succeed
}
CloseHandle(inf.hEvent); //delete event
return success; //successful reading}
Алгоритмы
Обобщенный алгоритм программы для МК
Дополнительные алгоритмы программы для МК
Алгоритм процедуры отключения WDT
Алгоритм функции SYSCLK_Init
нет
да
Алгоритм функции Port_Init
Алгоритм функции ADCInit
нет
да
Алгоритм функции DMAInit
нет
да
Алгоритм работы функции UART0_Init
Алгоритм функции Timer3_Init
Алгоритм функции main
Алгоритм функции Config
Алгоритм функции SendData
нет
да
Алгоритм функции ReceiveData
нет
да
Обобщенный алгоритм программы Windows-приложения
Алгоритм работы функции рисования графика
Алгоритм обработки сообщений