• Главная • Назад •








Counter

 


CRC - циклический избыточный код
 


Здесь приведены примеры программ дляк PIC-контроллеров.

 


CRC-8 (пример для PIC16F84)

list p=p16f84
#include p16f84.inc
;===============================================================
;
; CRC-8 для Dallas iButton устройств
;
;
; From Maxim/Dallas AP Note 27
;
; "Understanding and Using Cyclic Redundancy Checks with
; Dallas Semiconductor iButton Products"
;
; Здесь описывается CRC-8 алгоритм используемый в изделиях iButton.
; Здесь также приводятся два примера, вычисления CRC-8.
;
;
; 18JAN03 - T. Scott Dattalo


cblock 0x20
    crc
endc

org 0
    goto start

;===============================================================
crc_8:
        xorwf     crc,f
        clrw
        btfsc      crc,0
        xorlw     0x5e
        btfsc      crc,1
        xorlw     0xbc
        btfsc      crc,2
        xorlw     0x61
        btfsc      crc,3
        xorlw     0xc2
        btfsc      crc,4
        xorlw     0x9d
        btfsc      crc,5
        xorlw     0x23
        btfsc      crc,6
        xorlw     0x46
        btfsc     crc,7
        xorlw     0x8c
        movwf     crc
    return

;===============================================================
start:

        clrf         crc
        movlw    1
        call         crc_8     ; crc = 0x5e

        clrf         crc
        movlw     2
        call         crc_8     ; crc = 0xbc

        clrf         crc
        movlw     4
        call         crc_8 ; crc = 0x61

        clrf         crc
        movlw     8
        call         crc_8 ; crc = 0xc2

        clrf         crc
        movlw     0x10
        call         crc_8 ; crc = 0x9d

        clrf         crc
        movlw     0x20
        call         crc_8 ; crc = 0x23

        clrf         crc
        movlw     0x40
        call         crc_8 ; crc = 0x46

        clrf         crc
        movlw     0x80
        call         crc_8 ; crc = 0x8c

; пример для dallas:

        clrf         crc
        movlw     0x02
        call         crc_8 ; crc = 0xbc

        movlw     0x1c
        call         crc_8 ; crc = 0xaf

        movlw     0xb8
        call         crc_8 ; crc = 0x1e

        movlw     0x01
        call         crc_8 ; crc = 0xdc

        movlw     0x00
        call         crc_8 ; crc = 0xf4

        movlw     0x00
        call         crc_8 ; crc = 0x15

        movlw     0x00
        call         crc_8 ; crc = 0xa2

        movlw     0xa2
        call         crc_8 ; crc = 0x00

        goto     start

end


CRC-16 (пример для PIC16F876A)

; * Этот модуль вычисляет контрольную сумму для полинома CRC16. Полином CRC16 определен *
; * как x16+x15+x2+x0. Вычисление сделано поразрядным приведением. Алгоритм проектирован *
; * для сообщения в два байта шириной. Алгоритм может легко быть изменен для более длинных сообщений. *
; ***********************************************************************************************


list p=16f876A                           ; list directive to define processor
#include <p16f876A.inc>             ; processor specific variable definitions
errorlevel 2
__CONFIG _CP_ALL & _CPD_ON & _WDT_ON & _HS_OSC & _BODEN_ON & _PWRTE_ON & _WRT_OFF & _LVP_OFF

#define PolynomLow b'00000101'    ; младший байт polynome
#define PolynomHigh b'10000000'    ; старший байт polynome
;#define PolynomLength 0x10        ; 16-разрядная длина polynome
#define DataLength .10                 ; Длина данных в Байтах
#define Iterations 0x08                  ; число итераций для вычисления циклического контроля избыточности

cblock 0x20
        CRC_HIGH            ; CRC старший байт
        CRC_LOW            ; CRC младший байт
        CRC_BUFF            ; CRC буферный регистр
        BITS                   ; число информационных разрядов
        DATABYTES          ; Число байт в буфере
        TEMP                  ; временный register
endc

ORG 0x00
;============================================================================================
; очистка памяти данных ;
                 movlw     0x20          ; банк 0
                 movwf     FSR           ;
 ClfMem0     clrf         INDF              ;
                 incf         FSR,f     ;
                 movlw     0x40       ;
                 subwf     FSR,w     ;
                 BNZ     ClfMem0     ;
                 clrf     INDF           ;
