| |
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
|