1. Pascal / Говнокод #6917

    +92

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    var
        CommHandle:integer;
        DCB:TDCB;
        Stat:TComStat;
        Kols,TransMask,Errs:DWord;
        Ovr:TOverlapped;
        s:string;
        i:integer;
    
    {Чтение канала n}
    function ReadChannel(n:integer):string;
    begin
    inc(n,32);                                                                                         //код запроса для прибора (это по спецификации прибора)
    s:=chr(n);                                                                                         //символ запроса
    WriteFile(CommHandle,s[1],length(s),Kols,@Ovr);                   //оправили этот код в прибор
    TransMask:=0;                                                                               //маска любого события в порте
    Ovr.hEvent:=CreateEvent(nil, True, False, nil);                          //хз
    repeat
    if not WaitCommEvent(CommHandle, TransMask, @Ovr) then                                                       //если приём закончен не до конца, то...
      if GetLastError = ERROR_IO_PENDING then WaitForSingleObject(Ovr.hEvent, INFINITE);           //при условии "хз" подождать ещё чуть-чуть
    
    ClearCommError(CommHandle,Errs,@Stat);                                          //скинуть длину байт из буфера порта в переменную Stat
    Kols:=Stat.cbInQue;                                                                                    //выяснить длину символов
    until (Kols=1) or (Kols=14);                                                                        //закончить, если в канале пусто (1) или данные есть (14)
    
    SetLength(s,Kols);                                                                                       //установить переменную s длиной Kols
    ReadFile(CommHandle,s[1],Kols,Kols,@Ovr);                                         //прочитать данные из порта в s, обнулив буфер
    if length(s)=1 then ReadChannel:='Пусто';                                             //дальше просто идёт обработка полученных данных
    if length(s)=14 then ReadChannel:=copy(s,5,7);
    end;
    
    
    
    {Основной код}
    for i:=1 to 60 do Value:=ReadChannel(i);                                         //ПОЛУЧИТЬ ДАННЫЕ ИЗ ПОРТА n

    Имеется прибор с хранением данных в 60 каналах. Связь осуществляется по RS-232.
    Чтобы получить данные, нужно отправить № кода нужного канала. В ответ придут данные этого канала.
    Если канал пустой, то приходит 1 байт, если данные есть, то 14 байт.
    Создана функция ReadChannel(n) с запросом данных из канала n.

    ПРОБЛЕМА:
    Прочитать все 60 каналов удаётся иногда 3 раза, иногда 15 раз. Но обязательно когда-нибудь программа зависнет на
    WaitCommEvent(CommHandle, TransMask, @Ovr), так ничего и не получив из порта.
    Если между командами
    WriteFile и WaitCommEvent
    поставить sleep(50) //9600 бод = 1200 б/с, то бишь 12 мс на 1 байт
    то всё пашет. Но это не дело же привязываться ко времени?
    Как избавиться от зависания на WaitCommEvent, чтобы процесс продолжился?
    Если прибор не получил байт, из-за чего не ответил, как это проверить? "Данных нет уже 0,5 с, значит и не будет; отправлю этот байт ещё раз".

    Запостил: sbs, 10 Июня 2011

    Комментарии (13) RSS

    • С чем то похожим сталкивался. В чем проблема, кто знает?
      Ответить
    • сначала говнокодим в жопу, потом спрашиваем, как там не влезть в говно
      Ответить
    • Не знаю, в чём больше, — в самом коде или пояснительном комментарии?
      Ответить
      • в сопроводиловке знатно наложено
        и сдаётся мне, что кто-то не знает, сколько битов на секунду в одном боде
        Ответить
    • Зато сразу видно ... и там и там аФтар ОчЕнь старался
      А может у кого то есть идеи?
      Ответить
    • WSAAsyncSelect?
      Ответить
    • Спасибо за ответы.
      Нашёл очень полезную подробную информацию здесь
      http://compconnect.ru/2011/02/rabota-s-com-portom-v-delphi-pri-pomoshhi-winapi-chast-2-asinxronnyj-rezhim/
      Ответить
      • хуйня какая-то

        и что, уютненький говнокодик опять скатывается в сраный дельфинубофорум?
        Ответить
        • перекатывается с пыхонубофорума на дельфинубофорум
          Ответить
          • хм, насколько я помню в пыхоразделе уже давно консалтинг не проводится
            Ответить
        • bugmenot, слишком сложно?

          Это тебе не
          if ListbBox1.Items.Strings[ListBox1.ItemIndex]='0' then showmessage('Строка 0');
          if ListbBox1.Items.Strings[ListBox1.ItemIndex]='1' then showmessage('Строка 1');
          if ListbBox1.Items.Strings[ListBox1.ItemIndex]='2' then showmessage('Строка 2');
          if ListbBox1.Items.Strings[ListBox1.ItemIndex]='3' then showmessage('Строка 3');
          Ответить
          • по ссылке такой же быдлокод, как и вопросе (аффтар один и пеарит свой технобложик?).
            кисонька, наложенный ввод/вывод - это просто и прямолинейно, если прочитать в справочнике PSDK перед тем, как колотить по клавиатуре
            Ответить

    Добавить комментарий