;============================================================================================


Begin         movlw     0x26         ; Данные для поколения циклического контроля избыточности
                movwf     FSR          ; Пункт установите, чтобы начаться из блока данных
                movlw     .0             ; data
                movwf     INDF         ;
                incf         FSR,f
                movlw     .1                 ; data
                movwf     INDF             ;
                incf         FSR,f
                movlw     .2                 ; data
                movwf     INDF             ;
                incf         FSR,f
                movlw     .3                 ; data
                movwf     INDF             ;
                incf         FSR,f
                movlw     .4             ; data
                movwf     INDF         ;
                incf         FSR,f
                movlw     .5             ; data
                movwf     INDF         ;
                incf         FSR,f
                movlw     .6             ; data
                movwf     INDF         ;
                incf         FSR,f
                movlw     .7         ; data
                movwf     INDF         ;
                incf         FSR,f
                movlw     .8         ; data
                movwf     INDF         ;
                incf         FSR,f
                movlw     .12         ; data
                movwf     INDF             ;
                incf         FSR,f
                movlw     .12         ; data
                movwf     INDF     ;
; инициализация, что должно быть сделано перед подпрограммой CRC16, может быть
; названный. Регистр FSR содержит указатель на первый байт
; данные и регистр DATABYTES содержат число байтов данных
; из сообщения.

                movlw 0x26         ; указатель установите на первое местоположение данных
                movwf FSR          ; инициализируйте регистр FSR

Main

                call         CRC16Generate            ; вычислите значение CRC16
; Запись CRC в конец массива данных
                incf         FSR, f                         ; укажите, чтобы позиционировать позади последнего байта данных
                movf       CRC_HIGH, w               ; скопируйте данные CRC_HIGH в w-регистр
                movwf    INDF                           ; скопируйте CRC_HIGH behing последний байт данных
                incf         FSR, f                         ; укажите на следующее местоположение
                movf       CRC_LOW, w                ; скопируйте данные CRC_LOW в w-регистр
                movwf     INDF                           ; данные копии в следующее местоположение

                movlw     0x26                            ; указатель установити на первое местоположение данных
                movwf     FSR                             ; инициализируйте регистр FSR
                call          CRC16Restore                ; восстановите значение CRC16

Stop goto Stop ;

; *******************************************************************************
; * Заголовок: Вычисление CRC16 *
; * параметр Input: Указатель на первый байт данных (указатель в регистре FSR) *
; * Число байтов данных запоминало в регистре DATABYTES *
; * Выходное устройство: Результат циклического контроля избыточности, запомненный в CRC_HIGH и CRC_LOW *
; *******************************************************************************
CRC16Generate
                call         CRC16Init               ; инициализируйте регистраторов
                movlw     0x03                     ; initialize TEMP register with 2
                movwf     TEMP                    ; move 0x02 into TEMP

NextCRC16
                call           CRC16Engine         ; Вычислите CRC16 для одного байта
                decfsz       DATABYTES, f       ; уменьшение счетчика обработанных байт
                goto          Reload                 ; переход на загрузку очередного байта

                decfsz         TEMP, f                ; decrement TEMP register
                goto             AppendZeros        ; Append zeros to message
              retlw 0x00                                ; return to main

AppendZeros
                  clrf         CRC_BUFF ; Подготовка для обработки
                  movlw     Iterations ; одного такта CRC
                  movwf     BITS ; с с байтом 0х00
                  incf         DATABYTES, f ;
                  goto         NextCRC16 ;

Reload ; Загрузка следующего байта из буфера
                    incf            FSR, f ; увеличить указатель
                    movf           INDF, w ; загрузить данные в аккумулятор
                    movwf         CRC_BUFF ; загрузить CRC_BUFF register
                    movlw         Iterations ; инициализировать register BITS
                    movwf         BITS ; загузить 8 в register BITS
                goto     NextCRC16 ; вычисление calculate next CRC
;=======================================================================================================
; * Titel: Восстановите функцию циклического контроля избыточности *
; * Ввод: Указатель на первый байт данных в FSR регистрируется *
; * Выходное устройство: циклический контроль избыточности w=0 был восстановлением sucessfull *
; * w=1 циклический контроль избыточности не был восстановлен sucessfull *
;=======================================================================================================
CRC16Restore
                        call CRC16Init ; initialize CRC registers
                        movlw 0x02 ; add offset to DATABYTES
                        addwf DATABYTES, f ; add offset to register DATABYTES
