Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

modbus crc16 mcu:pic16
http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=2287
Страница 1 от 1

Автор:  the_real_maniac [ Нед Апр 30, 2006 1:29 pm ]
Заглавие:  modbus crc16 mcu:pic16

Пиша си код за генериране за CRC16 за modbus и като цяло нищо сложно.
Даже за няма и 5мин написах кода, обаче нещо не се получава.

Цитат:

Generating a CRC

Step 1 Load a 16-bit register with FFFF hex (all 1's). Call this the CRC register.

Step 2 Exclusive OR the first eight-bit byte of the message with the low order byte of the 16-bit CRC register, putting the result in the CRC register.

Step 3 Shift the CRC register one bit to the right (toward the LSB), zerofilling the MSB. Extract and examine the LSB.

; Кой LSB да се чете , новият или този който "изпада" при преместването / shift-a ?

Step 4 If the LSB is 0, repeat Step 3 (another shift). If the LSB is 1, Exclusive OR the CRC register with the polynomial value A001 hex (1010 0000 0000 0001).

Step 5 Repeat Steps 3 and 4 until eight shifts have been performed. When this is done, a complete eight-bit byte will have been processed.

Step 6 Repeat Steps 2 ... 5 for the next eight-bit byte of the message. Continue doing this until all bytes have been processed.

Result The final contents of the CRC register is the CRC value.



_едит_

нарочно пиша тук след правилата веднага , и

значи изпълняват се 3-та стъпка след това 4-та и след това се брой , така го разбирам.
И относно кой LSB се проверява, това extract ме тегли повече към мисълта , че новият LSB се чете.
Кода на този вариант не съм го дал , ще го дам нарочно в нов пост, но пак не ми излизат стойностите, вярно близко

edit2: hmm дори и това ново разбиране обаче се оказва не както трябва

получавм C198 , вместо А194
а и не се връзва ... :-( защо е толкова двузначно написано е*ати.
кой shift-ваня се броят и кой не да му ***

_крайедит_


Код:

   ERRORLEVEL   -302

   LIST   p=PIC16F628A
   #include<p16f628a.inc>
   __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF & _BODEN_OFF
   #define   RAMBASE 0x20

#define   RESET_VECTOR   0x000
#define   INT_VECTOR      0x004

   ORG   RESET_VECTOR
   goto   start
   ORG   INT_VECTOR

   goto   interrupt

   CBLOCK   RAMBASE

   CRC_HI, CRC_LO, CRC_SHIFTC

   ENDC

MODBUS_CRC_INIT MACRO

   movlw   0xFF
   movwf   CRC_HI
   movwf   CRC_LO

   ENDM

start:

   MODBUS_CRC_INIT

   movlw   0x0b
   call   modbus_crc16
   movlw   0x0f
   call   modbus_crc16
   movlw   0x00
   call   modbus_crc16
   movlw   0x00
   call   modbus_crc16
   movlw   0x00
   call   modbus_crc16
   movlw   0x01
   call   modbus_crc16

   goto   $

modbus_crc16:   

   xorwf   CRC_LO,F

   movlw   0x08
   movwf   CRC_SHIFTC   ; shiftcount

crc16_shift:

   bcf   STATUS,C
   rrf   CRC_HI,F
   rrf   CRC_LO,F
   
   decfsz   CRC_SHIFTC,F
   goto   crc16_continue
   return

crc16_continue:

   btfss   STATUS,C
   goto   crc16_shift
   
   movlw   0xA0
   xorwf   CRC_HI,F
   movlw   0x01
   xorwf   CRC_LO,F

   goto   crc16_shift
;
;

interrupt:

   return
;
;

   END



вярното CRC на горното е

CRC_LO = 94
CRC_HI = a1

а аз получавам

CRC_LO = EB
CRC_HI = 49

Автор:  the_real_maniac [ Нед Апр 30, 2006 10:14 pm ]
Заглавие: 

http://www.embeddedrelated.com/groups/p ... w/4385.php

Код:

;-------------------------------------------------------------------------------------------------
;   ******************************  CRC16 routine  ******************************************
;-------------------------------------------------------------------------------------------------
;--CLASS REGISTERS-----------------------------------------------------------
;Temp1   
;CRC_High
;CRC_Low   
;----------------------------------------------------------------------------
CallAddCRC16M
  xorwf CRC_High,f
  movlw 8
  movwf Temp1

CRC_Loop
  bcf ALUSTA,C
  rrcf CRC_Low,f
  rrcf CRC_High,f
  btfss ALUSTA,C
  goto NoXOring
  movlw B'10100000'
  xorwf CRC_Low,f
  movlw B'0000001'
  xorwf CRC_High,f
NoXOring
  decfsz Temp1,F
   goto CRC_Loop
  return



близко съм бил ,ама с тея двузначни правила ...

едит2: просто гледам първият ми опит и разликата е , че след последният shift (8-мият не се прави една проверка на LSB и съответно се губи един евентуален XOR, поне така го виждам аз). крайедит2

едит:

Значи забелязва се къде е разковничето точно в интерпретацията на повторният shift ако LSB=0 и броенето все пак.

Не ме радва никак факта , че такива правила са написани така двузначно , вместо човек сам да си свърши работа, за да ги разбера трябваше да намеря готов код. Не ми хареса.

Код:
   ERRORLEVEL   -302

   LIST   p=PIC16F628A
   #include<p16f628a.inc>
   __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF & _BODEN_OFF
   #define   RAMBASE 0x20

#define   RESET_VECTOR   0x000
#define   INT_VECTOR      0x004

   ORG   RESET_VECTOR
   goto   start
   ORG   INT_VECTOR
   goto   interrupt

   CBLOCK   RAMBASE

   CRC_HI, CRC_LO, CRC_SHIFTC

   ENDC

MODBUS_CRC_INIT MACRO

   movlw   0xFF
   movwf   CRC_HI
   movwf   CRC_LO

   ENDM

start:

   MODBUS_CRC_INIT

   movlw   0x0b
   call   modbus_crc16
   movlw   0x0f
   call   modbus_crc16
   movlw   0x00
   call   modbus_crc16
   movlw   0x00
   call   modbus_crc16
   movlw   0x00
   call   modbus_crc16
   movlw   0x01
   call   modbus_crc16

   goto   $

modbus_crc16:   

   xorwf   CRC_LO,F
   movlw   D'8'
   movwf   CRC_SHIFTC   ; shiftcount

crc16_shift:

   bcf   STATUS,C         ; zero the MSB
   rrf   CRC_HI,F         ; shift toward LSB
   rrf   CRC_LO,F         ; STATUS,C carry the bit frmo HI to LO

   btfss   STATUS,C      ; check LSB
   goto   crc16_end      ; if 0 -> shift again + MSB=0

   movlw   0xA0         ; if 1 -> CRC16 XOR 0xA001
   xorwf   CRC_HI,F
   movlw   0x01
   xorwf   CRC_LO,F

crc16_end:

   decfsz   CRC_SHIFTC,F
   goto   crc16_shift
   return
;
;

interrupt:

   return
;
;

   END



и всичко точно.

Автор:  Syrius-B [ Пон Май 01, 2006 12:38 am ]
Заглавие: 

Не разбирам, защо сте се втренчили в CRC. Никак не е удобно за реализация с процесор.
Модбъс има и ASCII вариант, и проверката за грешки се прави побайтово - LRC. Играчка работа.
CRC е измислен за хардуерна реализация и там върши работа наистина.

Автор:  the_real_maniac [ Пон Май 01, 2006 9:46 am ]
Заглавие: 

modbus като цяло е нещо ново за мен.
Чел съм една част от документацията на протокола и да ... има modbus RTU и modbus ASCII, обаче в моят случей се ползва RTU - това (1) . Правя master ;-)

(2) може и аз да съм се заблудил, но правилата при RTU ми се виждат по-прости, а защо ненужно да усложнявам.

При modbus ASCII всеки байт се праща с 2 байта - всяка 8бит стойност се представя в шестнайсетичният й вид чрез ASCII (ясно , че това го знаеш , но започвам мисъл :-))

