Нескольно простых вопросов о программировании AVR на Си.

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4386512#p4386512"]кроме деления часто используют вычитание.[/uquote]
Т.е. каждый раз сравнивают (проверяют), что разность больше чем вычитаемое, тогда продолжают вычитать. Накапливают переменную. и так далее с каждым разрядом?
Станислав
Реклама
Аватара пользователя
Eats
Потрогал лапой паяльник
Сообщения: 309
Зарегистрирован: Сб фев 18, 2023 21:51:01
Откуда: Санкт-Петербург

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Eats »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=4386503#p4386503"]Понимаю, что надо использовать деление на 10 и остаток от деления на 10. Много чего уже посмотрел, но все равно плохо доходит.[/uquote]Так ведь Eddy_Em в Сообщении от Вт ноя 22, 2022 11:07:19 на предыдущей странице уже всё расписал!
Суть в том, что я не знаю, сколько разрядов у числа изначально. Может быть три, а может пять.
А какая разница, сколько их? Изначально буфер на 5 символов надо заполнить пробелами или каким другим пустым кодом, если кодировка не ASCII. Цифры же формируются с конца (обратите внимание на --bufptr у Eddy_Em), и этот цикл заканчивается не по счётчику, а по нулевому остатку от исходного числа. При этом сколько символов сформировалось, столько и ладно. Программа даже не заморачивается подсчётом этих символов!
Опишите суть, или ткните, где это максимально понятно расписано.
AVR Application Note 204: BCD Arithmetics. Начинается этот аппноут как раз с программы, а точнее с алгоритма Binary 16 to BCD Conversion. А хорошее разъяснение всей этой математики есть в 3-м томе 4-томника "Микроконтроллеры" от Алекса Фрунзе. Не столь популярное, но тоже небесполезное описание всё той же самой математики есть и в жёлтой книжке "Программы для микропроцессоров" Гуртовцева и Гудыменко. И всё это есть в сети.
Всего доброго.
Евгений.
Реклама
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение akl »

