Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Исходники программ и библиотек
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2, 3, 4
Шалапут:-)
Поделюсь своим кодом на Ассме для организации меню на буквенно цифровом дисплее HD4478 16х2.. В программе реализована отправка строк с флеш памяти. При нажатии одной из 4 кнопок происходит прерывание Int_1, затем его обработка (со звуковым сигналом). Куда подключать кнопки и дисплей, ясно из программы, динамик-через усилительный транзистор
Расчитано для работы на 4 МГц кварце. Для приминения на других частотах кварца нужно просто поменять значение, заносимое в рег r20
DELAY20MS:
wdr; sbros storozhevogo timera (mozhno zapreshat' ego raboty)
LDI R20,110; Сюда (20=1МГц, 40=2 и.т.д)
d20:
dec r20
...
если что неясно, пишите kadrum@narod.ru или ICQ#: 191-851-131
smile3046.gif

код для HD 4478 здесь
Yuriy_AVR
Может кому будет полезно очень быстрое преобразование двоичного ( 4-х байтного ) числа в двоично-десятичное число . Собственный алгоритм . Взято из рабочей программы ; некогда было окультуривать. Вполне можно перенести на Си . Очень удобно когда есть неоходимость , например , вывода на экран каких либо значений , которые считаются внутри в двоичном виде .
Fakir
на телесисах пробегала сылка на коллекцию исходников: http://faq.embedders.org/_examples_code/
и документации: http://lord-n.narod.ru/walla.html#faqembedders
Сергей Борщ
Часто появляются вопросы об удобном доступе к ножкам порта. Несколько раз выкладывал в разных темах очень удобные (как мне кажется) макросы. Решил выложить здесь наиболее свежую версию, чтобы потом долго не искать. Пользоваться ими так:
Код
#define LED1    PORTC,2,H   // output, active high (led from PC2 to GND)
#define LED2    PORTD,3,L   // output, active low (led from Vcc to PD3)
#define KEY1    PINB,5,L    // input, active low (key from PB5 to GND, pull-up resistor)
#define KEY2    PINC,7,H    // input, active high (key from Vcc to PC7, pull-down resistor)

#include "ascold.h"
unsigned char Key1Status;
unsigned char Key2Status;
void main() {
    Key1Status = signal(KEY1);
    Key2Status = signal(KEY2);
    for(;;) {
        cpl(LED1);          // toggle LED1
        if(signal(KEY1))    // if KEY1 pressed, turn on LED2
            on(LED2);
        else                // otherwice turn off LED2
            off(LED2);
    }
}}

Если в результате переразводки вывод поменялся, достаточно изменить лишь одну строчку #define

Я использую с компилятором IAR для процессоров AVR, MSP430, AT91SAM7, LPC2xxx, ADuC70xx. Но они должны работать и с любым другим компиляторм.
ReAl
Цитата(Сергей Борщ @ Jan 21 2007, 00:19) *
очень удобные (как мне кажется) макросы.

Я тоже ими пользуюсь очень давно :-)
Только signal() переименовал сразу же в bit_active() (ну и все остальные в bit_on/bit_off для однообразия).
После какого-то давнего залёта со своей переменной с именем errno в борландовском С - не рискую применять имена, могущие пересечься с чем-то "очень стандартным".
Sergei Frolov
Код
(*
   Вычисление дня недели в приложениях автоматического вычисления
   дня недели в датах от 1996 года и старше.

   Copyright (C) Sergei Frolov, 1998.   v1.0  Jan, 4, 1998.

   Программа ориентирована на применение в приложениях, написанных
   на языке ассемблера без использования аппаратного умножения/деления
   и операций с плавающей запятой.
*)

program denned;
const
  YEARS  : array[0.. 3] of byte = (0, 2, 3, 4);
  MONTHS : array[1..12] of byte = (0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5);
  DAYOFWEEKS  : array[0..6] of string =
    ('Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг',
     'Пятница', 'Суббота');
var
  a, b, c, d, e, f, tmp : byte;
  day, month, year      : word;

begin
  repeat
    write('Число XX -> ');    readln(day);
    if day = 0 then break; { выход }
    write('Месяц XX -> ');    readln(month);
    write('Год XXXX -> ');    readln(year);
    tmp := year - 1996;
    a := tmp and 3;
    b := (tmp shr 2) + (tmp and $FC);
    c := MONTHS[month];
    if (a = 0) and (month > 2) then inc(c);
    a := YEARS[a];
    e := (a + b + c + day) mod 7;
    writeln('Результат: ', DAYOFWEEKS[e]);    writeln;
  until false;
