Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Сравнение больших чисел, 64 бита и больше
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Pyku_He_oTTyda
#include <mega8535.h>
// 1 Wire Bus functions
#asm
.equ __w1_port=0x18 ;PORTB
.equ __w1_bit=0
#endasm
#include <1wire.h>

#include <stdio.h> // Standard Input/Output functions

#define MAX_DEVICES 1 //определяем максимальное количество устройств на шине

unsigned char rom_codes[MAX_DEVICES][9]; //выделяет память (9 бит умноженное на кол-во устройств)

void main(void)
{
unsigned char i=0;
unsigned char j;
unsigned char devices;

// USART initialization
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x03;

// Analog Comparator: Off
ACSR=0x80;

w1_init(); // 1 Wire Bus initialization

// Watchdog Timer initialization
#pragma optsize-
WDTCR=0x1F;
WDTCR=0x0F;

#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

//ищем устройство командой 0xf0, в rom_codes ложится 9 байт (family-1,serial-6,CRC8-1,некоторые устройства возвращают 9 байт)
devices=w1_search(0xf0,rom_codes);

/* display the ROM codes for each detected device */
printf("%-u DEVICE(S) DETECTED\n\r",devices); // выводим количество подключенных устройств

for (j=0;j<9;j++) // задаем, какую часть кода выводить
{
printf("%-X",rom_codes[i][j]);
}
printf("\n\r");

}



На основе примера из CVAVR програмка, которая в сом-порт сбрасывает номер подключенного 1-wire устройства (DS1990). Эта часть кода работает.
Подскажите, как сравнить номер "таблетки" с неким заданным значением, которое можно будет определить в начале программы, или с несколькими значениями. Вот собственно вопрос мой...
Еще приветствуются указание моих косяков в программе и в комментариях
Pyku_He_oTTyda
Попробую, я еще только взялся за С, так что для меня не все еще прозрачно.
vet
#include <string.h>

if (memcmp(rom_codes[i], my_code, 9)==0) {
//совпадение с блоком в SRAM
}

if (memcmpf(rom_codes[i], my_flash_code, 9)==0) {
//совпадение с блоком во FLASH
}
GetSmart
Цитата
unsigned int test = array[0] * array[1] * array[2] * array[3] * array[4] * array[5] * array[6] * array[7];

Не делайте так низачто! Ерунда какая-то. Человек не понял, что сам написал. Уж лучше сравнивать побайтно.
Pyku_He_oTTyda
Цитата
#include <string.h>

if (memcmp(rom_codes[i], my_code, 9)==0) {
//совпадение с блоком в SRAM
}


Буду пробовать, мне знак не нужен, только равно или нет.
Pyku_He_oTTyda
А как мне определить такой большой my_code ? Например такой: 11E6CAC00701
unsigned char array[9]; - так будет корректно?
GetSmart
Цитата
А как мне определить такой большой my_code ?
unsigned char array[9]; - так будет корректно?

Да. Лишь бы было в RAM.
haker_fox
Цитата(GetSmart @ May 26 2006, 15:25) *
Цитата
unsigned int test = array[0] * array[1] * array[2] * array[3] * array[4] * array[5] * array[6] * array[7];

Не делайте так низачто! Ерунда какая-то. Человек не понял, что сам написал. Уж лучше сравнивать побайтно.


Елки-палки... Я прошу прощения... Я действительно написал большую ерунду, я удалил свое сообщение. Просто что-то жарко сегодня в моем городе и я сильно устал. Поэтому не подумал и написап эту дрянь. Сори!!! bb-offtopic.gif
BVU
Цитата(Pyku_He_oTTyda @ May 26 2006, 08:34) *
....
На основе примера из CVAVR програмка, которая в сом-порт сбрасывает номер подключенного 1-wire устройства (DS1990). Эта часть кода работает.
Подскажите, как сравнить номер "таблетки" с неким заданным значением, которое можно будет определить в начале программы, или с несколькими значениями. Вот собственно вопрос мой...
Еще приветствуются указание моих косяков в программе и в комментариях

При считывании номера переведите его в строку ASCII символов (s1) и делайте сравнение с шаблонной строкой (s2) оператором - strcmp(s1, s2), где char *s1, s2; Можно написать свою функцию для сравнения строк, если нехотите или не т возможности использовать библиотчную.
Pyku_He_oTTyda
Цитата
GetSmart


Простите за назойливость, а не могли бы черкнуть пример на моем частном случае,
определить вот это значение: 11E6CAC00701
а то я плывуsad.gif
_Bill
Цитата(Pyku_He_oTTyda @ May 26 2006, 10:04) *
Цитата
GetSmart


