Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: DS18B20 вычисление CRC как это сделать?!
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
eXeC001er
Можно подробнее, а если еще и примерчик что вабще гуд.
at90
для кодевижена. Использовалась для ds1990
#pragma warn-
unsigned char crc8(void *p,unsigned char n)
{
#asm
clr r30
ld r24,y
tst r24
breq __crc83
ldi r22,0x18
ldd r26,y+1
ldd r27,y+2
__crc80:
ldi r25,8
ld r31,x+
__crc81:
mov r23,r31
eor r23,r30
ror r23
brcc __crc82
eor r30,r22
__crc82:
ror r30
lsr r31
dec r25
brne __crc81
dec r24
brne __crc80
__crc83:
#endasm
}
#pragma warn+
m16
у меня есть рабочий пример на асме авр. вышлю на мыло к сообщению не прикрепляется-Ошибка загрузки
eXeC001er
Еще я не особенно врыбуюсь для каких байт считать этот CRC, там есть ROM и есть ScratchPad и там и там CRC, видать для каждого свой.
В апнотах от maxim-ic есть пример подсчета но там какой то табличный способ, как его использовать не пойму!
GxOST
Цитата(eXeC001er @ Jan 24 2006, 10:02) *
Можно подробнее, а если еще и примерчик что вабще гуд.