NextCRCRestore ;
                        call CRC16Engine ;
                    decfsz         DATABYTES, f             ; Decrement the number of data bytes by one
                    goto         ReloadRestore                 ; reload CRC_BUFF register with new data byte
; check if CRC_HIGH and CRC_LOW equal to zero
                    movf         CRC_HIGH, f                 ; copy CRC_HIGH onto itself
                    btfss         STATUS, Z                 ; is content zero?
                    goto         CRCError                 ; no, CRC error occured
                    movf         CRC_LOW, f             ; copy CRC_LOW register onto itself
                    btfss         STATUS, Z                 ; is content zero?
                    goto         CRCError                     ; no, CRC error occured
                    retlw         0x00                         ; return to main (0= no error)
CRCError ;
                    retlw         0x01 ; return to main with error code 1
; Reload CRC buffer register with new data word.
ReloadRestore ;
                    incf         FSR, f ; point to next data byte
                    movf        INDF, w ; copy data into w-register
                    movwf     CRC_BUFF ; move data into CRC_BUFF register
                    movlw      Iterations ; initialize register BITS with 8
                    movwf     BITS ; move 8 into register BITS
                    goto        NextCRCRestore ; calculate next CRC
;=======================================================================================================
; * Titel: Инициализация CRC16 *
; * Ввод: Указатель на первый байт данных в FSR регистрируется *
; * Выходное устройство: ни один *
;=======================================================================================================
CRC16Init ;
                    movf          INDF, w          ; копируем данные в W-register
                    movwf        CRC_HIGH          ; копируем из w-register в CRC_HIGH register
                    incf            FSR, f              ; установим указатель на следующие данные
                    movf          INDF, w            ; копируем данные в w-register
                    movwf        CRC_LOW          ; копируем из w-register в CRC_LOW
                    incf           FSR, f               ; установим указатель на следующие данные
                    movf          INDF, w            ; копируем данные в w-register
                    movwf        CRC_BUFF          ; копируем данные в буфер CRC register
                    movlw         Iterations          ; инициализируем регистр BITs (0х08)
                    movwf        BITS                ; продолжительность полинома для итерации
                    movlw         DataLength          ; Загрузить количество байт в буфере
                    movwf         DATABYTES          ; для обработки
                    movlw         0x03                   ; скоректировать количество байт в буфере
                    subwf          DATABYTES, f     ; т.к. 3 байта уже загружены.
                    retlw          0x00                   ; возврат из подпрограммы инициализации
;=======================================================================================================
; * Titel: Механизм CRC16 *
; * Ввод: Указатель на первый байт данных в FSR регистр *
; * Выходное устройство: ни один *
;=======================================================================================================
CRC16Engine ;
                    bcf          STATUS, C          ; очистить бит переноса
                    rlf          CRC_BUFF, f          ; shift bit7 of CRC_BUFF into carry flag
                    rlf          CRC_LOW, f          ; shift bit7 of CRC_LOW into carry flag and shift 0 into bit7 of CRC_LOW
                    rlf          CRC_HIGH, f          ; rotate carry flag into bit0 of CRC_HIGH and rotate bit7 of CRC_HIGH into carry flag
;
                    btfss          STATUS, C          ; тестировать бит переноса установлен?
                    goto          NextBitEngine          ; carry flag is clear there next rotation
                    movlw          PolynomHigh          ; carry flag is set therefore XOR CRCSHIFT registers
                    xorwf          CRC_HIGH, f          ; XOR CRC_HIGH register
                    movlw          PolynomLow          ; load w-register with low byte of polynom
                    xorwf          CRC_LOW, f          ; XOR CRC_LOW register
NextBitEngine ;
                    decfsz          BITS, f          ; do for all bits
                    goto          CRC16Engine          ; calculate CRC for next bit
                    retlw          0x00          ; return from Subroutine
;=======================================================================================================
END

 


Для получения дополнительной информации используйте:

MAGETEX
Ukraine
Телефон: +380-50-575-98-63
Факс: +380-50-575-98-63
Интернет: invent-systems@ya.ru
 

Главная | Назад
 
Отправить сообщение для: gchernov@mail.ru с вопросами и замечаниями об этом веб-узле.
© 2007 MAGETEX
Дата изменения: 23.08.2013