end.
umup
Сергей Борщ
Цитата
#define LED1 PORTC,2,H // output, active high (led from PC2 to GND)

Интересно, как у вас работают программы с комментариями // в #define, или компилятор это отлавливает ?
Сергей Борщ
Цитата(umup @ Feb 4 2007, 19:30) *
Сергей Борщ
Цитата

#define LED1 PORTC,2,H // output, active high (led from PC2 to GND)

Интересно, как у вас работают программы с комментариями // в #define, или компилятор это отлавливает ?
IAR не жалуется. GCC (WinAVR) тоже. Согласно http://gcc.gnu.org/onlinedocs/cpp/Initial-...tial-processing комментарии заменяются пробелами до обработки #define
Сергей Борщ
Цитата(svlad @ Feb 20 2007, 20:09) *
Цитата(Kuzmi4 @ Feb 20 2007, 14:21) *

2 svlad - interrupt.h и io.h надо поставить винавр тогда они появяться.
Если кому интересно могу выложить декодировку манчестера по INT0 для 8-й меги.

не уж то ни у кого нет WinAVR? smile.gif
В чем вопрос-то состоял? www.google.ru, искать по ключевому слову WinAVR. Хотя это первое, что нужно делать перед писанием в конференции.
Kuzmi4
Драсте всем!
В прикреплённом файле - ф-ция и интерупт с помощъю которых я ловил манчестер для эм-мариновских карт - у них манчестерская кодировка данных + хитрый протокол передачи,кому надо - может пообкусывать чё не надо.
megachip
Шрифт от Нокии 6510 анг/рус для библиотеки www.apetech.de/article.php?artId=1&nnId=10.
prottoss
Выложил исходники своего программатора AVR910 USB.
http://pinokio3000.narod.ru/my_designs/AVR..._Programmer.htm
Kuzmi4
2 Beer - ну бывает...
SasaVitebsk
Часто при работе с АЦП приходится делать таблицу пересчёта. Например когда датчик нелинейный или когда точность надо повысить. Кроме того иногда приходится применять те или иные механизмы. Например (как в моём случае) шаговый двигатель со стрелкой. Или простой ШД. В этом случае значение АЦП должно непосредственно указывать на положение стрелки (или механизма).

Короче так или иначе, но приходится СОЗДАВАТЬ ТАБЛИЦУ ПЕРЕСЧЁТА. smile.gif Иногда она неясна. То есть не поддаётся строгому математическому моделированию. Конечно, наверное здесь поможет знание такого пакета как MATHCAD, но иногда просто устаёшь от непрерывного изучения вспомогательных пакетов. Я не люблю бегло ознакамливаться, а изучать толково - банально не хватает времени.

Короче в моём случае, я как правило, сажусь и пишу небольшую вспомогательную программку. Имея исходники, при необходимости модифицирую её под конкретную задачу. Таким образом общее число таких программок перевалило уже сотни за 3. smile.gif
Со временем оказывается, что к некоторым програмкам обращаешься не один раз. (В частности к этой). Поэтому прилагаешь некоторые усилия для оптимизации её и так сказать завершённости.

Итак данная программа:
1) по нескольким точкам создаёт таблицу
2) Позволяет её сохранить в виде файла или текста
3) Позволяет её вывести в виде графика (для визуального контроля)
4) Позволяет слегка корректировать
5) Позволяет сгладить с помощью квадратичной интерполяции
Kuzmi4
оки... сча вот порылся , нашёл проэкт.. сча заттачу усе ф-ции - пользуйтесь,разбирайтесь.Хотя мож коряво написаны - но писал давно, работают и ладно...
файл который - "файл.Х" то там только объявы чтоб легче было...СОбсно:
/*****************************************************************************
Types definitions
******************************************************************************/
#define UCHAR unsigned char
#define UINT unsigned int
#define ULONG unsigned long
#define BOOL UCHAR
#define FALSE 0
#define TRUE 1
yarunt
Цитата(Waso @ Dec 19 2005, 17:29) *
Предлагаю сюда скидывать (кому не жалко) свои инклюды для работы с периферийными устройствами, предназначенные для работы в IAR. Дело в том, что например для WinAVR такую библиотеку можно найти в сети. CodeVision имеет свою библиотеку. А ИАР этим не богат. Приходится либо писать свое с нуля, либо переделывать то что есть. Гемора в этих двух занятиях поровну.
Самому мне правда пока нечего выкинуь. Наоборот, нужны исходники для стандартного текстового ЖКИ-дисплея, клавиатуры 4х4, АЦП, ШИМ и пользовательского интерфейса. Так как с ИАРом (и вообще с Си) только знакомлюсь - дело идет медленно.

