Форум по разработке и ремонту электронной техники Киевский форум радиолюбителей и электронщиков. Форумы по разработке и ремонту электронной техники
    Схемы электрические принципиальныеГлавная    ФорумФорум    ПоискПоиск по форуму    Личные сообщенияФайлообменник    Личные сообщенияРадиотехнический каталог   

Фотогалерея   <b>Профиль</b>Ваш профиль    Личные сообщенияЛичные сообщения    ГруппыГруппы   

FAQFAQ    РегистрацияРегистрация    ВходВход

Уважаемые посетители! Это старая версия форума. Новая версия находится по адресу: http://www.remexpert.com
"Хитрости кода" ...
На страницу 1, 2  След.
 
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Форум по разработке и ремонту электронной техники -> Микроконтроллеры, процессоры, ПЛИС...
 

Благодарности и т.д.
Ветка полезна ... буду почитывать
100%
 100%  [ 9 ]
Уберите это безобразие!
0%
 0%  [ 0 ]
Всего проголосовало : 9

Автор Сообщение
AndryG
Модератор


Зарегистрирован: 24.07.2006
Сообщения: 411
Откуда: Helios-3

СообщениеДобавлено: 17 Апр 2007, 10:03    Заголовок сообщения: "Хитрости кода" ... Ответить с цитатой

Доброго времени суток.

Каждый во время творения находил и узнавал нечто новое для себя ... возможно это был велосипед - не важно - для Вас это было новое и интересное ... и Вы думали: "Надо запомнить - удачный код получился"

Предлагаю в этой ветке собирать подобные "изюминки".

Повторюсь еще разок ... многим покажется, что это "свалка велосипедов" ... но ведь есть люди, которые такой модели двухколесного чуда еще не видели! Поделитесь?

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

_________________
AndryG


Последний раз редактировалось: AndryG (05 Июл 2007, 17:05), всего редактировалось 3 раз(а)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
AndryG
Модератор


Зарегистрирован: 24.07.2006
Сообщения: 411
Откуда: Helios-3

СообщениеДобавлено: 17 Апр 2007, 10:18    Заголовок сообщения: Ответить с цитатой

Код не мой, но хочу поделится!

Взято с поста г-на umup на electronix.ru

Датчик DS18B20 возвращает температуру с фиксированной запятой ... 4 знака после запятой.
Таким образом ... для получения температуры с точностью 0.1 градуса нам нужно возвращаемое значение умножить на 0.625
Код:

 value = (value>>1) + (value>>3);

Как всё просто! И никаких дробей и т.д.
Как работает ...
Сдвиг вправо на один бит -- это деление на два
Сдвиг вправо на три бита -- это деление на восемь
Перепишем...
Код:

 value = value*(1/2) + value* (1/8) = value*(4/8) + value * (1/8) = value * (5/8) = value* 0.625
 


Напоследок весь код функции: (Полное его объяснение не входит в мою задачу ... смотрите даташит на датчик)
Преобразования в формат с фиксированной запятой (1 знак после запятой):
Код:

 int16_t ds1w_12bit_to_celsius(uint16_t value)
{uint8_t uc1;
uc1 = (value>>8) & 0x80; //запомнить знак числа
if (uc1) value = 0-value; //если нужно, проинвертировать
value = (value>>1) + (value>>3); //скорректировать
if (uc1) value = 0-value; //восстановить знак
return(value);
}
 


Небольшая цитата с http://pro-radio.ru/controllers/3196/
Цитата:

"Влад Князев.Умножение без умножения"- толковая статья про умножение на константу, как раз у вас -это частный случай :
http://www.onembedding.com/hints/algorithms/mwom/


Замечательная статейка!

_________________
AndryG


Последний раз редактировалось: AndryG (03 Май 2007, 11:09), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
AndryG
Модератор


Зарегистрирован: 24.07.2006
Сообщения: 411
Откуда: Helios-3

СообщениеДобавлено: 03 Май 2007, 10:27    Заголовок сообщения: Ответить с цитатой

Частенько бывает такая заморочка:
Цитата:

объявляем переменную размером в слово (2 байта), а потом нужно получить доступ к каждому байту слова как к отдельным переменным.


Мне в свое время предложили такой вариант:
Код:

 /*Два макроса служат для доступа к младшему и старшему байту
  переменной размером не менее двух байтов*/
#define LOBYTE(x) (*(unsigned char*)&x)
#define HIBYTE(x) (*(((unsigned char*)&x)+1))

//ПРИМЕР!!!
 unsigned int big_var = 0x1234;
 #define  big_var_low LOBYTE(big_var)
 $define  big_var_hi   HIBYTE(big_var)

 putchar(big_var_low); // OUT 0x34
 putchar(big_var_hi);   // OUT 0x12

// Ну или просто ... просто ... без define
 putchar(LOBYTE(big_var));   // OUT 0x34
 putchar(HIBYTE(big_var));   // OUT 0x12



Если нужно "добираться" не только к нулевому и первому байту (например структура или еще там какой замудренный формат данных), то можно сотворить универсальным макрос:
Код:

   #define BYTENO(x,n) (*(((unsigned char*)&x)+n)) 
// n - номер байта, который Вас интересует.
 

_________________
AndryG
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
Zas
Знатный посетитель (>20)
Знатный посетитель (>20)


Зарегистрирован: 04.02.2007
Сообщения: 44

СообщениеДобавлено: 03 Май 2007, 12:38    Заголовок сообщения: Ответить с цитатой

Полагаю что про деление с помощью правого сдвига и умножения с помощью левого знают все.
Но многие даже не подозревают как получить остаток от деления на число степени двойки.
Так вот:
Код:
x mod 2^k = x and (2^k-1)

Пример:
Остаток от деления числа 58 на число 8 (2^3):
58 mod 8 = 58 mod 2^3 = 58 and (2^3-1) = 0b0111010 and 0b0111 = 0b0010 = 2

Источник
Как-то в книге по асму увидел что остаток деления на 4 можно получить с помощью функции x and 0b0111 и до меня дошло Улыбка
Все елементарно до безобразия:
При делении на 2^n мы сдвигаем число на n битов влево, собсно n битов выкидывается. Остается целая часть. А чему ещё быть дробной частью как не выкинутым битам? Улыбка Теперь простой логикой выводим функцию для нахождения этих n битов:
Эта функция должна оставить все биты идущие после 2^n-го. Если учитывать что 2^n это еденица и n нулей то надо n нулей поменять на еденицы, а все остальное на нули. Собственно это выполняет функция отнимания еденицы (1000 -1 = 0111). А дальше функция and отрезает лишние еденицы.
ТАк я это понимаю для себя Улыбка
А теперь мат доказательство:
Есть число представленое в двоичной системе:
b0*2^0 + b1*2^1 + b2*2^2 +... + bn*2^n

Поделим это число на 2^k. В результате получаем:
b0*2^(0-k) + b1*2^(1-k) + b2*2^(2-k) +... + bn*2^(n-k)

Целой частью деления являются все числа индекс которых >= k
Остаток числа с индексом < k
А дальше получаем остаток по методу описаному выше.

З.Ы. простите за бред Улыбка
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
derun
Знатный посетитель (>20)
Знатный посетитель (>20)


Зарегистрирован: 10.04.2007
Сообщения: 32

СообщениеДобавлено: 21 Май 2007, 13:19    Заголовок сообщения: Обмен байтами между регистрами не используя команду обмена Ответить с цитатой

Язык Ассемблер.
Обмен байтами между регистрами не используя команду обмена, например если ее нет.
Например для AVR это будет выглядить так
Обмен регистров R1,R2
Код:

EOR R1,R2  ;EOR-исключающее ИЛИ (XOR)
EOR R2,R1
EOR R1,R2


Быстрее чем использовать MOV, и не требует дополнительных регистров или стека.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DL36
Живет здесь... (>100)
Живет здесь... (>100)


Зарегистрирован: 04.10.2006
Сообщения: 192
Откуда: Херсон

