Tema: Re: UART programavimas
Autorius: Nerijus
Data: 2010-05-26 17:14:13
dekui uz koda:) reikes pastudijuot :) o kodel sakai kad nepavyks :) beto as 
nespaudau migtuko.. esu idejes filmuka kaip hyper terminal tvarkosi su mano 
hardware :) ir speja atvaizduot kiekviena baita :)
galiu aisku ir koda duot:
=================================
http://pastebin.com/uzbwps6g        |  C# kodas
=================================
http://pastebin.com/eGPVDM0W  |  AVR kodas
=================================
cia nebera toks kodas koks buvo kai dariau .. cia dabar suletinta.. daug 
konversiju nueina vejais :) as cia stenebejau vejo generatoriukaus itampa :)
o seniau buvo ADC interupte siuntimas :)
tai va tokios tokeles :)
"saimhe" <oh.no@oh.my> wrote in message 
news:htj63v$2pk$1@trimpas.omnitel.net...
>> kaip ant C# parasyt panasia programele kaip hyper terminal..
>> pati problema aprasyta cia: 
>> http://www.xoom.lt/2010/05/20/tipo-skopas-voltage-logger/
>
>   Kodėl kodo neduodi, kad iškart matytųsi, kas negerai?
>
>   Nuskaitinėti duomenis be buferizavimo, vos tik jiems atėjus, nėra 
> prasmės.
> Čia kompas neužsiima raketos žemė-oras vairavimu, kad reikėtų išjungti 
> vidinį
> UART buferį (default'as windowsuose 14 baitų), pačiam aptarnauti INT 0C/0B 
> ir
> apskritai naudoti kokią nors realtime operacinę. O kur dar USB/RS232 
> keitikliai,
> juose vėlinimai išvis neprognozuojami. Bet koks PC-based oscilografas ar
> panaši duomenų surinkimo sistema neišvengia buferizavimo. Pakanka, kad 
> buferio
> pildymas truktų kokią pusę sekundės ar panašiai, nes toliau vėlinimas 
> darosi
> pastebimas ir nervina.
>   Be to, skaityti iš porto turi atskiras thread'as. Kai jam skirtas 
> buferis
> prisipildo, tada duoda signalą skaičiavimo bei atvaizdavimo thread'ui ir 
> ima
> pildyti antrą buferį. Paskui atitinkamai sukeičia.
>
>   Kartą dariau GPS logerį savo mobiliakui. Kuo primityvesnį, kad naudotų
> mažiau resursų ir nepamestų duomenų net vykstant pokalbiui. Taigi jokių 
> C#.
> Štai priimantis thread'as:
>
> ---------------------------------------------------------------------------
>    while (!stopASAP)
>    {
>        /* open the port anew and set it up */
>        if (hComm != INVALID_HANDLE_VALUE)
>            CloseHandle(hComm);
>        hComm = CreateFile(tszComm, GENERIC_READ | GENERIC_WRITE, 0, NULL,
>            OPEN_EXISTING, 0, NULL);
>        if ((hComm != NULL) && (hComm != INVALID_HANDLE_VALUE))
>        {
>            DCB dcb;
>            COMMTIMEOUTS ct;
>
>            SetupComm(hComm, BUFSIZE / 4, BUFSIZE * 2);
>            PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR 
> | PURGE_RXCLEAR);
>            if (GetCommState(hComm, &dcb))
>            {
>                dcb.BaudRate = CBR_38400;
>                dcb.ByteSize = 8;
>                dcb.Parity = NOPARITY;
>                dcb.StopBits = ONESTOPBIT;
>
>                if (!SetCommState(hComm, &dcb))
>                    if (!dwReadErrorCode || !fReadErrorHold)
>                    {
>                        dwReadErrorCode = GetLastError();
>                        tszReadErrorLoc = _T("s");
>                        fReadErrorHold = TRUE;
>                    }
>            }
>            else
>                if (!dwReadErrorCode || !fReadErrorHold)
>                {
>                    dwReadErrorCode = GetLastError();
>                    tszReadErrorLoc = _T("g");
>                        /* fReadErrorHold not set: unavailability of this 
> call is not
>                           critical, especially for virtual ports like 
> "External GPS"
>                           that constantly fail with ERROR_NOT_READY
>                         */
>                }
>
>            /* timeouts will minimize amount of incomplete reads below */
>            ct.ReadTotalTimeoutConstant = ct.ReadTotalTimeoutMultiplier = 
> 0;
>            ct.WriteTotalTimeoutConstant = ct.WriteTotalTimeoutMultiplier = 
> 0;
>            ct.ReadIntervalTimeout = 1000;  /* we expect some data each 
> second */
>            SetCommTimeouts(hComm, &ct);
>
>            /* setup finished, we can read now */
>            do
>            {
>                LPBYTE pbReadBuf;
>                DWORD nReadAt;
>                DWORD nToRead;
>                DWORD nReadCount;
>
>                nReadAt = 0;
>                if (!fBufIdx)
>                    pbReadBuf = abBuffer1;
>                else
>                    pbReadBuf = abBuffer2;
>
>                /* ensure that the buffer is full */
>            fill:
>                nToRead = BUFSIZE - nReadAt;
>                if (!ReadFile(hComm, pbReadBuf + nReadAt, nToRead, 
> &nReadCount, NULL))
>                    /* a blocking call if no Bluetooth connection yet; 
> however
>                       after a connection is established for the first 
> time, and
>                       no data comes for the given time interval, ReadFile 
> returns
>                       with no bytes read after that interval. Handy to 
> detect a
>                       lost connection etc.
>                     */
>                {
>                    if (!dwReadErrorCode || !fReadErrorHold || 
> (tszReadErrorLoc[0] == _T('g')))
>                    {
>                        dwReadErrorCode = GetLastError();
>                        tszReadErrorLoc = _T("r");
>                        fReadErrorHold = TRUE;
>                    }
>                    break;
>                }
>                nReadAt += nReadCount;
>                nBytesReadTotal += nReadCount;
>                if ((nReadCount != nToRead) && !stopASAP)
>                {
>                    ClearCommError(hComm, &nReadCount, NULL);
>                    goto fill;
>                }
>
>                /* reset state but only if the previous code was displayed 
> */
>                if (!fReadErrorHold)
>                    dwReadErrorCode = 0;
>
>                pbWriteBuf = pbReadBuf;
>                nAvailSize = BUFSIZE;
>                fBufIdx = !fBufIdx;
>                PulseEvent(heDataAvail);
>            } while (!stopASAP);
>        }
>        else
>            if (!dwReadErrorCode || !fReadErrorHold)
>            {
>                tszReadErrorLoc = _T("c");
>                dwReadErrorCode = GetLastError();
>                fReadErrorHold = TRUE;
>            }
>
>        /* comm port may appear again after a while */
>        Sleep(1000);
>    }
> ---------------------------------------------------------------------------
>
>   BUFSIZE paskutiniu metu buvo 1024 ir gavosi pats tas.
>   "goto fill": bus atiduotas tik pilnas buferis.
>   Antras thread'as, kai nebeturi duomenų apdorojimui, su 
> WaitForSingleObject
> laukia PulseEvent šitame thread'e.
>   Su "overlapped" tipo operacijomis galbūt pavyktų viską padaryti ir
> vieninteliame thread'e. Bet Windows Mobile jų nepalaiko.
>
>   Naudoti kaip Hyperterminal -- esą paspausi mygtuką tame ATtiny ir ekrane
> iškart atsiras simbolis -- tikrai nepavyks, paskirtis ne tokia.
>
> -- 
>  saimhe