Вот хочу выложить проэктик на алгоритмбилдере 4.8 . В нём инициалиация дисплея сименс сх65 тип LS020***.
При удачной сборке должны быть 3 цветных полосы ,принажатой кнопки должен сработать позификатор и нарисовать в центре квадрат(тест на длинну проводков к дисплею).
Qwertty
Цитата(yarunt @ Mar 20 2007, 10:22) *
Вот хочу выложить проэктик на алгоритмбилдере 4.8

В схеме включения диод повышающего конвертера для подсветки правильно нарисован? smile.gif
yarunt
Цитата(Qwertty @ Mar 20 2007, 12:26) *
В схеме включения диод повышающего конвертера для подсветки правильно нарисован? smile.gif

ohmy.gif Диод правильно ,ошибка в том что LED_GND подключить надо на землю. Питание подсветки около 9 в.
Qwertty
Цитата(yarunt @ Mar 20 2007, 12:19) *
ohmy.gif Диод правильно ,ошибка в том что LED_GND подключить надо на землю. Питание подсветки около 9 в.

Правильно????? Тогда по другому спрошу - зачем нужны VT1 и L1? Если диод правильно стоит.... smile.gif
yarunt
Цитата(Qwertty @ Mar 20 2007, 13:40) *
Правильно????? Тогда по другому спрошу - зачем нужны VT1 и L1? Если диод правильно стоит.... smile.gif

Да точно диод не правильно стоял smile.gif
alecsvg
Цитата(haker_fox @ Dec 20 2005, 02:03) *
Может быть сюда вообще выкладывать различные подпрограммы, для работы не только с периферией, но и например математику, сортировку, обработку данных и т.п.

Шрифты для граф.панели LCD ???help.gif help.gif
Есть панель WG12864
Интересуют русские шрифты 5х7. Где достать?
Чем сделать мультики для неё (редактор графический с промотром созданного?)
SasaVitebsk
Фонты 6х8, 8х8 в виндовой кодировке начиная с кода 0x21. Фонты пропорциональные. (Моноширинные)
acex2
Цитата(SasaVitebsk @ Mar 29 2007, 16:52) *
Фонты 6х8, 8х8 в виндовой кодировке начиная с кода 0x21. Фонты пропорциональные. (Моноширинные)


Шрифт может быть или пропорциональным, или моноширинным.
Kolia
Додрый день

Есть архивчик программ - весит 82 Мега.
ссылка пароль::gevv

автор архива gevv - http://hyperelektronik.com/

здесь можно посмотреть картинки проектов
DeXteR
Цитата(Kolia @ Mar 30 2007, 13:11) *
Додрый день
Есть архивчик программ - весит 82 Мега.
ссылка пароль::gevv
автор архива gevv - http://hyperelektronik.com/
здесь можно посмотреть картинки проектов


Ктонибудь закачал ???
Если есть возможность - пожалуйста переложите куданибудь в удобный хостинг
xemul
Цитата(DeXteR @ Mar 30 2007, 13:51) *
Ктонибудь закачал ???
Если есть возможность - пожалуйста переложите куданибудь в удобный хостинг

Через 20 минут будет в /upload/MCs/AVR/Projects/Gevv.rar
Перепаковано без пароля и странных символов в именах файлов и директорий.

.Done smile.gif
plan
Привет ВСЕМ. Выкладываю рабочий проект для связи по радиоканалу (сс2500) для CVAVR.Может где-то чего нибудь криво так что сами подправите.Использовал библиотеки msp430.
prottoss
Цитата(VAHOO @ Apr 10 2007, 20:28) *
Привет prottoss! хочу с компилировать файл, но не компилируется
пишет #error This file should only be compiled with iccavr or aavr with processor option -v1
в чем проблема, у меня IAR v 4.21, помоги пожалуйста!
В файле stdafx.h подключен хедер io8515.h. Его лучше всего заменить на ioavr.h вот так