1byte = 0xA1 -> 2bytes send 'A' '1'


- добавям още една задача към процесора да преобразува 8бит стойност в 2 ASCII.
отделянето на младшата и старшата тетрада не е проблема.

- генерирам двойно повече трафик.*

Не знам, но не виждам плюса :-?

Относно LRC - определено изглежда по-лесно за генериране и пак не знам дали Този + си заслужава.

Много Ви благодаря за включвате , ще го имам предвид , очевидно имате опит с Modbus.

* - сетих се и за това -> използвам двойно повече време , а знаем , че серийната комуникация е чуствителна към времената , т.е увеличавам времето през което мцу-то не може да прави друго, освен да се занимава с приемане изпращане. Не че в случея има такова нещо, но реших да го спомена.

Автор:  Syrius-B [ Пон Май 01, 2006 10:23 am ]
Заглавие: 

В режим RTU даже и с UART-а ще имаш проблем - таймингите между байтовете са критични, тъй като основния рзделител между пакетите е по време.
CRC освен това ще ти харчи на порядък повече и памет и производителност. Ако и времето и ресрсите (процесора) са ограничени - дали заради 0х00 формата на данните си струва?

Автор:  the_real_maniac [ Пон Май 01, 2006 10:51 am ]
Заглавие: 

ОК. В случея при положение , че Slave у-вото е с RTU и да иска човек няма как да работи с ASCII ..., нали ?