Отличная штука для понимания идеи
А вообще понимать не обязательно, берешь исходники и вперед.
eXeC001er
эт не то, я не разберусь в этих языках.
MicronSys
unsigned char one_wire_byte[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
IB_CRC=iButtonCRC(one_wire_byte);



unsigned char iButtonCRC( unsigned char *code)
{
unsigned char j, i, Data, tmp, CRC = 0;
for (j = 0; j < 7; j++)
{
Data = code[j];
for (i = 0; i < 8; i++)
{
tmp = 1 & (Data ^ CRC);
CRC >>= 1;
Data >>= 1;
if ( 0 != tmp ) CRC ^= 0x8c;
}
}
return CRC;
}

Простинко и совкусом 101% рабочая
cheers.gif
GxOST
Цитата(eXeC001er @ Jan 24 2006, 10:58) *
Цитата(GxOST @ Jan 24 2006, 10:42) *

Цитата(eXeC001er @ Jan 24 2006, 10:02) *

Можно подробнее, а если еще и примерчик что вабще гуд.

Отличная штука для понимания идеи
А вообще понимать не обязательно, берешь исходники и вперед.

эт не то, я не разберусь в этих языках.

да чего ж там понимать! Всё как на це. Вот пример формирования crc в соответствии со сгенеренным верилогом (табличный)
MicronSys
Цитата(GxOST @ Jan 24 2006, 13:08) *
Цитата(eXeC001er @ Jan 24 2006, 10:58) *

Цитата(GxOST @ Jan 24 2006, 10:42) *

Цитата(eXeC001er @ Jan 24 2006, 10:02) *

Можно подробнее, а если еще и примерчик что вабще гуд.

Отличная штука для понимания идеи
А вообще понимать не обязательно, берешь исходники и вперед.

эт не то, я не разберусь в этих языках.

да чего ж там понимать! Всё как на це. Вот пример формирования crc в соответствии со сгенеренным верилогом (табличный)


Не таблица енто отстой ПАМЯТЬ НЕ РЕЗИНОВАЯ !!! blink.gif
Если делать в тинька то лишние байты ох как нужны !!!!! a14.gif
haker_fox
В прикрепленной теме есть табличная реализация CRC8, а поиском по подфоруму можете найти и полный исходник для DS18B20...
MicronSys
Вот полный текст для работы с DS1990A

#define ONEWIRE 0x08 // BIT Какой пин использовать
#define ONEPIN (*(volatile unsigned char *)0x30) // PIN register
#define ONEDDR (*(volatile unsigned char *)0x31) // Data Direction Register
#define ONEPORT (*(volatile unsigned char *)0x32) // PORT

unsigned char one_wire_byte[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
void OneWireReadROM(void);
unsigned char OneWireReset(void);
unsigned char OneWireReadByte(void);
void OneWireWriteByte(unsigned char);
unsigned char iButtonCRC( unsigned char *code);

void OneWireReadROM(void) {
OneWireWriteByte(0x33);
one_wire_byte[0] = OneWireReadByte();
one_wire_byte[1] = OneWireReadByte();
one_wire_byte[2] = OneWireReadByte();
one_wire_byte[3] = OneWireReadByte();
one_wire_byte[4] = OneWireReadByte();
one_wire_byte[5] = OneWireReadByte();
one_wire_byte[6] = OneWireReadByte();
one_wire_byte[7] = OneWireReadByte();
one_wire_byte[8] = iButtonCRC(one_wire_byte);
}
unsigned char OneWireReset(void)
{
ONEPORT &= ~(ONEWIRE); // Normal input no pull up
if (!(ONEPIN & ONEWIRE)) return 0; // detect 0V on buss error
ONEDDR |= ONEWIRE; // out at 0
_delay_loop_2(462); // 500 us

ONEDDR &= ~(ONEWIRE); // Set to input
_delay_loop_2(64); // 70 us

if ((ONEPIN & ONEWIRE) == 0)
{
_delay_loop_2(462); // 500 us
return(1);
}
_delay_loop_2(462); // 500 us
return(0);
}
//********************************************************************************
*********
void OneWireWriteByte(unsigned char data)
{
unsigned char i;
ONEPORT &= ~(ONEWIRE);
for (i=0;i<=7;i++)
{
ONEDDR |= ONEWIRE;
if (data & 0x01)
{ // Send 1
_delay_loop_2(1); // 7 us

ONEDDR &= ~(ONEWIRE);
_delay_loop_2(32); // 70 us
}
else
{ // Send 0
_delay_loop_2(32); // 70 us
ONEDDR &= ~(ONEWIRE);
_delay_loop_2(1); // 7 us
}
data>>=1;
}
}
//********************************************************************************
*********
unsigned char OneWireReadByte(void)
{
unsigned char data = 0;
unsigned char i;

ONEPORT &= ~(ONEWIRE); // Output '0' or input without pullup
for (i=0;i<=7;i++)
{
ONEDDR |= ONEWIRE; // Set output to '0'
asm("nop");
ONEDDR &= ~(ONEWIRE); // Set to input
asm("nop");
data >>=1;
if (ONEPIN & ONEWIRE) data |= 0x80;
else data &= 0x7f;
_delay_loop_2(32); // 70 us
}
return data;
}
//********************************************************************************
*********
unsigned char iButtonCRC( unsigned char *code)
{
unsigned char j, i, Data, tmp, CRC = 0;
for (j = 0; j < 7; j++)
{
Data = code[j];
for (i = 0; i < 8; i++)
{
tmp = 1 & (Data ^ CRC);
CRC >>= 1;
Data >>= 1;
if ( 0 != tmp ) CRC ^= 0x8c;
}
}
return CRC;
}

int main(void)
{
if(OneWireReset()=1) // Есть ключ
{
OneWireReadROM()
if(one_wire_byte[7]=one_wire_byte[8]) // CRC OK
{
// Делаем что нужно
}


}

}
Помоему здесь все проще и понятней cheers.gif
ROC
А на чем пишем-то? ASM, C? Если С, то который?
Для BASCOM-AVR & FastAVR, например, вообще есть встроенная функция CRC8 и в FastAVR это выглядит весьма просто:

Dim tmpT(9) As Byte
'
' bla-bla-bla
'
Sub Read1820()
1Wread tmpT,9
If Crc8(VarPtr(tmpT),9)=0 Then ' check Crc, if OK
CalcTmp() ' calc temp
1Wreset
else
Locate 2,1: Lcd "DS18B20 CRC Error!"
end if

Что-то у меня ввод в виде кода не работает.... sad.gif
IgorKossak
Цитата(ROC @ Jan 24 2006, 11:29) *
Что-то у меня ввод в виде кода не работает.... sad.gif

Код
Dim tmpT(9) As Byte
'
' bla-bla-bla
'
Sub Read1820()
1Wread tmpT,9
If Crc8(VarPtr(tmpT),9)=0 Then    ' check Crc, if OK
  CalcTmp()        ' calc temp
  1Wreset
else
Locate 2,1: Lcd "DS18B20 CRC Error!"
end if

Работает
Atashi
ежели памяти полно, а надо быстро, то вот так:

crc8_tabl[]=
{
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};

// if bytes=7 ->returns CRC
// if bytes=8 -> returns 0
//

char crc8_compute(char * str, char bytes)
{
char crc8=0;

while (bytes)
{
crc8=crc8_tabl[crc8 ^ *str++];
--bytes;
}
return crc8;
}
wink.gif
eXeC001er
to MicronSys
а почему здесь 7 а не 8?! for (j = 0; j < 7; j++)
байтов то 9, последний CRC, которое считается по оставшимся 8 байтам.
m16
рабочий пример на асме. до восьми датчиков ds1820. переименовать в zip архив.
GxOST
Цитата(MicronSys @ Jan 24 2006, 12:18) *
Цитата(GxOST @ Jan 24 2006, 13:08) *

Цитата(eXeC001er @ Jan 24 2006, 10:58) *

Цитата(GxOST @ Jan 24 2006, 10:42) *

Цитата(eXeC001er @ Jan 24 2006, 10:02) *

Можно подробнее, а если еще и примерчик что вабще гуд.

Отличная штука для понимания идеи
А вообще понимать не обязательно, берешь исходники и вперед.

эт не то, я не разберусь в этих языках.

да чего ж там понимать! Всё как на це. Вот пример формирования crc в соответствии со сгенеренным верилогом (табличный)

Не таблица енто отстой ПАМЯТЬ НЕ РЕЗИНОВАЯ !!! blink.gif
Если делать в тинька то лишние байты ох как нужны !!!!! a14.gif

Таблица зато быстрей. Тут уж выбирай. К тому же можно табличную CRC, но обрабатывать по полбайта - таблица уменьшится с 256 до 16 байт (это для CRC8). В моем примере именно так и сделано для CRC16, правда там полубайты заранее разнесены по байтам, но кому надо - может переделать smile.gif

ЗЫ. Народ! вы про тэги [code] [/code] не в курсе что-ли?
eXeC001er
вот в айбатонах 8 байт и 8 это CRC! а в термометрах 9 байт. но в даташите тоже написано что то про 7 байт, никак не пойму.
по сайту поискал нашел, но файлы не скачиваются, говорит что их уже нет.
MicronSys
[quote name='eXeC001er' date='Jan 24 2006, 14:41' post='80832']
to MicronSys
а почему здесь 7 а не 8?! for (j = 0; j < 7; j++)
в сях 0 тоже ипользуется

типа 0,1,2..7 итого 8 байт cheers.gif
GxOST
Цитата(MicronSys @ Jan 24 2006, 17:57) *
to MicronSys
а почему здесь 7 а не 8?! for (j = 0; j < 7; j++)
в сях 0 тоже ипользуется

типа 0,1,2..7 итого 8 байт cheers.gif

j<7, значит 7 не считается. cranky.gif
MicronSys
Бывает a14.gif
BVU
Цитата(eXeC001er @ Jan 24 2006, 13:41) *
to MicronSys
а почему здесь 7 а не 8?! for (j = 0; j < 7; j++)
байтов то 9, последний CRC, которое считается по оставшимся 8 байтам.

Почитайте на этом сайте:
http://www.zinetz.info/article.php?id=home_temp2
Человек с этим разобрался и все подробно изложил, даже с примерами. smile.gif
Kovrov
на, мил человек, пользуйся и не мучейся :-)
Код
;*******************************************************************************
****
; Вычисление CRC (Х8+X5+X4+1) блока памяти
; в XH:XL надо загрузить начальный адрес блока памяти
; в count количество байт
;.def HiCRC = temp6
;.def LoCRC = temp5  здесь будет CRC8 блока памяти по окончании подпрограммы
;.def BitCount = temp2
;.def temp = r16
;.def count = temp3
;*******************************************************************************
****
CHECK_CRC:
    ldi        temp3,8        ; всего 8 байт
    LDX        (bufer_ds1820)
GetCRC_8:
      ldi     temp,0x18     ; загрузка полинома
      mov     temp6,temp     ; в регистр HiCRC
      clr     temp5         ; обнуление CRC регистра

CRC_Loop:
      ldi        temp2,8         ; указываем 8 бит для подсчета ;
      ld         temp,X+        ; берем байт из буфера

Bit_Loop:
      push     temp         ; сохранение байта в стеке
      eor     temp,temp5     ; xor байта и регистра CRC
      lsr     temp         ; сдвигаем младший бит получившегося байта в перенос
      brcc     Zero_0         ; проверяем младший разряд байта
      eor     temp5,temp6 ; если там 1, то CRC xor полином
Zero_0:
      ror     temp5          ; если там 0, то просто сдвиг CRC регистра
      pop     temp         ; возвращаем байт на место
      lsr     temp         ; и сдвигаем его
      dec     temp2       ;
      brne     Bit_Loop       ; переход на цикл проверки слеующего бита

      dec     temp3         ;
      brne     CRC_Loop     ; переход на следующий байт буфера
      ret


расчитана на вычисление группы байт
под темпы подставишь свои регистры
без труда переделаешь на апдейт CRC каждым новым байтом - что эффективней
типа как тока прочитал байт от 1820 сразу суешь его в эту процедуру
afe
Я уже давал эту ссылку и на этот вопрос там есть сорцы и для DS16b20:

http://electronix.ru/forum/index.php?showtopic=10934&st=15

http://hubbard.engr.scu.edu/avr/avrlib/
Pyku_He_oTTyda
Kovrov
Не обьясните, как начинающему на пальцах, как правильно определить буфер, например в 90S2313, и смоделировать программу в AVRstudio.
Особенно интересует, откуда берет значение строка

ld temp,X+ ; берем байт из буфера
m16
Цитата(Pyku_He_oTTyda @ Feb 1 2006, 08:57) *
Особенно интересует, откуда берет значение строка
ld temp,X+ ; берем байт из буфера


система команд авр. http://www.gaw.ru/html.cgi/txt/doc/micros/avr/asm/start.htm
Atashi
... давненько не был здесь; похоже, сомнения насчет 7/8/9 байтов где-то застряли.
Придется объясниться.

на таблетке ds1991 etс такая инфа набита: 01 - код семейства, потома 6 байтов кода, ище байт CRC:
итого выходить осемь байта.
Отчего и происходят мозоли, по авторитетному мнению г-на Пруткова. angry.gif
Pyku_He_oTTyda
m16
Торнутая в морду лица ссылка помоглаsmile.gif, мозги запудренные просветлились. На обеде разобрался, откуда берет данные.

Вопрос вдогонку - 01(код семейства) участвуеn в подсчете CRC?
m16
Цитата(Pyku_He_oTTyda @ Feb 1 2006, 13:21) *
m16
Торнутая в морду лица ссылка помоглаsmile.gif, мозги запудренные просветлились.

зачем так грубо. имхо если сам разобрался с карандашом то глубже оседает в извилинах.
http://www.gaw.ru/html.cgi/txt/app/micros/avr/avr318.htm
Pyku_He_oTTyda
С СRС разобрался вчера на базе примера от Kovrov. Немного расписал поподробнее, что бы начинающим было понятнее.

.include "2313def.inc"

.cseg
.org 0

.def temp = R16
.def count = R17
.def BitCount = R18
.def HiCRC = R19
.def LoCRC = R20 ;здесь будет СRC8 блока памяти по окончании подпрограмы


;блок ссылок на обработчики прерываний
;=====================================

rjmp RESET ;reset handler
nop ;rjmp EXT_INT0 ;IRQ0 handler
nop ;rjmp EXT_INT1 ;IRQ1 handler
nop ;rjmp TIM_CAPT1 ;timer1 capture handler
nop ;rjmp TIM_COMP1 ;timrt1 compare handler
nop ;rjmp TIM_OVF1 ;timer1 overflov handler
nop ;rjmp TIM_OVF0 ;timer0 overflov handler
nop ;rjmp UART_RXC ;UART RX complete handler
nop ;rjmp UART_DRE ;UDR empty handler
nop ;rjmp UART_TXC ;UART TX complete handler
nop ;rjmp ANA_COMP ;analog comparator handler


;*******************************************************************************
; Вычисление CRC (Х8+X5+X4+1) блока памяти
; в XH:XL надо загрузить начальный адрес блока памяти
; в count количество байт
;
; Данныее должны находится в блоке памяти в следующем порядке:
; начальный адрес памяти - Family Code
; следующие шесть - HEX чисела в обратном порядке, написанному на ключе
; последний адрес - СRС
;
; В результате успешных действий в регистре LoCRC должны находится нули
;*******************************************************************************

CHECK_CRC:
ldi count,8 ; всего 8 байт

GetCRC_8:
ldi temp,0x18 ; загрузка полинома
mov HiCRC,temp ; в регистр HiCRC
clr LoCRC ; обнуление CRC регистра

CRC_Loop:
ldi BitCount,8 ; указываем 8 бит для подсчета
ld temp,X+ ; берем байт из буфера

Bit_Loop:
push temp ; сохранение байта в стеке
eor temp,LoCRC ; xor байта и регистра CRC
lsr temp ; сдвигаем младший бит получившегося байта в перенос
brcc Zero_0 ; проверяем младший разряд байта (перейти, если перенос очищен)
eor LoCRC,HiCRC ; если там 1, то CRC xor полином

Zero_0:
ror LoCRC ; если там 0, то просто сдвиг CRC регистра
pop temp ; возвращаем байт на место
lsr temp ; и сдвигаем его
dec BitCount ; декременируем значение регистра
brne Bit_Loop ; переход на цикл проверки слеующего бита

dec count ; декременируем значение счетчика байт
brne CRC_Loop ; переход на следующий байт буфера

tst LoCRC ;проверяем на ноль CRC
breq good ;если равно нулю, переходим на метку "good"

ret ;если результат не равен нулю,
;возвращаемся из подпрограммы подсчета CRC

;*******************************************************************************

good:
rjmp good

;====
;MAIN
;====

RESET:

ldi temp,low(RAMEND) ;определение начала
out SPL,temp ;стека и ОЗУ

clr r27
ldi r26,0x60 ;загрузка начального адреса блока памяти


rjmp CHECK_CRC
Atashi
Да, 01 участвует.

Вообще, алгоритм-то универсальный, любые дивайсы, любое кво байтов катят.
Kovrov
Цитата(Pyku_He_oTTyda @ Feb 1 2006, 08:57) *
Kovrov
Не обьясните, как начинающему на пальцах, как правильно определить буфер, например в 90S2313, и смоделировать программу в AVRstudio.
Особенно интересует, откуда берет значение строка

ld temp,X+ ; берем байт из буфера

да ни каких особо ухищрений не нужно просто определяешь область озу в тиньке
если 2313 то там 128 байт всего
для 1820 нужно (процесс чтения после конвертации - в смысле когда температуа измерилась)
в такой последовательности ты их (байты)будешь получать от 1820
первым идет:
(1 байт температура младший байт)
2- температура старший байт
3- юзерский байт 1
4- юзерский байт 2
5 байт конфигурации
6- не используется
7- не используется
8 - не используется
9 - контрольная сумма (ради чего весь сыр бор)
- 9й можешь не писать в буфер тогда буфер будет 8 байт всего
но по началу лучше пиши
;---------
вообщем берешь каждый считанный байт и кидаешь его в буфер
буфер определяешь нну например от начала памяти (начало у тиньки есть адрес $60)
поэтому буфер будет от $60... $68 - всего 9 байт (вместе с контр суммой)
все это хозяйство а имеено начало буфера
LDI XL,low($0060)
LDI XH,high($0060) ; определяешь начало буфера
и 8 байт всего
кстати для тини старший байт не используется(т.к 128 байт всего) поэтому LDI r16,high(xxxx) можно
неписать после прогона процедуры в темп 5 получается контр сумма
она должна быть равна 9 байту буфера если равна то все ок можно сказать что чтение с 1820 произошло успешно если не ровна то извините....
d__
Вот еще один вариант реализации на языке С.
Характерная особенность-подсчитывает частичную контрольную сумму--т.е. с приходом каждого байта обновляется контрольная сумма. Переведено на С из контрольного примера в даташите на языке ассемблера Z80. Почему частичная--так удобнее, получил байт -- обновил контрольную сумму. Общая метода такова--перед началом приема информационного пакета контрольная сумма обнуляется. Потом принимаются все байты информационного пакета, включая контрольную сумму, каждый байт проходит через данную подпрограмму, обновляя контрольную сумму. Если пакет принят без ошибок, то вычисленная контрольная сумма равна нулю.

#define POLY8 (0x8c) //x^8+x^5+x^4+x^0 position bits are mirrored
// because register is shifted right


unsigned char partdowcrc(unsigned int oldcrc,unsigned char val)
{
register char i;
oldcrc ^= val;
for(i=0;i<8;i++)
{
if((oldcrc &1 )!=0)oldcrc ^= (POLY8 << 1);
oldcrc >>=1;
}
return oldcrc;
}
Pyku_He_oTTyda
Kovrov

Разве неправильно я расписал для 1990? При правильности считывания в LoCRC разве не должны быть нули? help.gif

;*******************************************************************************

; Вычисление CRC (Х8+X5+X4+1) блока памяти
; в XH:XL надо загрузить начальный адрес блока памяти
; в count количество байт
;
; Данныее должны находится в блоке памяти в следующем порядке:
; начальный адрес памяти - Family Code
; следующие шесть - HEX чисела в обратном порядке, написанному на ключе
; последний адрес - СRС
;
; В результате успешных действий в регистре LoCRC должны находится нули
;*******************************************************************************
Kovrov
Цитата(Pyku_He_oTTyda @ Feb 3 2006, 08:54) *
Kovrov

Разве неправильно я расписал для 1990? При правильности считывания в LoCRC разве не должны быть нули? help.gif

че уже считаем для 1990? недавно тока температуру читали ;-)
нет нулей быть не должно за исключением если сумма равна нулю...
кстати мне попадался экземпляр 1990 у которого реально крк = 00!
можешь выложить суда содержимое буфера
кстати для 1990 ( а если точнее результат команды "read rom"$33 - это 7байт +crc
Pyku_He_oTTyda
01 1E 06 CA 0C 00 00 70

Это конкретный ключ, проверил еще пяток, нули в LoCRC

01 код семейства, лежит в $60, остальное по порядку.
70 - CRC
Kovrov
Цитата(Pyku_He_oTTyda @ Feb 3 2006, 14:38) *
01 1E 06 CA 0C 00 00 70

Это конкретный ключ, проверил еще пяток, нули в LoCRC

01 код семейства, лежит в $60, остальное по порядку.
70 - CRC

только что прогнал через приведенную процедуру все совпало в смысле контро сумма = $70.
Kovrov
посмотрел на твой исходник
ты в твоем случае 8ой байт (крк) подставляешь в процедуру проверки и естественно если сумма совпала то
LOCRC = 0
только зачем лишний цикл?
проще поставить в count=7 а после сравнить $70и $70.
Твой вариант тоже верен.
а в чем проблема то? :-)
Pyku_He_oTTyda
Проблемы нет, просто хотелось уточнить все до конца. Тем более Ваш пример мне очень помог! Большое спасибо!
ilya514
Цитата(Pyku_He_oTTyda @ Feb 3 2006, 14:38) *
01 1E 06 CA 0C 00 00 70