Код
#include <ioavr.h>


Ну и в меню Project->Options->General Options->Target выставить требуемый МК.

Enjoy!:-)
Александр Куличок
Цитата
Не совсем исходники, но все же:
Макросы для тех, кто работает с ассемблером + раскраска комментариев и макросов в ассемблере (AVRStudio) (копировать в .\AVR Tools\AVRStudio\Edit\)
(раскраска директив компилятьра, комментариев разными цветами после ;* ;/ ;- ;+ плюс раскраска макросов)

Не удалось присоединить файлы. Повторяю.
Нажмите для просмотра прикрепленного файла
Нажмите для просмотра прикрепленного файла
prottoss
Цитата(VAHOO @ Apr 11 2007, 13:48) *
а "systime.h" откудо найти ???
если нетрудно отправ примерчик скажем бегушая строка,
и если написал дока для етих библиотек, тоже отправ,
я LCD подключил на PORTC , 4 бит, спасибо!
systime.h осталься по невнимательности и в данной реализации абсолютно не нужен. Примера бегущей строки нету:-) а делать влом - некада- сорри:-) В принципе не вижу трудностей и предлагаю написать самому - мне такие задачи задавали на 4-ом курсе:-))) Делал за одну пару.
by-pass
Класс для работы с CAN контроллера AT90CAN128.
C++.
backa
Цитата(Nanobyte @ Mar 31 2007, 23:12) *
Э-э-э-хх, вот если бы залить по отдельным проектам, а то интересует 3-4 темы, а качать 82 МБ тяжко... sad.gif

__tp://www.reverseelectronics.com/AVRproject/
тут в "розницу" smile.gif по-штучно
Выбирай что нравиться и качай smile.gif

а тут фотки
__tp://www.sonsivri.com/forum/index.php?topic=2303.0
umup
вот немного :
http://umup.narod.ru/ul_c_lib.zip
Serg_greS
Вот нашел несколько вещей на досуге, думаю будет интересно:
на h__p://www.harbaum.org/till/index.html:
Подключение HD44780 через USB h__p://www.harbaum.org/till/lcd2usb/index.html
USB->i2c h__p://www.harbaum.org/till/i2c_tiny_usb/index.html
SPI2CF, a fast and efficient WLAN interface for the AVR h__p://www.harbaum.org/till/spi2cf/index.html

на h__p://www.ulrichradig.de/site/atmel/avr_webserver/
не немецком, но понять несложно AVR webServer - Gerдte ьber HTTP schalten
Serg_greS
h_tp://barello.net/avrx/index.htm
AvrX is a Real Time Multitasking Kernel written for the Atmel AVR series of micro controllers
IgorKossak
Как то пытался использовать AVRx RTOS.
Проект сырой (есть глюки) и трудно развиваемый. Не говоря уже о переносимости.
Последние обновления были два года назад.
На мой взгляд автор утратил интерес к проекту. Тем более, что существуют много более удачных альтернатив на С/С++.
Скоростные преимущества обсуждаемого проекта на мой взгляд мизерны.
Serg_greS
Еще немного библиотек
h__p://www.ember.com/pdf/EM260/HAL
Код
adc.h     Sample A/D converter driver, for multiple users
button.h     Sample API functions for using push-buttons
buzzer.h     Sample API functions for playing tunes on a piezo buzzer
crc.h     Functions that provide access to cyclic redundancy check calculation
dev0470.h     Functions specific to the dev0470 breakout board
ember-types.h     Ember data type definitions
error-def.h     Return code definitions for EmberZNet stack API functions
error.h     Return codes for Ember API functions and module definitions
hal.h     Generic set of HAL includes for all platforms
iar.h     Compiler/platform-specific definitions and typedefs for the IAR AVR C compiler
led.h     Sample API funtions for controlling LEDs
micro.h     Functions common across all microcontroller-specific files
random.h     Functions that provide access to random numbers
reserved-ram.h     Memory allocations that allow for data sharing between the normally running application and bootloader
hal/micro/serial.h     Serial hardware abstraction layer interfaces
app/util/serial/serial.h     High-level serial communication functions
spi-protocol.h    Example AVR SPI Protocol implementation for interfacing with EM260
spi.h     Generic SPI manipulation routines
system-timer.h     Functions that provide access to the system clock
avr-atmega/32/system-timer.h     Functions that provide access to the system clock for ATmega32 microcontroller
uart.h     Prototypes and defines for the hardware-specific UARTs