[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=4386503#p4386503"]...Теперь я хочу разбивать число неопределенного количества разрядов на цифры... Суть в том, что я не знаю, сколько разрядов у числа изначально...[/uquote]
Не обязательно делить или вычитать. Можно провести десятичную коррекцию, начиная с младших разрядов.
https://radiokot.ru/forum/viewtopic.php ... 9#p1417529
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

В древности писал статью на тему вывода чисел: http://arv.radioliga.com/content/view/106/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Starichok51 »

СКАЗОЧНИК писал(а):Т.е. каждый раз сравнивают (проверяют), что разность больше чем вычитаемое, тогда продолжают вычитать. Накапливают переменную. и так далее с каждым разрядом?
да, каждый раз нужно сначала делать проверку на возможность вычесть, потом вычитают.
а иногда делают наоборот - сначала вычитают, потом проверяют остаток на знак. если положительный, продолжают вычитать. если отрицательный, прибавляют и переходят к следующему разряду.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Реклама
veso74
Поставщик валерьянки для Кота
Сообщения: 1906
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение veso74 »

Starichok51, спасибо, интересно. Код небольшой (против /10 и %10).

Код: Выделить всё

int16_t data = 9876;
---
  while ((data - 1000) > 0) {
    data -= 1000;
    a++;
  }

  while ((data - 100) > 0) {
    data -= 100;
    b++;
  }

  while ((data - 10) > 0) {
    data -= 10;
    c++;
  }

  d = data;
---
результат:
9876
9 8 7 6
---
Да, но медленнее :P.
Код выше по сравнению с кодом ниже: 20 µs / 4 µs (ATmega328, 16 MHz).

Код: Выделить всё

  a = data / 1000;
  b = (data / 100) % 10;
  c = (data / 10) % 10;
  d = data % 10;
Реклама
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Starichok51 »

veso74, что-то мне не верится, что деление и потом взятие %10 работает быстрее вычитания.
я не умею писать для МК на Си, чтобы самому это проверить.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
veso74
Поставщик валерьянки для Кота
Сообщения: 1906
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение veso74 »

Все по умолчанию, оптимизация на макс. Ардуино IDE, со своим языком и функциями (печать в Serial из отчетности время пропущен).
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение WiseLord »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4386703#p4386703"]veso74, что-то мне не верится, что деление и потом взятие %10 работает быстрее вычитания.
я не умею писать для МК на Си, чтобы самому это проверить.[/uquote]
Поверьте, быстрее.
Компиляторы сейчас умные, и при включенной (по умолчанию) оптимизации сами реализуют деление на 10 как умножение со сдвигом, что и кода меньше занимает, и по времени гораздо быстрее, чем отнимать и считать циклы.

К примеру, вместо целочисленного деления uint8_t числа на 10 компилятор сам может сообразить, что это то же самое, что умножить это число на 205 и результат сдвинуть на 11 разрядов вправо.

Почему 205? Потому что X / 10 = X * 204.8 / 2048 ~= X * 205 / 2048 = (X * 205) << 11. Что для любых чисел само по себе приблизительно, но для однобайтовых X погрешность нулевая.
OKF
Это не хвост, это антенна
Сообщения: 1392
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение OKF »

+1000500. Считаю, и не только я, что в наше время, в первую очередь, нужно обращать внимание на наглядность исходного текста, а не заниматься "оптимизацией". Все эти оптимизации ушли вместе с ассемблером.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19048
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Starichok51 »

WiseLord, а если число большое и нужно поделить на 10 тысяч или на 10 миллионов?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
mont-oriol
Мучитель микросхем
Сообщения: 437
Зарегистрирован: Пн май 27, 2019 07:18:28
Откуда: ВВХ-ск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение mont-oriol »

https://radiokot.ru/forum/viewtopic.php ... 7#p4386697
Тестирование некорректное. Если data - константа, компилятор имеет полное право вместо

Код: Выделить всё

data = 9876;
a = data / 1000;
b = (data / 100) % 10;
c = (data / 10) % 10;
d = data % 10;
записать a = 9; b = 8; c = 7; d = 6;
И МК вообще ничего не будет вычислять.
Кроме того, в коде с циклами три ошибки. Но это так, мелочи.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение WiseLord »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4386819#p4386819"]WiseLord, а если число большое и нужно поделить на 10 тысяч или на 10 миллионов?[/uquote]Принцип остаётся тот же - заменить деление на умножение и сдвиг.
Если контроллер умеет аппаратно умножить два 8бит числа с 16бит результатом, то и умножение чисел с большей разрядностью легко сводится к умножению октет и суммироованию, что всё равно обходится дешевле циклов вычитаний.
veso74
Поставщик валерьянки для Кота
Сообщения: 1906
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение veso74 »

МК вычисляет :) И еще хочет :ПП

Код: Выделить всё

uint64_t data = 11126789012;
---
  data++;
  PORTB = data / 123456789;
36..40 µs
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

Добавлю: встроенная функция avr-gcc позволяет иметь остаток от деления одновременно с получением частного. Т.е. не сначала деление, а потом взятие остатка от деления, а за один вызов. Думаю, оптимизатор распознает эту ситуацию и делает с минимальными затратами.

Если честно, то вообще не понимаю, к чему в данной ситуации погоня за тактами... Индикация - процесс настолько низкоприоритетный и медленный, что экономить на нем просто глупо...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
veso74
Поставщик валерьянки для Кота
Сообщения: 1906
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение veso74 »

mont-oriol, да, компилятор считает один раз. С расчетом в цикле изменилось: 24 µs к 72 µs. Нравится, есть где использовать.

А лично в 99% случаев неважно как написано - от этого ничего не зависит (скорость?), и если память будет на пределе (если, конечно не любимый ATtiny13A). Вопрос ради вопроса.
Вложения
2.jpg
(68.36 КБ) 77 скачиваний
1.jpg
(61.4 КБ) 76 скачиваний
Аватара пользователя
СКАЗОЧНИК
Идёт направо - песнь заводит, Налево - сказку говорит.
Сообщения: 5000
Зарегистрирован: Чт апр 21, 2011 17:55:50
Откуда: Иркутск

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение СКАЗОЧНИК »

[uquote="ARV",url="/forum/viewtopic.php?p=4386677#p4386677"]В древности писал статью на тему вывода чисел: http://arv.radioliga.com/content/view/106/49/[/uquote]
Очень понравилась Ваша реализация. ) Переделал чуток под себя, конечно.
Идеально выводит числа на 6 разрядов индикатора, прям как я хотел.