Это конкретный ключ, проверил еще пяток, нули в LoCRC

01 код семейства, лежит в $60, остальное по порядку.
70 - CRC

А как вручную посчитать crc для этого ключа?
Pyku_He_oTTyda
И вопрос в догонку:
Если на шине присутствует подчиненный, то он должен в течение 60 мкс после освобождения ведущим шины установить низкий уровень длительностью не менее 60 мкс.

Как правильнее поступить:
1. Отследить наличие установки низкого уровня, по истечении 60мкс после освобождения линии ведущим?
2.Отследить не только наличие низкого уровня, но и измерить его длительнось?

По мне более правильным кажется второй вариант, но к примеру в AVR318 алгоритм такой:
Установка "0" мастером на 480мкс - освобождение шины - ждем 70мкс - чтение шины - ждем 410мкс - работаем дальше.
Вот как раз момент "чтение шины" не очень понятен, если не измерять длительность ответа, разве помехоустойчивость на высоте будет? Или с этим мирится и всю надежду возлажить на последующее чтение номера и подсчет CRC?
add
Цитата(Pyku_He_oTTyda @ Feb 8 2006, 08:53) *
Вот как раз момент "чтение шины" не очень понятен, если не измерять длительность ответа, разве помехоустойчивость на высоте будет?