СообщениеДобавлено: 21 Май 2007, 21:27    Заголовок сообщения: Ответить с цитатой

Добавлю от себя.

Очень часто надо сделать преобразование int-char.
Это я подсмотрел у AVRа которого чаще всего можно найти на сахаре и телесистемах.

Это свернутая версия atoi С стандарта ANSI но в отличие от оригинала работает быстрее.
Вызываш itoa2(5999) результат будет в asc[5]

Код:

unsigned char asc[5];

 void itoa2(unsigned int binval)
{
int step[]={10000,1000,100,10,1};
unsigned int temp,val;
unsigned char i,atemp;

val=binval;

 for (i=0; i<5; i++)
 {
  temp=step[i];
  atemp='0';
  while(val >= temp)
  {
   atemp++;
   val-=temp;
  }
  asc[i]=atemp;
 }
}
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DL36
Живет здесь... (>100)
Живет здесь... (>100)


Зарегистрирован: 04.10.2006
Сообщения: 192
Откуда: Херсон

СообщениеДобавлено: 10 Июл 2007, 9:58    Заголовок сообщения: Ответить с цитатой

Быстрая пп для подсчета единиц в байте.

Идею нашел в сети (автор Дмитрий Кирашов) но как всегда перепечатки и ошибки испортили все дело. Пп взятая в сети оказалась нерабочая. проанализировал код, поправил, что где надо.

Я ее использую при необходимости рассчитать бит паритета, но привожу в первозданном виде, при необходимости всегда можно поправить результат.

Нормально работает с PicLite от хайтека, для Picc18 нормально адаптировать, пока не удалось . См. далее в виде асм модуля.

Код:

unsigned char var;

void NumberBit(unsigned char j )
{
   var=j;   
   #asm
   rrf      _var, w   ;
   andlw   0x55      ;
   subwf   _var, w   ;
   movwf   _var
   andlw   0x33
   addwf   _var,f      ;
   rrf      _var,f
   addwf   _var,f
   rrf      _var,f
   swapf   _var,w
   addwf   _var,w
   andlw   0x0f;

   
   #endasm
}

результат вычисления остается в аккумуляторе.


Последний раз редактировалось: DL36 (30 Янв 2008, 21:25), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DL36
Живет здесь... (>100)
Живет здесь... (>100)


Зарегистрирован: 04.10.2006
Сообщения: 192
Откуда: Херсон

СообщениеДобавлено: 27 Янв 2008, 12:34    Заголовок сообщения: Ответить с цитатой

Решил продолжить.

Довольно частая задача, развернуть байт, для PICC-18 наиболее быстрый вариант будет так выглядеть.

Код:

;PSECT text0,class=CODE,local,delta=2
psect   text,class=CODE,delta=1,reloc=2
global  _reverseByte;
signat  _reverseByte,4201
_reverseByte:
    MOVWF    var;
    SWAPF     var, w ;           
    XORWF    var, w ;           
    ANDLW     0x66 ;                     
    XORWF    var, f ;           
    RRCF       var, w ;       
    RRCF       var, f ;       
    ANDLW     0x55 ;                     
    ADDWF     var, f ;           
    RRCF       var, f ;           
    ADDWF     var, f ;           
    RLNCF      var, w ;
    return                  ;

psect   temp,global,class=COMRAM,space=1,ovrld
var:        ds 1


Это надо оформить в виде отдельного файла reverseByte.as и подключить его в проект.
В проекте необходимо объявить внешнюю функцию extern unsigned char reverseByte( unsigned char var );

Во время компиляции компилятор выдает безболезненное предупреждение на последнюю строку, пока не знаю как побороть.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DL36
Живет здесь... (>100)
Живет здесь... (>100)


Зарегистрирован: 04.10.2006
Сообщения: 192
Откуда: Херсон

СообщениеДобавлено: 27 Янв 2008, 13:58    Заголовок сообщения: Ответить с цитатой

Еще до кучи.

Для PICC-18

Код:
;; Подпрограмма подсчитывающая количество битов установленных в 1 в байте

