Ответ

Предупреждение: в данной теме не было сообщений более 730 дней.
Если не уверены, что хотите ответить, то лучше создайте новую тему.
Имя:
E-mail:
Тема:
Иконка:

Визуальная проверка:
Белое солнце ...:
Денег нет, но вы ...:
Тебя что, в Гугле ... ?:

подсказка: нажмите alt+s для отправки или alt+p для предварительного просмотра сообщения


Сообщения в этой теме

Автор: Andy
« : 17 Марта 2011, 16:40:33 »

Дополз, наконец, до штриховского протокола. Командный процесор уже наваял, на днях буду алгоритм pumpkin-а опрелеление скорости порта тестить...
Автор: pumpkin
« : 23 Декабря 2010, 16:59:19 »

Да, CRC16 - 16 битный. И в протоколе (http://www.cashcodesm.narod.ru/download/cashcode-net-interface.doc), насколько я понял, тоже 2 байта под CRC отводится. Причем младший байт впереди.
Автор: Andy
« : 23 Декабря 2010, 13:24:46 »

Блин, сейчас внимателнее прочитал мануал, и увидел, что за crc отвечает не один а два байта. Тем не менее, код работает, поправлять почти ничего не пришлось...
Автор: Andy
« : 23 Декабря 2010, 12:03:35 »

Спасибо! Все  заработало!

А в чем проблема была? Они паскалевский код криво написали? Сишные птичьи закорючки уже сил небыло разобрать...
Автор: pumpkin
« : 22 Декабря 2010, 18:26:40 »

Вот такой код у меня вышел
Цитировать
$crystal = 10000000
$regfile = "m32def.dat"

Dim Indata(5) As Byte
Dim Crcval As Word
Dim Datalen As Word

Datalen = 5
Indata(1) = &H02
Indata(2) = &H03
Indata(3) = &H06
Indata(4) = &H33
Indata(5) = &HDA
Print "CRC TEST"
Gosub Crc
Print Hex(crcval)
Print "END"
Print "-------------------"
End
End

Crc:
Dim I As Byte
Dim Tmpcrc As Word
Dim J As Byte
Dim W As Word
Crcval = 0
For I = 1 To Datalen
Tmpcrc = Crcval Xor Indata(i)
  For J = 0 To 7
    W = Tmpcrc And &H0001
    Shift Tmpcrc , Right , 1
    If W <> 0 Then
      Tmpcrc = Tmpcrc Xor &H8408
    End If
  Next J
  Crcval = Tmpcrc
Next I
Return

Выдаваемый на консоли результат:
CRC TEST
0081
END
-------------------
Автор: Andy
« : 22 Декабря 2010, 16:52:52 »

Блин, нашел еще мануал по этому протоколу. Там вообще финиш.

Код на си
Цитировать
#define POLYNOMIAL 0x08408
unsigned int GetCRC16(unsigned char* bufData, unsigned int sizeData)
{
unsigned int CRC, i;
unsigned char j;
CRC = 0;
for(i=0; i < sizeData; i++)
{
CRC ^= bufData;
for(j=0; j < 8; j++)
{
if(CRC & 0x0001) {CRC >>= 1; CRC ^= POLYNOMIAL;}
else CRC >>= 1;
}
}


Код на паскале
Цитировать

const CCNET_CRC_POLY = $08408
function GetCRC16(InData: array of byte; DataLng: word): word;
var i: word;
j: byte;
begin
result:=0;
for i:=0 to (DataLng-1) do
begin
result:=result xor InData;
for j:=0 to 7 do
begin
if (result and $0001)<>0 then
begin
result:= result shr 1;
result:= result xor CCNET_CRC_POLY;
end
else
result:= result shr 1;
end;
end;
end;
Мой код.
Цитировать

Crc:
Dlinna2 = Dlinna - 1
Result = 0
For I = 1 To Dlinna2
  Result = Result Xor Indata(i)
  For J = 0 To 7
    Tmpcrc = Result And &H1
    If Tmpcrc <> 0 Then
       Shift Result , Right , 1
       Result = Result Xor Cr_ccnet_crc_poly
       Else
     Shift Result , Right , 1
    End If
   Next
Next
If Result = Bytecrc Then
Commandrecived = 1
Else
Xorsumerror = 1
Printbin Result
End If
Return





Результат crc - 0! что и не удивительно, как ноль ни крути он нолем и останется. Это даже я понимаю..
Автор: Andy
« : 22 Декабря 2010, 16:25:06 »

Бьюсь сейчас с протоколом CCNET, там скорость всего одна но с подсчетом контрольной суммы заморочка снова.

Код есть на си и паскале, перевел его в баском с паскаля - фигня выходит, CRC не совпадает, хоть убей...

Вот код на си:

Цитировать
#define POLYNOMIAL 0x08408

unsigned int GetCRC16(unsigned char* bufData, unsigned int sizeData)
{
  unsigned int TmpCRC, CRC, i;
  unsigned char j;
  CRC = 0;
  for(i=0; i < sizeData; i++)
   {
    TmpCRC = CRC ^ bufData;
    for(j=0; j < 8; j++)
     {
      if(TmpCRC & 0x0001) {TmpCRC >>= 1; TmpCRC ^= POLYNOMIAL;}
      else TmpCRC >>= 1;
     }
   }
  return CRC;
}




Вот на паскале:
Цитировать

const _CR_CCNET_CRC_POLY = $08408

function GetCRC16(InData: array of byte; DataLng: word): word;
var i,TmpCRC: word;
    j: byte;
begin
result:=0;
for i:=0 to (DataLng-1) do
 begin
  TmpCRC:=result xor InData;
  for j:=0 to 7 do
   begin
    if (TmpCRC and $0001)<>0 then
     begin
      TmpCRC:=TmpCRC shr 1;
      TmpCRC:=TmpCRC xor _CR_CCNET_CRC_POLY;
     end
                                  else
     TmpCRC:=TmpCRC shr 1;      
   end;
  result:=TmpCRC;
 end;
end;



Вот я на баскоме нарулил:

Цитировать

Crc:
Dlinna2 = Dlinna - 1
Result = 0
For I = 1 To Dlinna2
  Nm = Indata(i)
  Printbin Nm
  Tmpcrc = Result Xor Nm
  For J = 0 To 7
    Tmpcrc1 = Tmpcrc And &H1
    If Tmpcrc1 <> 0 Then
       Shift Tmpcrc , Right , 1
       Tmpcrc = Tmpcrc Xor cr_ccnet_crc_poly
       Else
     Shift Tmpcrc , Right , 1
    End If
   Next
  Result = Tmpcrc
Next
If Result = Bytecrc Then
Commandrecived = 1
Else
Xorsumerror = 1
Printbin Result
End If
Return





Исходная строка байт -

02 03 06 33 DA 81  - последняя- 81 контрольная сумма.

Вот еще для примера:

Цитировать
000001 12:49:46.577 COM4 << 02 03 06 33 DA 81 ...3РЄРѓ
000002 12:49:46.593 COM4 >> 02 03 06 19 82 0F ....‚.
000003 12:49:46.593 COM4 << 02 03 06 33 DA 81 ...3РЄРѓ
000004 12:49:46.624 COM4 >> 02 03 06 19 82 0F ....‚.
000005 12:49:49.061 COM4 << 02 03 06 30 41 B3 ...0AС–
000006 12:49:49.093 COM4 >> 02 03 06 00 C2 82 ....В‚
000007 12:49:49.093 COM4 << 02 03 06 33 DA 81 ...3РЄРѓ
000008 12:49:49.108 COM4 >> 02 03 06 13 D8 A0 ....РЁВ 
000009 12:49:49.108 COM4 << 02 03 06 00 C2 82 02 03 06 41 4F D1 ....В‚...AOС


Контроллер показывает CRC - 50

От отчаяния загрузил турбо паскаль, наваял код:

Цитировать
Program arr;



const
 CR_CCNET_CRC_POLY = $08408;

var i,TmpCRC: word;
    result: byte;
 DataLng: word;
   j: byte;


InData: array [0..5] of byte;

begin
InData[0]:= $2;
InData[1]:= $3;
InData[2]:= $6;
InData[3]:= $33;
InData[4]:= $da;
InData[5]:= $81;

DataLng := 6;


begin
result := 0;
for i := 0 to (DataLng-1) do
 begin
  TmpCRC := result xor InData;
  for j := 0 to 7 do
   begin
    if (TmpCRC and $0001)<>0 then
     begin
      TmpCRC := TmpCRC shr 1;
      TmpCRC := TmpCRC xor CR_CCNET_CRC_POLY;
     end
                                  else
     TmpCRC := TmpCRC shr 1;
   end;
  result := TmpCRC;
 end;
end;

writeln (result);
writeln (TmpCRc);
writeln (i);
writeln (j);


readln

end.


Тот вообще показывает результат - 4  :\'(

Бьюсь головой о клаву....
Автор: pumpkin
« : 01 Октября 2010, 05:21:10 »

Исправил ошибку
Gosub Setbaud должен быть внутри If Successbaudnum = 0 Then, чтоб новая скорость устанавливалась только в случае если предыдущие скорости потерпели неудачу.
Автор: pumpkin
« : 30 Сентября 2010, 21:35:52 »

А если вот так попробовать?
Цитировать
Dim Baudnum As Byte
Dim Successbaudnum As Byte

Print "Hello"
\'Тестируем
Gosub Speed
If Successbaudnum > 0 Then
  Print "Связь удалась на скорости номер " ; Successbaudnum
Else
  Print "Связь не удалась вообще"
End If
Print "Bye-bye"
End

Speed:
Successbaudnum = 0
For Baudnum = 7 To 1 Step -1
  If Successbaudnum = 0 Then       \'если до сих пор успехов не было
    Gosub Setbaud    \'устанавливаем очередную скорость
    \' здесь делаем всякие попытки связи с ведомым устройством
    \'если попытка удалась, то текущий Baudnum записываем в Successbaudnum
    If Baudnum = 3 Then Successbaudnum = Baudnum               \' например удалось связаться на 9600
  End If
Next
Return

Setbaud:
If Baudnum = 1 Then Baud = 2400
If Baudnum = 2 Then Baud = 4800
If Baudnum = 3 Then Baud = 9600
If Baudnum = 4 Then Baud = 19200
If Baudnum = 5 Then Baud = 38400
If Baudnum = 6 Then Baud = 57600
If Baudnum = 7 Then Baud = 115200
Return
Автор: Andy
« : 30 Сентября 2010, 15:41:58 »

Начало. Самое начало. Обычная процура определения скорости обмена с ком портом выявила "приятные" неожиданности. Хотя и побудила штудировать ассемблер, подтверждая мое убеждение что если хочешь реально писать программы и изучать контроллеры, лучше бейсика не найти. Упираясь в ограничения волей-неволей упрешся в асм.

Столкнулся с такой темой - нельзя скорость ком порта передать переменной. Константой можно, не вопрос. Поэтому пришлось функцию определения скорости написать так:

Цитировать

Const Baud2400 = 2400
Const Baud4800 = 4800
Const Baud9600 = 9600
Const Baud19200 = 19200
Const Baud38400 = 38400
Const Baud57600 = 57600
Const Baud115200 = 115200

Speed:
Baud = Baud4800
Gosub Chekbaud
Baud = Baud9600
Gosub Chekbaud
Baud = Baud19200
Gosub Chekbaud
Baud = Baud38400
Gosub Chekbaud
Baud = Baud57600
Gosub Chekbaud
Baud = Baud115200
Gosub Chekbaud
Baud = Baud2400
Gosub Chekbaud
Endspeed:
Return

Chekbaud:
do
\'здесь делаем всякие попытки связи с ведомым устройством
\'если попытка удалась,то переходим к НЕОБЫЧНОМУ ВЫХОДУ ИЗ ПОДПРОГРАММЫ МИНУЯ СТЕК
Exit Do
\'Если попытка связи не удалась,то выходим из подпрограммы по обычному
GoTo Endchekbaud

loop

pop r20
pop r20
Goto Endspeed
Endchekbaud:
Return


В данном примере нам пришлось выйти из подпрограммы грубо, не через адрес возврата, для этого нам пришлось выщелкнуть из стека адрес возврата, иначе бы программа рухнула, как подкошеный боров.

Но можно ли сделать все более красиво?