Здравствуйте.
Я пытаюсь прикрутить вывод ЦАП(взятый из примера WriteData) к SynchroInput, чтобы сделать съем АЧХ. И получается что при запуске один раз срабатывает ЦАП, а потом выдается ошибка, что не может стартануть вывод данных. SyncWithADC = 1
Привожу код потоковой части.
void __fastcall TSynchroThread::Execute()
{
//---- Place thread code here ----
// инициализация текущего потока
Synchronize(InitThread);
// остановим работу ЦАП и одновременно сбросим USB-канал чтения данных
if(!ThreadError) { if(!pModule->STOP_DAC()) ThreadError = true; }
// остановим работу АЦП и одновременно сбросим USB-канал чтения данных
if(!ThreadError) { if(!pModule->STOP_ADC()) ThreadError = true; }
// делаем предварительный запрос на ввод данных
if(!pModule->ReadData(&IoReq)) { Mes = L"Не могу послать запрос на сбор данных с модуля!"; Synchronize(ShowErrorMessageBox);}
RequestNumber = 0x0;
// делаем предварительный запрос на вывод данных
if(!pModule->WriteData(&IoReq_d[RequestNumber]))
{
CloseHandle(WriteOv[0].hEvent);
CloseHandle(WriteOv[1].hEvent);
WriteThreadErrorNumber = 0x2;
IsWriteThreadComplete = true;
}
// основной цикл сбора и отображения данных
while(!Terminated && !ThreadError)
{
//стартуем вывод данных
if(!pModule->START_DAC()) { Mes = L"Не могу стартануть вывод данных!"; Synchronize(ShowErrorMessageBox); break;}
// стартанем сбор данных
if(!pModule->START_ADC()) { Mes = L"Не могу стартануть сбор данных!"; Synchronize(ShowErrorMessageBox); break;}
// вторая половина массива WriteBuffer
RequestNumber ^= 0x1;
// делаем запрос на выввод данных
if(!pModule->WriteData(&IoReq_d[RequestNumber])) { Mes = L"Не могу послать запрос на вывод данных с модуля!"; Synchronize(ShowErrorMessageBox); break; }
// ждем завершения асинхронной операции записи данных в модуль
if(!WaitingForRequestCompleted(IoReq_d[RequestNumber^0x1].Overlapped)) break;
// ожидание завершения сбора данных
if(!WaitingForIoRequestCompleted(&IoReq)) break;
// сформируем следующую порцию данных для первой половинки буфера WriteBuffer
GenSin(0);
// формируем структуру IoReq
//IoReq_d.Buffer = WriteBuffer;
// остановим АЦП и одновременно сбросим USB-канал чтения данных
if(!pModule->STOP_ADC()) { Mes = L"Не могу завершить сбор данных!"; Synchronize(ShowErrorMessageBox); break; }
// остановим ЦАП и одновременно сбросим USB-канал чтения данных
if(!pModule->STOP_DAC()) { Mes = L"Не могу завершить вывод данных!"; Synchronize(ShowErrorMessageBox); break; }
// отобразим полученные данные
if(Terminated) break;
//Synchronize(RedrawViewer);
// задержечка
Sleep(100);
}
// остановим АЦП и одновременно сбросим USB-канал чтения данных
if(!pModule->STOP_ADC()) { Mes = L"Не могу завершить сбор данных!"; Synchronize(ShowErrorMessageBox); }
// остановим ЦАП и одновременно сбросим USB-канал чтения данных
if(!pModule->STOP_DAC()) { Mes = L"Не могу завершить сбор данных!"; Synchronize(ShowErrorMessageBox); }
// прервём все асинхронные запросы
if(!CancelIo(ModuleHandle)) { Mes = L"Не могу прервать асинхронный сбор!"; Synchronize(ShowErrorMessageBox); }
// освободим используемые ресурсы
FreeResource();
// ждём-с
while(!Terminated) { Sleep(50); }
}
// инициализация текущего потока
//---------------------------------------------------------------------------
void __fastcall TSynchroThread::InitThread(void)
{
WORD i;
// пока ничего не выделено под буфер данных
WriteBuffer = NULL;
// пока не создан поток ввода данных
hWriteThread = NULL;
// сбросим флажок наличия ошибки
ThreadError = false;
// мы в потоке
MainForm->IsSynchroThreadRunning = true;
// дескриптор устройства
ModuleHandle = MainForm->ModuleHandle;
// кол-во акивных каналов
ChannelsQuantity = MainForm->ChannelsQuantity;
// кол-во отсчётов на канал
ChannelPoint = MainForm->ChannelPoint;
// общее кол-во собираемых данных
PointsToRead = ChannelPoint * ChannelsQuantity;
// попробуем выделить буфер под получаемые с платы данные
ReadBuffer = new SHORT[PointsToRead];
// попробуем выделить буфер под выводимые на плату данные
WriteBuffer = new SHORT[2*DataStep];
if(!ReadBuffer) { Mes = L"Не могу выделить память под получаемые данные!"; ShowErrorMessageBox(); return; }
if(!WriteBuffer) { Mes = L"Не могу выделить память под выводимые данные!"; ShowErrorMessageBox(); return; }
// структура параметров работы АЦП модуля
ap = MainForm->ap;
// формируем необходимую структуру для сбора данных
ZeroMemory(&ReadOv, sizeof(OVERLAPPED));
// создаём событие для асинхронного запроса
ReadOv.hEvent = CreateEvent(NULL, FALSE , FALSE, NULL);
if(!ReadOv.hEvent) { Mes = L"Не могу создать событие ReadEvent!"; ShowErrorMessageBox(); return; }
// формируем структуру IoReq
IoReq.Buffer = ReadBuffer;
IoReq.NumberOfWordsToPass = PointsToRead;
IoReq.NumberOfWordsPassed = 0x0;
IoReq.Overlapped = &ReadOv;
IoReq.TimeOut = PointsToRead/ap.AdcRate + 1000;
// структура параметров работы ЦАП модуля
ad = MainForm->ad;
GenSin(1);
// формируем структуру IoReq
for(i = 0x0; i < 0x2; i++)
{
// формируем необходимую структуру для вывода данных
ZeroMemory(&WriteOv[i], sizeof(OVERLAPPED));
// создаём событие для асинхронного запроса
WriteOv[i].hEvent = CreateEvent(NULL, FALSE , FALSE, NULL);
if(!WriteOv[i].hEvent) { Mes = L"Не могу создать событие WriteEvent!"; ShowErrorMessageBox(); return; }
IoReq_d[i].Buffer = (SHORT *)(WriteBuffer + i*DataStep);
IoReq_d[i].NumberOfWordsToPass = DataStep;
IoReq_d[i].NumberOfWordsPassed = 0x0;
IoReq_d[i].Overlapped = &WriteOv[i];
IoReq_d[i].TimeOut = DataStep/ad.DacRate + 1000;
}
// теперь можно сделать предварительный,
// т.е. до функции START_DAC(), запрос на вывод данных
}
//формирование массива
void __fastcall TSynchroThread::GenSin(bool IsFirst)
{
DWORD i, BaseIndex;
ad = MainForm->ad;
if (IsFirst)
{
SignalFrequency = 8;
for (i = 0x0; i < DataStep; i+=2)
{
WriteBuffer[i+0x0] = Round(SignalAmplitude*sin(2.0*M_PI*SignalFrequency
*CurrentTime));
WriteBuffer[i+0x1] = SHORT(-WriteBuffer[i + 0x0]);
CurrentTime += 1.0/ad.DacRate;
}
}
else
{
BaseIndex = (RequestNumber^0x1)*DataStep;
for(i = 0x0; i < DataStep; i += 0x2)
{
WriteBuffer[i + BaseIndex + 0x0] = Round(SignalAmplitude*sin(2.*M_PI
*SignalFrequency*CurrentTime));
WriteBuffer[i + BaseIndex + 0x1] = SHORT(-WriteBuffer[i + BaseIndex + 0x0]);
CurrentTime += 1.0/ad.DacRate;
SignalFrequency += 1e-6;
}
}
}