psect   text,class=CODE,delta=1,reloc=2
global  _counterBitInByte;
signat  _counterBitInByte,4201
_counterBitInByte:
   rrcf       var, w  ;
   andlw    0x55    ;
   subwf    var, w  ;
   movwf   var
   andlw    0x33
   addwf    var,f   ;
   rrcf        var,f
   addwf    var,f
   rrcf        var,f
   swapf    var,w
   addwf    var,w
   andlw    0x0f;
   return           ;

psect   temp,global,class=COMRAM,space=1,ovrld
var:        ds 1


Это надо оформить в виде отдельного файла counterBitInByte.as и подключить его в проект.
В проекте необходимо объявить внешнюю функцию extern unsigned char counterBitInByte( unsigned char var );


Последний раз редактировалось: DL36 (30 Янв 2008, 16:50), всего редактировалось 2 раз(а)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DL36
Живет здесь... (>100)
Живет здесь... (>100)


Зарегистрирован: 04.10.2006
Сообщения: 192
Откуда: Херсон

СообщениеДобавлено: 30 Янв 2008, 17:07    Заголовок сообщения: Ответить с цитатой

Привел этот текст на микрочипе и здесь пускай хранится.
Должны быть определены так же
#define MHZ *1000L /* number of kHz in a MHz */
#define KHZ *1
Код:

HI-TECH Software PICC-18
;******************************************************************************
;   Подпрограмма выполнения программной выдержки времени
;   Входные данные:
;   Переменная типа int
;   файл DelayUsInt.as
;   необходимо объявить extern DelayUsInt(unsigned int delay);
;   При необходимости, привязать к микросекундам
;   delay = (((unsigned long long)(x))*(unsigned long long)(XTAL_FREQ))
;            /(unsigned long long)(12MHZ);
;   Где х требуемая задержка в микросекундах
;   XTAL_FREQ частота кварца, например #define XTAL_FREQ 40000KHZ
;******************************************************************************
  #include <aspic18.h>
  global  _DelayUsInt
  global  ?_DelayUsInt

    opt pw 80
    psect   text,class=CODE,delta=1,reloc=2

    ;signat  _DelayUsInt,4200
    _DelayUsInt$delay   set ?_DelayUsInt               
    psect   text


_DelayUsInt:                     
            movlw     low ?_DelayUsInt  ;Грузим FSR
            movwf     FSR0L,c
            movlw     high ?_DelayUsInt
            movwf     FSR0H,c
            movf    POSTINC0,f,c        ;Инкрементируем для возможности последующего входа
_DelayUsInt_1:                          ;Вход после проверки старшего разряда           
            movf    POSTDEC0,f,c        ;Поскольку адрес был инкрементирован для старшего разряда
_DelayUsInt_2: 
            decfsz  INDF0,f,c           ;Декремент младшей цифры
            goto    _DelayUsInt_2       ;Крутимся тут до нуля
            movf    PREINC0,f,c         ;Смотрим на старшую цифру
            bnz     _DelayUsInt_3       ;Если ноль то выход
            return
_DelayUsInt_3:             
            decf      INDF0,f,c           ;Декремент старшей цифры         
            goto    _DelayUsInt_1
               


Последний раз редактировалось: DL36 (30 Янв 2008, 21:23), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Форум по разработке и ремонту электронной техники -> Микроконтроллеры, процессоры, ПЛИС... Часовой пояс: GMT + 2
На страницу 1, 2  След.
Страница 1 из 2

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете добавлять вложения в этом форуме
Вы можете просматривать вложения в этом форуме


Rambler's Top100 PageRank Яндекс цитирования
Сайты наших друзей: Гири, все о гирях, Автоматизация магазинов, супермаркетов, ресторанов, кинотеатров,
Весы электронные, Сканеры штрих-кода, Принтеры штрих-кода

Powered by phpBB © 2001, 2005 phpBB Group

Время генерации страницы: 0.7122s (PHP: 90% - SQL: 10%) - SQL запросов: 13 - GZIP enabled - Debug on