<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=29&amp;t=24730&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2024-11-09T15:17:34+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=29&amp;t=24730&amp;mode</id>
<entry>
<author><name><![CDATA[Artur_26]]></name></author>
<updated>2024-11-09T15:17:34+01:00</updated>
<published>2024-11-09T15:17:34+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238583#p238583</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238583#p238583"/>
<title type="html"><![CDATA[Re: MODBUS RTU - SLAVE]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238583#p238583"><![CDATA[
Cześć,<br />Mirku dziękuję za sprostowanie, faktycznie napisałem to dość nie precyzyjnie, bo faktycznie z mojego opisu wynika, że w skład ramki wchodzi ten odstęp:)<br />Tak dokładnie chciałem przekazać, że czas pomiędzy ramkami nie może być krótszy niż 3,5 znaku.<br />Generalnie chciałem przekazać jak na poniższym rysunku:<br /><br /><a href="https://obrazkiforum.atnel.pl/4513/f896f586f048d271b4b0b57c49c75557.png"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/4513/f896f586f048d271b4b0b57c49c75557.png" alt="Obrazek" /></a><br /><br />Dzięki:)<br /><br />Pozdrawiam<br />Serdecznie<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=4513">Artur_26</a> — 9 lis 2024, o 15:17</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2024-11-09T11:41:55+01:00</updated>
<published>2024-11-09T11:41:55+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238580#p238580</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238580#p238580"/>
<title type="html"><![CDATA[Re: MODBUS RTU - SLAVE]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238580#p238580"><![CDATA[
No to kolega ślicznie pojechał z opisem i teorią modbusa, brawo.<br /><br />Jedyne co podpowiem to odnośnie samego początku, bo napisałeś troszkę może nieprecyzyjnie:<br /><br /><div class="quotetitle">Artur_26 napisał(a):</div><div class="quotecontent"><br />Każdą wiadomość rozpoczyna i kończy tzw. cisza na łączu. Jest to czas bezczynności,<br />trwający 3,5 x czas pojedynczego znaku.<br /></div><br /><br />Wynikałoby z tego opisu że po pierwsze ta cisza to składnik ramki a gorsze, że musi wystąpić dwa razy, chyba że źle rozumiem twoje słowa.<br /><br />CISZA w modbus rtu to rzeczywiście 3,5 znaku ale nie ma to nic wspólnego z samą ramką. To chodzi o CZAS między ramkami, i to czas MINIMALNY, nie powinien być krótszy niż 3,5 znaku, za to może być czas ciszy swobodnie dłuższy niż 3,5 znaku. <br /><br />Oznacza to że np przy 9600 minimalny czas &gt;= 3,5ms musi być zapewniony między ramkami<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 9 lis 2024, o 11:41</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Artur_26]]></name></author>
<updated>2024-11-09T02:41:44+01:00</updated>
<published>2024-11-09T02:41:44+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238578#p238578</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238578#p238578"/>
<title type="html"><![CDATA[MODBUS RTU - SLAVE]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=24730&amp;p=238578#p238578"><![CDATA[
Hej,<br />witam wszystkich forumowiczów, dawno mnie tu nie było <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> <br />Chciałbym się z wami podzielić tym czego dowiedziałem się na temat MODBUS RTU.<br />Tworzę sobie mały układ, który będzie Serwerem MODBUS i przy okazji musiałem trochę wgryźć się w temat:)<br /><br />Może komuś się przyda, a po drugie może ktoś zweryfikuje czy nie piszę głupot:)<br /><br />Przepraszam za nie uporządkowany wygląd postu ale miałem ładnie poukładane, to jak wkleiłem treść, wszystko się porozjeżdżało <img src="https://forum.atnel.pl/images/smilies/icon_redface.gif" alt=":oops:" title="Zawstydzony" /> <br />Jest na to jakiś sposób??<br /><br />Wszystko co tu opisałem jest na podstawie :<br /><br />strony <a href="http://www.modbus.org"  class="postlink">http://www.modbus.org</a>  <br />                                    <br />MODBUS APPLICATION PROTOCOL SPECIFICATION V1.1b3<br />                        <br />oraz <a href="https://www.modbustools.com/modbus.html"  class="postlink">https://www.modbustools.com/modbus.html</a>                      <br />                <br />Założenie : serwer MODBUS RTU nie musi posiadać obsługi wszystkich rozkazów MODBUS wymienionych<br />                w standardzie.<br /><br />/*****************************************************************************************************************                            <br /><br />                                    Opis budowy ramki MODBUS RTU <br />[syntax=c]|     START      | Adres  | Funkcja |        Dane        |   CRC   |      STOP       |  <br />    <br />| 3,5 ramki UART | 1 bajt | 1 bajt  |     n x bajtów     | 2 bajty | 3,5 ramki UART  |[/syntax]<br />    <br />Każdą wiadomość rozpoczyna i kończy tzw. cisza na łączu. Jest to czas bezczynności, <br />trwający 3,5 x czas pojedynczego znaku.                                                                     <br />    <br />Odstęp pomiędzy wysyłanymi znakami nie może być dłuższy niż 1,5 x czas pojedynczego znaku. <br /><br />Czas ten jest zależny od ustawienia transmisji: <br />                                                                                 <br />- BAUDRATE                                                                            <br />- ilość bitów danych danych (założenie - 8 bitów)<br />- czy jest bit parzystości      (założenie - brak) <br />- ile jest bitów stopu           (założenie - 1 bit)                 <br />     <br />Najdłuższa ramka UART 12 bitów:<br />    <br />| START | Bit 1 | Bit 2 | Bit 3 | Bit 4 | Bit 5 | Bit 6 | Bit 7 | Bit 8 | parzystość | STOP | STOP | <br />                                                        <br />przy założeniu założeniach podanych wyżej, długość ramki wynosi: 10 bitów <br />    <br />| START | Bit 1 | Bit 2 | Bit 3 | Bit 4 | Bit 5 | Bit 6 | Bit 7 | Bit 8 | STOP |     <br />   <br />obliczenie czasu trwania jednej ramki UART:<br />    <br />t = (1/BAUDRATE)[s]<br />   <br />t3,5 = 3,5 * t = 3,5 * (1/BAUDRATE)<br />   <br />Przykładowo dla BAUDRATE = 9600 i długości ramki 10 bitów:<br />    <br />t = (1/9600) = 1041,6667 mikro sekundy<br />t1,5 = 1,5 * 1041,6667 = 1562,5 mikro sekundy        <br />t3,5 = 3,5 * 1041,6667 = 3645,8333 mikro sekundy          <br /><br />Maksymalna długość ramki MODBUS RTU dla RS232 / RS485 to: 256 bajtów  <br />                                                        <br />- 1   bajt   adres SLAVE                                 <br />- 1   bajt   kod funkcji (rozkaz)<br />- 252 bajty  dane                               <br />- 2   bajty  suma kontrolna CRC         <br />    <br />Co reprezentują przesyłane wartości w polu &quot;DANE&quot; zależy od konkretnej funkcji, która ma być wykonana. <br />Np. adres początkowy, liczbę zmiennych, offsets, dane do zapisu rejestrów itp.  <br />    <br />Dane mogą być 8 bitowe lub 16 bitowe. <br />    <br />Dane 16 bitowe dzielone są na bajty i wysyłane w kolejności: Hi Lo     <br />                                                                     <br />Suma CRC jest 16 bitowa i wysyłana w kolejności: Lo Hi            <br />                                                                   <br />przykład ramki: <br />[syntax=c]| Adres  | Funkcja |                                   Dane                                           |       CRC      |                                            <br />| 0x02   |   0x03  | Hi Dana1 | Lo Dana1| Hi Dana2 | Lo Dana2| Hi Dana3 | Lo Dana3| Hi Danan| Lo Danan| Lo CRC | Hi CRC|[/syntax]                                                 <br />   <br />                                                          <br />Ramki MODBUS RTU podzielone są na 3 rodzaje:                      <br />                                                                                                                                                <br />- zapytanie, {adres slave, kod fukcji, dane, CRC}     <br />               <br />- odpowiedź, {adres slave, kod fukcji, dane, CRC}  <br />        <br />- odpowiedź na &quot;wyjątek&quot; - zwraca się kod błędu  {adres slave, kod funkcji wyjątku, kod błędu }  <br />           <br />            kod funkcji wyjątku = 0x80 + kod funkcji MODBUS  np. 0x80 + 0x03 = 0x83<br />            kod błędu - opisane poniżej                                              <br />  <br />                                                                 <br />Kiedy klient wysyła zapytanie do serwera, to oczekuje poprawnej odpowiedzi.<br />Mogą być 4 odpowiedzi:  <br />  <br /> 1. Jeśli serwer otrzyma zapytanie bez błędu komunikacji, to zwraca poprawną odpowiedź<br />  <br /> 2. Jeśli serwer nie otrzyma zapytania z powodu błędu komunikacji, to nie zwraca żadnej odpowiedzi                                                                                  <br />     Klient stwierdzi, że został przekroczony TIME-OUT. <br />     <br />3. Jeśli serwer otrzyma zapytanie ale sumy CRC nie będą się zgadzać, to nie zwraca żadnej odpowiedzi                        <br />     Klient stwierdzi, że został przekroczony TIME-OUT.  <br />     <br />4. jeśli serwer otrzyma zapytanie bez błędu komunikacji, ale nie może go obsłużyć, to zwróci                        <br />     odpowiedź z kodem błędu.<br /><br />                                          Kody błędów: <br />  <br />0x01    ILLEGAL FUNCTION               serwer nie obsługuje kodu funkcji zawartego w zapytaniu<br />0x02    ILLEGAL DATA ADDRESS        adres danych otrzymany w zapytaniu jest nie poprawny lub podany <br />                                                        adres z ilością rejestrów do odczytu jest nie poprawny.<br />                                                        Np. serwer ma 100 rejestrów (adresy od 0 do 99), a w zapytaniu <br />                                                        podajemy adres 101 lub podajemy adres 90 a ilość rejestrów<br />                                                        do odczytu 20.<br />                                      <br />0x03    ILLEGAL DATA VALUE          dana (dane) zawarte w zapytaniu nie są dopuszczalne dla serwera <br />                                                      Np. przekroczona wartość jakiejś nastawy<br />                                      <br />0x04    SERVER DEVICE FAILURE    Wystąpił nieodwracalny błąd, gdy serwer próbował wykonać                        <br />                                                      żądaną akcję<br />                                      <br />0x05    ACKNOWLEDGE                      opis str. 48 dokumentu źródłowego<br />0x06    SERVER DEVICE BUSY             opis str. 48 dokumentu źródłowego<br />0x08    MEMORY PARITY ERROR          opis str. 48 dokumentu źródłowego<br />0x0A    GATEWAY PATH UNAVAILABLE  opis str. 49 dokumentu źródłowego<br />0x0B    GATEWAY TARGET DEVICE       opis str. 49 dokumentu źródłowego<br />            FAILED TO RESPOND  <br />          <br />                           <br />                        Typy danych w MODBUS     (Teoria)<br />  <br />W protokole MODBUS zdefiniowano 2 rodzaje danych<br />        - cewki                                                         <br />        - rejestry<br />    <br />Każdy rodzaj danych ma przypisane zakresy adresów.<br />    <br />UWAGA: TO JAKIE DANE I W JAKICH ADRESACH BĘDĄ WYKOŻYSTANE DANE OKREŚLONE JEST PRZEZ TWÓRCĘ &quot;SLAVE&quot;<br />    <br />Cewki    - reprezentują bity - mogą reprezentować stany fizyczne wejść, wyjść <br />Rejestry - 16 bitowe - mogą być tylko odczytywane lub odczytywane i zapisywane.<br />                                Jakie mają znaczenie to zależy od twórcy <br />                           <br />[syntax=c]+-----------------------------------------------------------------------------------------------------------------------------------+                           <br />|      Typ zmiennej     |  Rodzaj zmiennej  |        operacja     |      Zastosowanie         |   Nr cewki/rejestru  | Adres w HEX  |  <br />|-----------------------+-------------------+---------------------+---------------------------+----------------------+--------------|                                         <br />|    Cewka wejściowa    |       1 bit       |  tylko do odczytu   |     wejścia/wyjścia       |       1 - 9999       |  0000 - 270E |                 <br />|    Discretes Input    |                   |                     |       urządzeń            |                      |              |<br />|-----------------------+-------------------+---------------------+---------------------------+----------------------+--------------|                           <br />|    Cewka wyjściowa    |       1 bit       |   odczyt / zapis    |     wyjścia urządzeń      |    10001 - 19999     |  0000 - 270E |         <br />|         Coils         |                   |                     |    wewnętrzne flagi       |                      |              |<br />|-----------------------+-------------------+---------------------+---------------------------+----------------------+--------------|                            <br />| Rejestry wejściowe    |     16 bitów      |  tylko do odczytu   |   liczbowa reprezentacja  |    30001 - 39999     |  0000 - 270E |          <br />|   Input Registers     |                   |                     |      stanów wejść/wyjść   |                      |              |  <br />|-----------------------+-------------------+---------------------+---------------------------+----------------------+--------------|                      <br />| Rejestry pamiętające  |     16 bitów      |   odczyt / zapis    |     odczyty i zapisy      |    40001 - 49999     |  0000 - 270E |         <br />|  Holding Registers    |                   |                     |   rejestró wewnętrznych   |                      |              |<br />|                       |                   |                     | parametryzacja urządzenia |                      |              |<br />+-----------------------------------------------------------------------------------------------------------------------------------+[/syntax] <br />        <br />    TAK NAPRAWDĘ TO OD NAS ZALEŻY JAK SOBIE ZORGANIZUJEMY PAMIĘĆ, ALE MUSIMY SIĘ TRZYMAĆ ZASAD    <br />    I PRZEDEWSZYSTKIM OPISAĆ  M A P Ę  P A M I Ę C I, CZYLI OKREŚLIĆ CO ZA CO ODPOWAIDA<br />    A TO WSZYSTJKO ZALEŻY OD TEGO CO DANY UKŁAD MA ROBIĆ. <br />    <br />    <br />    <br />                  Opisy kodów funkcji MODBUS - nie wszystkie są wymienione<br />    <br />    Kody funkcji mogą przyjmować wartość od 1 do 127                  <br />    <br />    Kody funkcji dzielimy na:<br />        - Public Function Codes              - kody funkcji publiczne                 zakres 1 - 64  i 111 - 127<br />        - User-Defined Function Codes   - definiowane przez użytkownika     zakres 65 - 72 i 100 - 110                                <br />        - Reserved Function Codes         - kody zastrzeżone   <br />        <br /> <br />    KODY PUBLICZNE - najbardziej przydatne (moim zdaniem) a i tak nie wszystkie się wykorzystuje <br />    <br />    0x01    Read Coils                            - odczyt wyjść bitowych<br />    0x02    Read Discrete Inputs             - odczyt wejść bitowych                                  <br />    0x03    Read Holding Registers          - odczyt rejestrów z podanego zakresu<br />    0x04    Read Input Register              - odczyt rejestrów wejściowych                                     <br />    0x05    Write Single Coil                   - zapis pojedynczego bitu<br />    0x06    Write Single Register            - zapis pojedynczego rejestru<br />    0x07    Read Exception status           - odczyt statusu wyjątku urządzenia SLAVE<br />    0x08    Diagnostic                           - test diagnostyczny<br />    0x0F    Write Multiple Coils               - zapis bitów z podanego zakresu<br />    0x10    Write Multiple Registers         - zapis rejestrów z podanego zakresu<br />    0x11    Report Server ID                  - identyfikacja urządzenia SLAVE <br />    0x17    Read/Write Multiple Registers                                              <br /><br />    Pozostałe kody w tabeli na stronie 11 podanego wcześniej dokumentu.   <br />    <br />    Przykłady jak wyglądają ramki dla konkretnych kodów funkcji: źródło <a href="https://www.modbustools.com/modbus.html"  class="postlink">https://www.modbustools.com/modbus.html</a><br />    <br />    Przykład kod funkcji 0x03                                                                                <br />    <br />    Zapytanie z MASTER:          HEX<br />    <br />    Slave Address                     01<br />    Function                             03       <br />    Starting Address Hi             00    <br />    Starting Address Lo             00    <br />    Quantity of Registers Hi       00    <br />    Quantity of Registers Lo       02    <br />    Error Check Lo                    C4    <br />    Error Check Hi                    0B    <br />                                   <br />    Total Bytes                  8 <br />    <br />    Wyliczenie adresu początkowego : Adres, który chcemy odczytać - Adres pierwszego rejestru<br />    czyli 4001 - 4001 = 0 dlatego : <br />        Starting Address Hi          0x00    <br />        Starting Address Lo          0x00<br />            <br />    jeśli chcielibyśmy czytać od adresu 4020 to robimy obliczenie : 4020 - 4001 = 19 (0x13) i wtedy byłoby:<br />        Starting Address Hi          0x00    <br />        Starting Address Lo          0x13<br />                                                   <br />    Odpowiedź od SLAVE:          HEX<br />    <br />    Slave Address                01    <br />    Function                        03           <br />    Byte Count                    04         <br />    Data Hi                         00            <br />    Data Lo                         06            <br />    Data Hi                         00           <br />    Data Lo                         05            <br />    Error Check Lo               DA    <br />    Error Check Hi               31    <br />    <br />    Total Bytes    9  <br />    <br /><br />        <br />    Przykład kod funkcji 0x16<br />    <br />    Zapytanie z MASTER:          HEX<br />                        <br />    Slave Address                  11    <br />    Function                          10           <br />    Starting Address Hi          00        <br />    Starting Address Lo          01    <br />    Quantity of Registers Hi    00    <br />    Quantity of Registers Lo    02    <br />    Byte Count                      04         <br />    Data Hi                           00           <br />    Data Lo                          0A            <br />    Data Hi                           01            <br />    Data Lo                          02            <br />    Error Check Lo                C6    <br />    Error Check Hi                 F0    <br /><br />    Total Bytes    13  <br />    <br />    <br />    Wyliczanie sumy CRC <br />    <br />    Sumę CRC wylicza się z:<br />        - Adresu SLAVE<br />        - kodu funkcji <br />        - danych<br />    <br />    np:                                 HEX<br />    Slave Address                   11    <br />    Function                           10           <br />    Starting Address Hi           00        <br />    Starting Address Lo           01    <br />    Quantity of Registers Hi     00    <br />    Quantity of Registers Lo     02    <br />    Byte Count                       04         <br />    Data Hi                             00           <br />    Data Lo                            0A            <br />    Data Hi                            01            <br />    Data Lo                            02 <br />    <br />    Wynikiem obliczeń jest : <br />                                 HEX<br />    Error Check Lo                 C6    <br />    Error Check Hi                 F0<br />                                  <br />        <br />******************************************************************************************************************/<br /><br />i jeszcze funkcja do obliczania CRC na podstawie <a href="http://www.modbus.org"  class="postlink">http://www.modbus.org</a><br />wynik 16 bitowy - przy czym starszy bajt to Lo CRC a młodszy bajt to Hi CRC<br /><br /><br />[syntax=c]ifndef CRC16_MODBUS_H_<br />#define CRC16_MODBUS_H_<br /><br />uint16_t CRC16(volatile char *adres, uint8_t usDataLen); // dlatego volatile, bo przekazuję bufor z UARTA, który jest volatile<br /><br />#endif  /* CRC16_MODBUS_H_ */[/syntax]<br /><br />[syntax=c]#include &lt;avr/io.h&gt; <br />#include &lt;avr/pgmspace.h&gt; <br />#include &quot;CRC16_MODBUS.h&quot;<br /><br />const uint8_t tab_CRCHi&#91;&#93; PROGMEM = {        <br />                                    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,<br />                                    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,<br />                                    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,<br />                                    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,<br />                                    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,<br />                                    0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,<br />                                    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,<br />                                    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,<br />                                    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,<br />                                    0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,                 <br />                                    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,<br />                                    0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,<br />                                    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,               <br />                                    0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,<br />                                    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,<br />                                    0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,<br />                                    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,<br />                                    0x40<br />                                    }; <br />                                 <br />const uint8_t tab_CRCLo&#91;&#93; PROGMEM = {<br />                                    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,<br />                                    0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,<br />                                    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,<br />                                    0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,<br />                                    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,<br />                                    0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,<br />                                    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,<br />                                    0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,<br />                                    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,<br />                                    0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,<br />                                    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,<br />                                    0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,<br />                                    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,<br />                                    0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,<br />                                    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,<br />                                    0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,<br />                                    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,<br />                                    0x40<br />                                    };<br /><br /> <br />uint16_t CRC16(volatile char *adres, uint8_t DataLen)<br /> {<br />   uint8_t CRCHi = 0xFF; /* high byte of CRC initialized */<br />   uint8_t CRCLo = 0xFF; /* low byte of CRC initialized */<br />   uint8_t Index;        /* will index into CRC lookup table */<br />                                                                 <br />   while (DataLen--) <br />    {                      <br />      Index = CRCHi ^ *adres++;         /* calculate the CRC */   <br />      CRCHi = CRCLo ^ pgm_read_byte(tab_CRCHi + Index);<br />      CRCLo = pgm_read_byte(tab_CRCLo + Index);<br />    }                                                      <br />                                                                   <br />   return  ((uint16_t) (CRCHi &lt;&lt; 8) | (uint16_t) CRCLo);                                                             <br /> }[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=4513">Artur_26</a> — 9 lis 2024, o 02:41</p><hr />
]]></content>
</entry>
</feed>