h__p://www.ember.com/pdf/EM250/HAL/
Serg_greS
Цитата
но как добраться к тем хэдерам

в смысле к самим реализациям? а не только прототипам?
наверное все остальное в их ИДЕ h__p://www.ember.com/products_zigbee_development_tools_debuggers.html
Стек EmberZNet предоставляется пользователям продукции Ember по запросу h__p://www.efo.ru/cgi-bin/go?2508#n21
и бесплатно (at90: Стэк Ембер как всегда даёт бесплатно.) http://electronix.ru/forum/index.php?s=&am...ost&p=95173
dimka76
пример проекта умножения с плавающей точкой.
работает быстрее, чем стандартная Си операция благодаря использованию аппаратного умножителя.
Подходит только для серии Mega
haker_fox
Цитата(dimka76 @ Aug 16 2007, 20:55) *
пример проекта умножения с плавающей точкой.
работает быстрее, чем стандартная Си операция благодаря использованию аппаратного умножителя.
Подходит только для серии Mega

bb-offtopic.gif Прошу прощения, а разве современные компиляторы не умеют использовать аппаратный умножитель? Или я Вас неверно понял?
at90
Вот куча исходников для AVR от немцев.
https://141.57.27.10/svn/avr-common-source/

http://www.ifas.htwk-leipzig.de/easytoweb/...ontent=download
yarunt
rc-5 на Алгоритм билдере.Может кому пригодится.
Waso
Выкладываю портированный мною под ИАР TCP-IP стек LwIP из демо FreeRTOS для отладочной платы AT91SAM7X-EK. Он все еще выдает некоторое количество варнингов, но они связаны с выключенным дебагом. Работает web-сервер, отвечает на пинги. Перед прошивкой нужно задать айпишники в хедере sam7_emac.h. Версия lwIP - 1.1.0. Когда попытался прикрутить более новую - удивился как много оставлено для дописывания ручками в исходниках.

Благодарю за помощь в освоении С и IAR местных гуру и особенно Сергей Борщ.
INT1
Здесь есть библиотеки для MODBUS
http://freemodbus.berlios.de/index.php
Поскольку free, то естественно WinAVR, но и не только для AVR. Прошу прощения если повторяюсь, 9стр. перелистывать неохота.
INT1
Цитата(umup @ Nov 6 2007, 15:21) *
что-то получается слишком большой размер кода. у меня RTU поместился в 500 байт Flash и 30 ОЗУ

Дело еще в том, на сколько код "откатан" в железе. Немного поизучали эту тему, но в последствии выяснилось, что в реализации всего протокола нет необходимости, а возможные коллизии обошли таймаутами. В сети попадлись вопросы в этой связИ, вот еще ветка:
http://www.fulcrum.ru/cgi-bin/bbs/mess_sel...;Sp=0&LID=0
Если Вы приаттачите свой исходик, то буду признателен.
umup
вот кусок :
www.ukpyr.narod.ru/mb_clp.c
правда там только функция 3, но при желании несложно добавить и другие.
Сергей Борщ
Цитата(Waso @ Oct 31 2007, 06:06) *
Выкладываю портированный мною под ИАР TCP-IP стек LwIP
А как все начиналось... smile.gif
Цитата(Waso @ Dec 19 2005, 18:29) *
Предлагаю сюда скидывать
...
Самому мне правда пока нечего выкинуь. Наоборот, нужны исходники для стандартного текстового ЖКИ-дисплея, клавиатуры 4х4, АЦП, ШИМ и пользовательского интерфейса.