Можно "читать шину" несколько раз(как в UARTе) в интервале ответа (60-240мкс) набирая статистику, обеспечивая тем самым высокий процент достоверности. Окно (имп.сбр+ожид60мкс+240мкс ответ)правда всеравно придется выдерживать.
Kovrov
Цитата(Pyku_He_oTTyda @ Feb 8 2006, 08:53) *
И вопрос в догонку:
Если на шине присутствует подчиненный, то он должен в течение 60 мкс после освобождения ведущим шины установить низкий уровень длительностью не менее 60 мкс.

Как правильнее поступить:
1. Отследить наличие установки низкого уровня, по истечении 60мкс после освобождения линии ведущим?
2.Отследить не только наличие низкого уровня, но и измерить его длительнось?


конечно! берешь таймер с тиком например мкс и зекаешь когда мастер сброс даст
сразу онулируешь тимер и следишь пока не кончиться ресет мастера
как кончился - смотришь че тамер на мерил если укладываешься в рамки то ок...
а вообще очень красиво и экономно засунуть его под EXT int и работать с его прерыванием
я так и делал очень приличная экономия!!
на счет 60 мкс - я не понял - речь идет о presence pulse?
Pyku_He_oTTyda
Цитата
на счет 60 мкс - я не понял - речь идет о presence pulse?