Не виждам проблема с RTU и UART.
Master си подготовя запитването - всеки един от байтовете в съобщението и ги праща един след друг (т.е в момента , в който байт N е изпратен , се изпраща N+1 и така). Така че няма да се се достигне timeout ;-)
При получавне на отговора от страна на master-a се изисква само да слуша и евентуално да следи да не се получи timeout. Така че пак не виждам проблема с UART-a.

Относно CRC, LRC. Определено CRC е по-усложнено за изичсление - което ме подсеща ,че трябва да видя колко време отнема в най-лошият случей изчисляването за 1byte :-| Но пък 16бит стойност намалява вероятността за грешка до ...

Въпросът , който повдигаш е наистина интересен.

Доколкото те разбирам казваш, че генерирането на CRC на съобщението е повече или голяма част от време за 'преобразуването на всеки байт в два ASCII код числа за цялото съобщение + изчисляване на LRC'.

Автор:  Syrius-B [ Пон Май 01, 2006 11:32 am ]
Заглавие: 

Ако Slave у-вото е с RTU и това не зависи от теб - наистина нямаш избор.
Ако по бавна линия ще пращаш големи масиви от данни (файлове?), и същевременно ще управляваш нещо в реално време - RTU е по-бързо (но само 2 пъти)
Във всички други случай RTU е по-зле на порядък (!10 пъти)

Автор:  the_real_maniac [ Пон Май 01, 2006 12:06 pm ]
Заглавие: 

1. У-вото е RTU.

2.Далеч съм от мисълта за файлове - просто данни (1bit access & 16bit access).
Линията е бавна - 9600bps (знам , че modbus дефинира 9600/19200 за серийна линия, а нагоре ако искаш имаше някои правила, за да се изчислят timeout закъсненията , но това не ме интересува; 9600 е скоростта)

Отделно още не мога да се представя какво е "файл" според Modbus. Май файл се ползва по-скоро като масив от данни, отколкото в смисъл на файл, но това е друга тема.

Случеят е този - бавна линия, през <1сек някъде ще се извлича информация с команди 01,02,03,04 за всички digital & analog i/o , които има Slave у-во; а Slave у-вото управлява в реално време.

Грубо(!) смятам , че имам да прочета около 50 байта.

Много благодаря за информацията относно ASCII ! Бях останал със съвсем друго впечатление :-)

едит: всъщност у-вата ще са няколко ~4 така че се получават ~200байта/сек полезна информация.

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/