Пополню копилку. Даже не исходником, а полезным приемом. Навеяно несколькими вопросами в последнее время, когда "все не работает" потому что программа ушла в необъявленный обработчик прерывания. Можно поставить на все неиспользуемые обработчики заглушки, но, во-первых, это не решение, а расчалка и распорка. А во-вторых не всякий флаг прерывания сбрасывается от самого факта входа в обработчик. Т.е. попали в заглушку, вышли из нее, тут же снова попали... Заглушка позволяет локализовать проблему. Но если заглушек несколько, возникает вопрос - в какую из них попадает программа? Хорошо, если есть много свободных ног - можно в каждой заглушке махать своей ногой. Но опять же есть неудобство - искать точки на плате, куда подключиться осциллографом, и перебирать их щупом. Идея в том, чтобы использовать одну ногу, а конкретное место программы, где нога шевелится, определять по скважности генерируемого сигнала:
Код
ISR(ADC_vect)
{
    for(;;)
    {
        on(TEST);
        _nop();
        _nop();
        _nop();
        off(TEST)
    }
}
ISR(UDRE_vect)
{
    for(;;)
    {
        _nop();
        on(TEST);
        _nop();
        _nop();
        off(TEST)
    }
}
......
ISR(UDRE_vect)
{
    for(;;)
    {
        _nop();
        _nop();
        on(TEST);
        _nop();
        off(TEST)
    }
}
.......
ISR(TIMER2_COMP_vect)
{
    for(;;)
    {
        _nop();
        _nop();
        _nop();
        on(TEST);
        off(TEST)
    }
}
Отсчитать скважность можно буквально по клеткам на экране.


P.S. Тема получилась очень полезная и давно переросла подфорум AVR. Не пора ли ее переместить куда-то в более общее место?
ASZ
Мои 0,5 копейки:

Реализация форматированного преобразования int в ASCII-строку.
Использован алгоритм, предложенный =AVR='ом:

Код
void ltoa_fmt(long val, s_char length, u_char *buff)
{
long ltemp;
int itemp;
s_char binc,atemp;
u_char *ptr1, *ptr2;

  ptr1 = buff;

  if (val<0)
   {
     val = -val;
     *buff++ = '-';
   }

  atemp='0';
  ltemp=1000000;
    while(val >= ltemp)
    {
      atemp++;
      val-=ltemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  ltemp=100000;
    while(val >= ltemp)
    {
      atemp++;
      val-=ltemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  itemp=10000;
    while(val >= itemp)
    {
      atemp++;
      val-=itemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  itemp=1000;
    while(val >= itemp)
    {
      atemp++;
      val-=itemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  itemp=100;
    while(val >= itemp)
    {
      atemp++;
      val-=itemp;
    };
  if(atemp != '0')
    *buff++=atemp;
  atemp='0';
  binc=(char)val;
    while(binc >= 10)
    {
      atemp++;
      binc-=10;
    };
  if(atemp != '0')
    *buff++=atemp;
  binc += '0';
  *buff=binc;

  atemp = buff - ptr1 + 1;
  ptr2 = ptr1 + length-1;
  while(atemp--)
    *ptr2-- = *buff--;
  atemp = ptr2 - ptr1 + 1;
  while(atemp--)          
    *ptr2-- = ' ';
}
umup
bin2bcd AVR :
Код
u32 bin2bcd_u32(u32 data, u8 result_bytes) NAKED;
u32 bin2bcd_u32(u32 data, u8 result_bytes)
{asm volatile(
  "push __tmp_reg__ \n push r26 \n push r27 \n push r30 \n push r31 \n"
  "mov __tmp_reg__, %A1   \n" /*number of bytes in result*/
   "bin2bcd_u32_00:       \n" /*correct input number by left shifts*/
     "mov r31, %A0        \n"
     "mov %A0, %B0        \n"
     "mov %B0, %C0        \n"
     "mov %C0, %D0        \n"
     "mov %D0, r31        \n"
     "dec __tmp_reg__     \n"
     "brne bin2bcd_u32_00 \n"
  
   "eor r26, r26          \n" /*clear result*/
   "eor r27, r27          \n"
   "eor r30, r30          \n"
   "eor r31, r31          \n"
   "mov __tmp_reg__, %A1  \n"
   "lsl __tmp_reg__ \n lsl __tmp_reg__ \n lsl __tmp_reg__ \n" /*__tmp_reg__=size in bits*8*/
  
   "bin2bcd_u32_01:       \n" /*shift loop*/
    "subi r26,-0x33       \n" /*add 0x33*/
    "sbrs r26, 3          \n" /*if carry to bit 3,*/
    "subi r26, 3          \n" /*subtract 3*/
    "sbrs r26, 7          \n" /*if carry to bit 7,*/
    "subi r26, 0x30       \n" /*subtract 0x30*/
    "subi r27,-0x33       \n" /*add 0x33*/
    "sbrs r27, 3          \n" /*if carry to bit 3,*/
    "subi r27, 3          \n" /*subtract 3*/
    "sbrs r27, 7          \n" /*if carry to bit 7,*/
    "subi r27, 0x30       \n" /*subtract 0x30*/
    "subi r30,-0x33       \n" /*add 0x33*/
    "sbrs r30, 3          \n" /*if carry to bit 3,*/
    "subi r30, 3          \n" /*subtract 3*/
    "sbrs r30, 7          \n" /*if carry to bit 7,*/
    "subi r30, 0x30       \n" /*subtract 0x30*/
    "subi r31,-0x33       \n" /*add 0x33*/
    "sbrs r31, 3          \n" /*if carry to bit 3,*/
    "subi r31, 3          \n" /*subtract 3*/
    "sbrs r31, 7          \n" /*if carry to bit 7,*/
    "subi r31, 0x30       \n" /*subtract 0x30*/
    "lsl r26 \n rol r27 \n rol r30 \n rol r31 \n" /*shift out buffer*/
  
    "sbrc %D0, 7          \n" /*skip if msbit of input =0*/
    "ori  r26, 1          \n" /*set lsb of output*/
    "lsl %A0 \n rol %B0 \n rol %C0 \n rol %D0 \n"/*shift input*/
  
    "dec __tmp_reg__      \n"
    "brne bin2bcd_u32_01  \n" /*repeat for all bits*/
  
    "movw r22, r26        \n" /*move result*/
    "movw r24, r30        \n"
    "pop r31 \n pop r30 \n pop r27 \n pop r26 \n pop __tmp_reg__\n"
    "ret \n"
  : :"r"(data),"r"(result_bytes):"r0","r26","r27","r30","r31" /*input and output parameters*/
  );


bin2bcd C :
Код
u32 bin2bcd_u32(u32 data, u8 result_bytes)
{u32 result = 0; /*result*/
  u8 u8_1;
  for (u8_1 = (4 - result_bytes); u8_1; u8_1--) data <<= 8; /*adjust input bytes*/
  for (u8_1 = (result_bytes << 3); u8_1; u8_1--) /*bit shift loop*/
  {u8 u8_2, u8_3;
   /*result BCD nibbles correction*/
   result += 0x33333333;
   /*result correction loop*/
   for (u8_3 = 4; u8_3; u8_3--)
   {u8_2 = result >> 24;
    if (!(u8_2 & 0x08)) u8_2 -= 0x03;
    if (!(u8_2 & 0x80)) u8_2 -= 0x30;
    result <<= 8; /*shift result*/
    result |= u8_2; /*set 8 bits of result*/
   }
   /*shift next bit of input to result*/
   result <<= 1;
   if (((u8)(data >> 24)) & 0x80) result |= 1;
   data <<= 1;
  }
  return(result);
}


bcd2bin AVR (GCC) :
Код
u32 bcd2bin_u32(u32 data, u8 result_bytes) NAKED;
u32 bcd2bin_u32(u32 data, u8 result_bytes)
{asm("push __tmp_reg__ \n push r26 \n push r27 \n push r30 \n push r31 \n"
  "eor r26, r26           \n" /*clear result*/
  "eor r27, r27           \n"
  "eor r30, r30           \n"
  "eor r31, r31           \n"
  "mov __tmp_reg__, %A1   \n"
  "lsl __tmp_reg__ \n lsl __tmp_reg__ \n lsl __tmp_reg__ \n" /*__tmp_reg__=input parameter size in bits*/

   "bcd2bin_u32_00:       \n" /*bits shift loop*/
  
    "lsr r31 \n ror r30 \n ror r27 \n ror r26 \n" /*shift out buffer*/
  
    "sbrc %A0, 0          \n" /*move lowest bit*/
    "ori  r31, 0x80       \n"
  
    "lsr %D0 \n ror %C0 \n ror %B0 \n ror %A0 \n"
  
    "sbrc %D0, 7          \n" /*if carry to bit 7,*/
    "subi %D0, 0x30       \n" /*subtract 0x30*/
    "sbrc %D0, 3          \n" /*if carry to bit 3,*/
    "subi %D0, 3          \n" /*subtract 3*/
    "sbrc %C0, 7          \n" /*if carry to bit 7,*/
    "subi %C0, 0x30       \n" /*subtract 0x30*/
    "sbrc %C0, 3          \n" /*if carry to bit 3,*/
    "subi %C0, 3          \n" /*subtract 0x30*/
    "sbrc %B0, 7          \n" /*if carry to bit 7,*/
    "subi %B0, 0x30       \n" /*subtract 0x30*/
    "sbrc %B0, 3          \n" /*if carry to bit 3,*/
    "subi %B0, 3          \n" /*subtract 3*/
    "sbrc %A0, 7          \n" /*if carry to bit 7,*/
    "subi %A0, 0x30       \n" /*subtract 0x30*/
    "sbrc %A0, 3          \n" /*if carry to bit 3,*/
    "subi %A0, 3          \n" /*subtract 3*/
  
    "dec __tmp_reg__      \n" /*repeat for all bits*/
    "brne bcd2bin_u32_00  \n"
  
   "movw r22, r26         \n" /*adjust result bytes*/
   "movw r24, r30         \n"
    "bcd2bin_u32_01:      \n"
     "mov __tmp_reg__,r25 \n"
     "mov r25,r24         \n"
     "mov r24,r23         \n"
     "mov r23,r22         \n"
     "mov r22,__tmp_reg__ \n"
     "dec %A1             \n"
     "brne bcd2bin_u32_01 \n"
  
   "pop r31 \n pop r30 \n pop r27 \n pop r26 \n pop __tmp_reg__ \n"
   "ret \n"
   : :"r"(data),"r"(result_bytes):"r0","r26","r27","r30","r31" /*input and output parameters*/
  );
}


bcd2bin C :
Код
u32 bcd2bin_u32(u32 data, u8 input_bytes)
{u32 result = 0; /*result*/
  u8 cnt_bits, cnt_bytes, tmp_byte;
  for (cnt_bits = (input_bytes << 3); cnt_bits; cnt_bits--)
  {/*shift next bit*/
   result >>= 1;
   if (((u8)(data)) & 0x01) result |= 0x80000000;
   data >>= 1;
   {/*BCD correction of result*/
    for (cnt_bytes = 4; cnt_bytes; cnt_bytes--)
    {tmp_byte = (data >> 24);
     if (tmp_byte & 0x80) tmp_byte -= 0x30;
     if (tmp_byte & 0x08) tmp_byte -= 0x03;
     data <<= 8;
     data |= tmp_byte;
    }
   }
  }
  /*adjust result bytes*/
  for (cnt_bits = (4 - input_bytes); cnt_bits; cnt_bits--) result >>= 8;
  return(result);
}



num2asc C - форматированный вывод числа с фикс.запятой в ASCI-буфер (options&7 = общее количество знаков, (options>>4)&7 = положение запятой считая справа, options&8 = 8 - отображать начальные нули, options&80 = 80 - сначала преобразовать в BCD) :
Код
void num2asc_s32(s32 data, u8 *buf, u8 options)
{u8 cnt_chars, point_pos;
cnt_chars = (options & 7); /*number of digits*/
/*convert negative to positive, set '-' flag*/
if (data < 0) {data = -data; options |= 1;} else options &= ~1;
/*if necessary, convert to BCD*/
if (options & 0x80) data = bin2bcd_u32(data, (cnt_chars >> 1) + 1);
cnt_chars++;
/*calculate point position*/
point_pos = cnt_chars - ((options >> 4) & 7);
if (point_pos) point_pos++;
while (cnt_chars) /*digits conversion loop*/
{if ((options & 8) && (data == 0) && (cnt_chars < point_pos))
  {if (options & 1) *buf = asc_minus; else *buf = asc_space;
   options &= ~1;
  } else
   {if ((cnt_chars == point_pos) && (options & 0x70)) /*store point*/
    {*buf = asc_point;
     cnt_chars--;
     buf--;
    }
    *buf = bin2asc_u8(data); /*store ASCII digit*/
   }
  cnt_chars--;
  buf--;
  data >>= 4;
}
if (options & 1) *buf = asc_minus;
}
alekseyb
Подсчет CRC для DALLAS 1Wire устройств.Работает очень быстро.

unsigned char crc_ib(unsigned char __crc,unsigned char data)
{
unsigned char temp;
temp=__crc^data;
__crc=0;
if (temp&(1<<7)){__crc^=0x8C;}
if (temp&(1<<6)){__crc^=0x46;}
if (temp&(1<<5)){__crc^=0x23;}
if (temp&(1<<4)){__crc^=0x9D;}
if (temp&(1<<3)){__crc^=0xC2;}
if (temp&(1<<2)){__crc^=0x61;}
if (temp&(1<<1)){__crc^=0xBC;}
if (temp&(1<<0)){__crc^=0x5E;}
return __crc;
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.