Простите за назойливость, а не могли бы черкнуть пример на моем частном случае,
определить вот это значение: 11E6CAC00701
а то я плывуsad.gif

Код
flash char pattern[] = {0x11, 0xe6, 0xca, 0xc0, 0x07, 0x01};   // Код "таблетки"
char         buffer[9];

char Match(char flash *pat, char *bp, char n)
         {
         while (n--)
               {
               if (*pat++ != *bp++)    // байты не совпали
                       return FAIL;          // - выход по ошибке
               }
          return OK;                        // Успешный выход
          }
...................
// -- Вызов
         if (Match(pattern, buffer, sizeof pattern) == OK) // Наш код!
                     Smile();                                  // :-)
         else                                              // Ерунда какая-то
                     Cry();                                    // :-(
Pyku_He_oTTyda
Вообще запуталсяsad.gif, сосвоим кодом было не разобратся, а тут еще новый
haker_fox
Цитата(Pyku_He_oTTyda @ May 26 2006, 16:49) *
Вообще запуталсяsad.gif, сосвоим кодом было не разобратся, а тут еще новый


Вы только не обижайтесь smile.gif но может Вам лучше сначала язык немного подучить? Опыть в программировании, как я понимаю, у Вас имеется. Максимум 1 - 1,5 недели хватит для начала. А так, вряд ли что дельно выйдет.
_Bill
Цитата(Pyku_He_oTTyda @ May 26 2006, 10:49) *
Вообще запуталсяsad.gif, сосвоим кодом было не разобратся, а тут еще новый

"То ли еще будет..., то ли еще будет... Ой ёй ёй..."
GetSmart
2 Pyku_He_oTTyda

По-моему _Bill написал хороший код. Без использования каких-либо библиотек. Он точно будет самым компактным. Советую. Если его чуть-чуть подправить. (уточнить)
____________________

Но если не нравится, то может этот:

unsigned char my_code[6] = {0x01,0x07,0xc0,0xca,0xe6,0x11};

for (j=0;j<9;j++)
{
if (memcmp(rom_codes[j][1], my_code, sizeof(my_code))==0) {
// выполнить что-то и выйти из цикла
break;
}
}

Я написал в обратном порядке байты (как в Интел-формате). Если подразумевалось не так, то переставьте их наоборот. Сам идентификатор как я понял содержит только 6 байт.
Pyku_He_oTTyda
Я и не обижаюсьsmile.gif, понимаю, что много непонятного... Вот я и учусь, мне удобнее учится на примерах, чем просто книгу читать.
Буду сейчас разбиратся на примере ваших кодов.
Всем спасибо! Отдельное спасибо _Bill и GetSmart.
Совершенно верно, индетификатор содержит шесть кодов, но это не принципиально, можно сравнивать хоть все девять.
_Bill
Цитата(Pyku_He_oTTyda @ May 26 2006, 11:57) *
Я и не обижаюсьsmile.gif, понимаю, что много непонятного... Вот я и учусь, мне удобнее учится на примерах, чем просто книгу читать.
Буду сейчас разбиратся на примере ваших кодов.
Всем спасибо! Отдельное спасибо _Bill и GetSmart.
Совершенно верно, индетификатор содержит шесть кодов, но это не принципиально, можно сравнивать хоть все девять.

smile.gif Может, не в тему, но все же... На будущее, т.с.
О пользе рекламы косметики
GetSmart
Цитата
Совершенно верно, индетификатор содержит шесть кодов, но это не принципиально, можно сравнивать хоть все девять.

Конечно. Если у Вас есть эти 9 кодов. Вы привели только 6 байт. Главное не запутаться относительно чего сравнивать эти 6 или 9 байт.
Pyku_He_oTTyda
11E6CAC00701 - это 9 кодов, строка printf("%-X",rom_codes[i][j]); выводит их в таком виде, то есть опускает незначащие нули, в нормальном виде выглядит так:
0x01, 0x1E, 0x06, 0xCA, 0x0C, 0x00, 0x00, 0x70, 0x01
otrog
Цитата(_Bill @ May 26 2006, 13:06) *
smile.gif Может, не в тему, но все же... На будущее, т.с.
О пользе рекламы косметики

a14.gif Сам постоянно пользуюсь "//" а "/*" и "*/" по возможности убираю из немоих исходников.
А в DEC, судя по всему, работают люди от искусства - все бы так строили свои процессоры (это я про систему команд PDP-11) wink.gif .