да, подчиненный должен ответить, что он на линии, низким уровнем не менее 60мкс
Цитата
а вообще очень красиво и экономно засунуть его под EXT int и работать с его прерыванием
я так и делал очень приличная экономия!!

можно принцип немного подробнее?
Kovrov
Presence pulsе делай по максимуму возможному а то у меня домофоны плохо открывались ;-)
насчет Ext int
заводишь это хохяйство на ногу внешнего прерывания
и настраиваешь прерывание на перепад 1-0
а пока ждешь прерывание контроллер переводишь в слип (холостой ход)
тоже самое делаешь когда принимаешь данные
Pyku_He_oTTyda
Ага, понятно, спасибо!
А проснется процессор при первом подключении таблетки? На этот вопрос ответа не нашел толкового. Имеется ввиду, спит процессор, ждет внешнего прерывания по спаду, подносим таблетку - он просыпается и начинает работу. Конечно можно промоделировать, но хочется стабильного результата.
Как вы в домофоне делали, если не секрет?
Есть идея использовать WDR, но не очень нравится
Kovrov
если на инт0 посадишь то вообще может от любого шороха проснуться!!!! ;-)
посмотри в дадашите на sleep mode select
PLATRO
парни а ниукаво нету просто проги для подсчета CRC ? ну типо чтоб вводишь в нее байты а она CRC щитает ?
defunct
Цитата(PLATRO @ Jun 13 2006, 20:58) *
парни а ниукаво нету просто проги для подсчета CRC ? ну типо чтоб вводишь в нее байты а она CRC щитает ?