Спасибо. :beer:

Добавлено after 2 minutes:
З.Ы. да и пришлось про свитч-кейс еще почитать, что он умеет не только с целыми числами работать, но и с символами.
Станислав
AQ29
Прорезались зубы
Сообщения: 200
Зарегистрирован: Сб июл 30, 2011 21:00:24

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение AQ29 »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4324348#p4324348"]ARV
И если критична производительность и/или объем кода - то стоит задуматься, а нужен ли тут float ?

Вспомнила, делался какой то показометр на линейке диодов, там логарифмическое что то просили считать. Пришлось туда втулить.[/uquote]
А если некритичны производительность и/или объем кода – то тоже стоит задуматься, а нужен ли тут float?

Как я понял из последней фразы, из-за логарифма вы «втулили» float.
Так в целочисленной арифметике тоже есть логарифм.
Например, в, условно говоря, хорошем ассемблере есть вызов функции логарифма. Одна строчка - и есть готовый логарифм.
По объёму и скорости выполнения программа наверняка будет лучше.
Скорее всего, подойдёт самый простой вариант, где аргумент – 2 байта. У него точность вроде как полпроцента, вполне достаточно для рядовых целей.
Диапазон, правда, небольшой, но, скорее всего, несложно расширить с помощью простой школьной арифметики.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

AQ29, Вам шашечки или ехать?
Суть была в чем - пихать флоаты налево и направо - не стоит. В большинстве (обратите внимание - не всегда) случаев от флоатов можно отказаться. Но иногда с ними проще.
У меня проектов на мелких МК с флоатами - ну вот только один и вспомнился. В остальных случаях получилось уйти к целочисленной математике. Ну там, где вообще надо было к ней уходить.
Касательно флоата и логарифма.
Это заказной проект был. Не особо дорогой. И тратить свое время на какие то изыски - не выгодно было.
Я отдавала себе отчет, что флоаты на авр - не самое лучшее решение...
Но в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм?
Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ?
Куда мне девать эти такты и килобайты? Солить на зиму?
Поэтому проще и быстрее взять флоатный логарифм (заодно не трахаться с пересчетом дробных коэффициентов, участвующих в расчетах, в целочисленные) и получить на выходе нужное мне число. Которое потом округлится в целочисленную переменную и засветится на шкале.
Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались...
Всё остальное процессорное время - в моем распоряжении..... И его для той задачи - много. Там можно считать что угодно, хоть float-ом, хоть double-ом... Подождать флаг прихода данных или обновления АЦП -пересчитать данные и обновить инфу для диодов..
Программа в восьмую мегу поместилась, около 30% флеша свободно осталось, в ТЗ по таймингам - умещалось с запасом.
А, и еще не надо спорить с заказчиком. Им надо было, что б все было точно-точно... Дали ТЗ с формулами - получили результат. Я получила денешшшшку. И все довольны.
Зачем мне тратить свое время в таком случае на придумывание?...
Белая и Пушистая
Аватара пользователя
Eats
Потрогал лапой паяльник
Сообщения: 309
Зарегистрирован: Сб фев 18, 2023 21:51:01
Откуда: Санкт-Петербург

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Eats »

[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4387329#p4387329"]в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм? Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ? Куда мне девать эти такты и килобайты? Солить на зиму?[/uquote]Вот, кстати, согласен на все 146%.
Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались...
Аналогичную задачу я решал (и решил) на 13-й тиньке, но (оффтопик!) на ассемблере, поскольку из прикидок на ардуине мне показалось, что на С, да ещё с логарифмом в плавающей запятой я в мелкую тиньку не уложусь: размер кода для 48-й атмеги даже без плавающей запятой был 1864 байта. На асме, конечно, уложился. Объём прошивки стал 760 байт, быстродействие упёрлось в АЦП, а не в процессор, и возник тот же самый вопрос: куда девать лишние такты и лишние байты (25% памяти)???
Зачем мне тратить свое время в таком случае на придумывание?...
Абсолютно справедливая постановка вопроса, ибо никогда не надо забывать про критерий разумной достаточности. :-)
Всего доброго.
Евгений.
Ответить

Вернуться в «AVR»