Цитата(Pyku_He_oTTyda @ May 26 2006, 13:56) *
11E6CAC00701 - это 9 кодов, строка printf("%-X",rom_codes[i][j]); выводит их в таком виде, то есть опускает незначащие нули, в нормальном виде выглядит так:
0x01, 0x1E, 0x06, 0xCA, 0x0C, 0x00, 0x00, 0x70, 0x01

Что еще за незначащие нули? По логике 11E6CAC00701 это
0x11, 0xE6, 0xCA, 0xC0, 0x07, 0x01.
Т.е. 6 байт(кодов). А незначащих нулей в данных нет smile.gif . Любой ноль что-нибудь да значит wink.gif .
Pyku_He_oTTyda
01 равен 1 и в двоичной, и в десятичной, и в шестнадцатиричной
otrog
А дошло! У Вас изначально было "0x01, 0x1E, 0x06, 0xCA, 0x0C, 0x00, 0x00, 0x70, 0x01",
А printf("%-X",rom_codes[i][j]); выдал "11E6CAC00701". Так? А я подумал, что наоборот - извиняйте blush.gif .
zltigo
Цитата(_Bill @ May 26 2006, 12:06) *
smile.gif Может, не в тему, но все же... На будущее, т.с.
О пользе рекламы косметики

B.W.Kernighan, R.Pike "The Practice of Programming"
С моими размышлениями по выработке стиля совпало очень много, по этому :-)
может и понравилась очень :-)
Русский перевод ~ в 2000 году тоже был.
prottoss
Цитата(_Bill @ May 26 2006, 15:34) *
Цитата(Pyku_He_oTTyda @ May 26 2006, 10:04) *

Цитата
GetSmart


Простите за назойливость, а не могли бы черкнуть пример на моем частном случае,
определить вот это значение: 11E6CAC00701
а то я плыву sad.gif

Код
flash char pattern[] = {0x11, 0xe6, 0xca, 0xc0, 0x07, 0x01};   // Код "таблетки"
char         buffer[9];

char Match(char flash *pat, char *bp, char n)
         {
         while (n--)
               {
               if (*pat++ != *bp++)    // байты не совпали
                       return FAIL;          // - выход по ошибке
               }
          return OK;                        // Успешный выход
          }
...................
// -- Вызов
         if (Match(pattern, buffer, sizeof pattern) == OK) // Наш код!
                     Smile();                                  // :-)
         else                                              // Ерунда какая-то
                     Cry();                                    // :-(




Привет всем. Код хорош но я бы выполнил его немного по другому) Можно делать не сравнение в цикле, а просто вычитание одного разрядного байта из другого, а результат хранить в общей сумме. В итоге если сумма не равна нулю, число не совпало, если равно нулю - число совпало с эталоном. Выйгрыш - меньше переходов при равенстве чисел и стабильность по времени исполнения кода, т.е. код всегда будет выполняться одинаковое число команд, что не мало-важно при работе с 1Ware. Конечно, мелочь, но нагляднее и приятнее))) :



Код


flash char pattern[] = {0x11, 0xe6, 0xca, 0xc0, 0x07, 0x01};   // Код "таблетки"
char         buffer[9];

/********************************************************************************
************

функция сравнения двух n-байтных чисел

********************************************************************************
************/



BOOL  Match(char flash *pat, char *bp, char n)
{      

       char sum = 0;


        while (n)
        {       sum += *pat++  - *bp++;

                n--;

        }



        return sum;

}



// ИМХО на мой вкус код более нагляден и эффективен)))
...................
// -- Вызов
         if (Match(pattern, buffer, sizeof pattern) == 0) // Наш код!
                     Smile();                                  // :-)
         else                                              // Ерунда какая-то
                     Cry();                                    // :-(
_Bill
Цитата(prottoss @ May 26 2006, 15:41) *
Привет всем. Код хорош но я бы выполнил его немного по другому) Можно делать не сравнение в цикле, а просто вычитание одного разрядного байта из другого, а результат хранить в общей сумме. В итоге если сумма не равна нулю, число не совпало, если равно нулю - число совпало с эталоном. Выйгрыш - меньше переходов при равенстве чисел и стабильность по времени исполнения кода, т.е. код всегда будет выполняться одинаковое число команд, что не мало-важно при работе с 1Ware. Конечно, мелочь, но нагляднее и приятнее))) :



Код


flash char pattern[] = {0x11, 0xe6, 0xca, 0xc0, 0x07, 0x01};   // Код "таблетки"
char         buffer[9];

/************************************************************************

функция сравнения двух n-байтных чисел

*************************************************************************/



BOOL  Match(char flash *pat, char *bp, char n)
{      

       char sum = 0;


        while (n)
        {       sum += *pat++  - *bp++;

                n--;

        }



        return sum;

}