Гм.. дык, CRC разные бывают от полинома зависит.
Вот функция на Delphi, подставляйте в нее нужный вам (Divisor) и будет вам CRC8 по требуемому полиному. Divisor задается как: bit15 <=> x^8, bit14 <=> x^7, .... , bit7 <=> x^0, остальные биты bit6..0 = 0.

Код
function CRC8( data: ShortString):byte;
// расчет CRC8 по образующему полиному x8 + x5 + x2 + 1
const
   Divisor = $9280; // [1001 0010 1]000 0000, в квадратных скобках образующий полином
var
   CodeWord : Cardinal;
   Temp  : Cardinal;
   i, j : integer;
begin
   if Length( data ) < 2 then
      raise Exception.Create('the data string must be at least 2 bytes long');
   Temp := byte(data[1]);
   for i := 2 to Length( data ) do
   begin
      CodeWord := Divisor;
      Temp := Temp shl 8 or byte(data[i]);
      for j := 15 downto 8 do
      begin
         if (Temp and (1 shl j) <> 0) then
            Temp := Temp xor CodeWord;
         CodeWord := CodeWord shr 1;
      end;
   end;
   Result := Temp and $FF;
end;


Строка data должна оканчиваться #0 обязательно, в этот 0 и помещается CRC.
При желании функция легко переделывается для расчета СRC16/CRC24
PLATRO
да в том то и фишка что я знаю тока vb )) и компиляторов нету. мнебы прогу готовую в которую вводишь семь байт и она щитает CRC-8. понимаю канешно что может много хочу, но малоли у каво есть)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.