// ИМХО на мой вкус код более нагляден и эффективен)))
...................
// -- Вызов
         if (Match(pattern, buffer, sizeof pattern) == 0) // Наш код!
                     Smile();                                  // :-)
         else                                              // Ерунда какая-то
                     Cry();                                    // :-(

Ну, тогда уж лучше так
Код
flash char pattern[] = {0x11, 0xe6, 0xca, 0xc0, 0x07, 0x01};   // Код "таблетки"
char         buffer[9];

/****************************************************************

функция сравнения двух n-байтных чисел

****************************************************************/

BOOL  Match(char flash *pat, char *bp, char n)
        {      
         char sum = 0;

         while (n)
                {
                sum |= *pat++ ^ *bp++;
                n--;
                }
         return sum;
        }

Вычитание не всегда даст корректный результат. Допустим, в одном случае разность будет +1, в другом - -1. В сумме будет ноль, хотя не совпадают два байта.
zltigo
Цитата(_Bill @ May 26 2006, 16:06) *
Вычитание не всегда даст корректный результат.

И так тоже не всегда! И это принципиальное ограничение. Заодно Вы всегда будете сравнивать ВСЮ память, хотя достаточно первого несравнения. Если хочется ускорять - переходите на сравнение (в зависимости от платформы) 32-16-и потом уже байтовых значений. В некоторых случах типа описанного, ускорение для несовпадающих значений даст сравнение с 'конца'.
defunct
Код
#define FALSE 0
#define TRUE 1

char Match(char __flash *pattern, char *str, char size)
{
  for(char i=0; i < size; i++){
     if (pattern[i] != str[i])
         return FALSE;
  }
  return TRUE;
}
zltigo
Цитата(defunct @ May 26 2006, 16:39) *
Код
     if (pattern[i] != str[size])
}

Что это было?

Да и зачем было заменять естественные для 'C' указатели?
GetSmart
2 prottoss
Можно и по-вашему. Иногда так бывает удобнее. Но со сложением разности Вы конечно сглючили. Как уже сказали лучше объединять через OR. В самом крайнем случае сумму объявить как INT, а разность байт специально обрезать до CHAR. Но всё-равно OR лучше.
defunct
Цитата(zltigo @ May 26 2006, 16:44) *
Цитата(defunct @ May 26 2006, 16:39) *

Код
     if (pattern[i] != str[size])
}

Что это было?


Опечатка?

Цитата
Да и зачем было заменять естественные для 'C' указатели?

только для наглядности.
prottoss
Цитата(GetSmart @ May 26 2006, 21:53) *
2 prottoss
Можно и по-вашему. Иногда так бывает удобнее. Но со сложением разности Вы конечно сглючили. Как уже сказали лучше объединять через OR. В самом крайнем случае сумму объявить как INT, а разность байт специально обрезать до CHAR. Но всё-равно OR лучше.




Согласен, сглючил. Конечно по OR !



Цитата(zltigo @ May 26 2006, 21:39) *
Цитата(_Bill @ May 26 2006, 16:06) *

Вычитание не всегда даст корректный результат.

И так тоже не всегда! И это принципиальное ограничение. Заодно Вы всегда будете сравнивать ВСЮ память, хотя достаточно первого несравнения. Если хочется ускорять - переходите на сравнение (в зависимости от платформы) 32-16-и потом уже байтовых значений. В некоторых случах типа описанного, ускорение для несовпадающих значений даст сравнение с 'конца'.






Я не говорил, что код быстрый, я говорил, что он стабильный по времени, т.е. всегда выполняется одинаковое количество тактов МК, что иногда не маловажно)
ps1x
bb-offtopic.gif

2 Pyku_He_oTTyda

Раз уж такая тема, Вы случаем не знаете как симулировать саму таблетку? (код на С, желательно CVAVR)
bb-offtopic.gif
Pyku_He_oTTyda
Цитата
unsigned char my_code[6] = {0x01,0x07,0xc0,0xca,0xe6,0x11};

for (j=0;j<9;j++)
{
if (memcmp(rom_codes[j][1], my_code, sizeof(my_code))==0) {
// выполнить что-то и выйти из цикла
break;
}
}



Сделал пока так, работаетsmile.gif
С другим приведенным кодом буду разбиратся, я еще новичек.
Эмулировать не пробовал, так как не было необходимости. Дома есть описание эмулятора на асм 51 семейства и на PICе. Могу конечно вам скинуть, но ссылки на это есть в этом форуме и вы наверное их видели.
В любом случае, алгоритм открытый, а программных наработок нет у меня.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.