Нескольно простых вопросов о программировании AVR на Си.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 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 на Си.
[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-томника "Микроконтроллеры" от Алекса Фрунзе. Не столь популярное, но тоже небесполезное описание всё той же самой математики есть и в жёлтой книжке "Программы для микропроцессоров" Гуртовцева и Гудыменко. И всё это есть в сети.Опишите суть, или ткните, где это максимально понятно расписано.
Всего доброго.
Евгений.
Евгений.
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="СКАЗОЧНИК",url="/forum/viewtopic.php?p=4386503#p4386503"]...Теперь я хочу разбивать число неопределенного количества разрядов на цифры... Суть в том, что я не знаю, сколько разрядов у числа изначально...[/uquote]
Не обязательно делить или вычитать. Можно провести десятичную коррекцию, начиная с младших разрядов.
https://radiokot.ru/forum/viewtopic.php ... 9#p1417529
Не обязательно делить или вычитать. Можно провести десятичную коррекцию, начиная с младших разрядов.
https://radiokot.ru/forum/viewtopic.php ... 9#p1417529
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
В древности писал статью на тему вывода чисел: http://arv.radioliga.com/content/view/106/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Starichok51
- Модератор
- Сообщения: 19048
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Нескольно простых вопросов о программировании AVR на Си.
да, каждый раз нужно сначала делать проверку на возможность вычесть, потом вычитают.СКАЗОЧНИК писал(а):Т.е. каждый раз сравнивают (проверяют), что разность больше чем вычитаемое, тогда продолжают вычитать. Накапливают переменную. и так далее с каждым разрядом?
а иногда делают наоборот - сначала вычитают, потом проверяют остаток на знак. если положительный, продолжают вычитать. если отрицательный, прибавляют и переходят к следующему разряду.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- Реклама
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1906
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Starichok51, спасибо, интересно. Код небольшой (против /10 и %10).
---
Да, но медленнее
.
Код выше по сравнению с кодом ниже: 20 µs / 4 µs (ATmega328, 16 MHz).
Код: Выделить всё
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
Да, но медленнее
Код выше по сравнению с кодом ниже: 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 на Си.
veso74, что-то мне не верится, что деление и потом взятие %10 работает быстрее вычитания.
я не умею писать для МК на Си, чтобы самому это проверить.
я не умею писать для МК на Си, чтобы самому это проверить.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1906
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Все по умолчанию, оптимизация на макс. Ардуино IDE, со своим языком и функциями (печать в Serial из отчетности время пропущен).
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
[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 погрешность нулевая.
я не умею писать для МК на Си, чтобы самому это проверить.[/uquote]
Поверьте, быстрее.
Компиляторы сейчас умные, и при включенной (по умолчанию) оптимизации сами реализуют деление на 10 как умножение со сдвигом, что и кода меньше занимает, и по времени гораздо быстрее, чем отнимать и считать циклы.
К примеру, вместо целочисленного деления uint8_t числа на 10 компилятор сам может сообразить, что это то же самое, что умножить это число на 205 и результат сдвинуть на 11 разрядов вправо.
Почему 205? Потому что X / 10 = X * 204.8 / 2048 ~= X * 205 / 2048 = (X * 205) << 11. Что для любых чисел само по себе приблизительно, но для однобайтовых X погрешность нулевая.
Re: Нескольно простых вопросов о программировании AVR на Си.
+1000500. Считаю, и не только я, что в наше время, в первую очередь, нужно обращать внимание на наглядность исходного текста, а не заниматься "оптимизацией". Все эти оптимизации ушли вместе с ассемблером.
- Starichok51
- Модератор
- Сообщения: 19048
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Нескольно простых вопросов о программировании AVR на Си.
WiseLord, а если число большое и нужно поделить на 10 тысяч или на 10 миллионов?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
-
mont-oriol
- Мучитель микросхем
- Сообщения: 437
- Зарегистрирован: Пн май 27, 2019 07:18:28
- Откуда: ВВХ-ск
Re: Нескольно простых вопросов о программировании AVR на Си.
https://radiokot.ru/forum/viewtopic.php ... 7#p4386697
Тестирование некорректное. Если data - константа, компилятор имеет полное право вместо
записать a = 9; b = 8; c = 7; d = 6;
И МК вообще ничего не будет вычислять.
Кроме того, в коде с циклами три ошибки. Но это так, мелочи.
Тестирование некорректное. Если data - константа, компилятор имеет полное право вместо
Код: Выделить всё
data = 9876;
a = data / 1000;
b = (data / 100) % 10;
c = (data / 10) % 10;
d = data % 10;И МК вообще ничего не будет вычислять.
Кроме того, в коде с циклами три ошибки. Но это так, мелочи.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="Starichok51",url="/forum/viewtopic.php?p=4386819#p4386819"]WiseLord, а если число большое и нужно поделить на 10 тысяч или на 10 миллионов?[/uquote]Принцип остаётся тот же - заменить деление на умножение и сдвиг.
Если контроллер умеет аппаратно умножить два 8бит числа с 16бит результатом, то и умножение чисел с большей разрядностью легко сводится к умножению октет и суммироованию, что всё равно обходится дешевле циклов вычитаний.
Если контроллер умеет аппаратно умножить два 8бит числа с 16бит результатом, то и умножение чисел с большей разрядностью легко сводится к умножению октет и суммироованию, что всё равно обходится дешевле циклов вычитаний.
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1906
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
МК вычисляет
И еще хочет :ПП
36..40 µs
Код: Выделить всё
uint64_t data = 11126789012;
---
data++;
PORTB = data / 123456789;- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Добавлю: встроенная функция avr-gcc позволяет иметь остаток от деления одновременно с получением частного. Т.е. не сначала деление, а потом взятие остатка от деления, а за один вызов. Думаю, оптимизатор распознает эту ситуацию и делает с минимальными затратами.
Если честно, то вообще не понимаю, к чему в данной ситуации погоня за тактами... Индикация - процесс настолько низкоприоритетный и медленный, что экономить на нем просто глупо...
Если честно, то вообще не понимаю, к чему в данной ситуации погоня за тактами... Индикация - процесс настолько низкоприоритетный и медленный, что экономить на нем просто глупо...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
veso74
- Поставщик валерьянки для Кота
- Сообщения: 1906
- Зарегистрирован: Сб май 05, 2012 20:24:52
- Откуда: KN34PC, Болгария
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
mont-oriol, да, компилятор считает один раз. С расчетом в цикле изменилось: 24 µs к 72 µs. Нравится, есть где использовать.
А лично в 99% случаев неважно как написано - от этого ничего не зависит (скорость?), и если память будет на пределе (если, конечно не любимый ATtiny13A). Вопрос ради вопроса.
А лично в 99% случаев неважно как написано - от этого ничего не зависит (скорость?), и если память будет на пределе (если, конечно не любимый ATtiny13A). Вопрос ради вопроса.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 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 разрядов индикатора, прям как я хотел.
Спасибо.
Добавлено after 2 minutes:
З.Ы. да и пришлось про свитч-кейс еще почитать, что он умеет не только с целыми числами работать, но и с символами.
Очень понравилась Ваша реализация. ) Переделал чуток под себя, конечно.
Идеально выводит числа на 6 разрядов индикатора, прям как я хотел.
Спасибо.
Добавлено after 2 minutes:
З.Ы. да и пришлось про свитч-кейс еще почитать, что он умеет не только с целыми числами работать, но и с символами.
Станислав
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4324348#p4324348"]ARV
И если критична производительность и/или объем кода - то стоит задуматься, а нужен ли тут float ?
Вспомнила, делался какой то показометр на линейке диодов, там логарифмическое что то просили считать. Пришлось туда втулить.[/uquote]
А если некритичны производительность и/или объем кода – то тоже стоит задуматься, а нужен ли тут float?
Как я понял из последней фразы, из-за логарифма вы «втулили» float.
Так в целочисленной арифметике тоже есть логарифм.
Например, в, условно говоря, хорошем ассемблере есть вызов функции логарифма. Одна строчка - и есть готовый логарифм.
По объёму и скорости выполнения программа наверняка будет лучше.
Скорее всего, подойдёт самый простой вариант, где аргумент – 2 байта. У него точность вроде как полпроцента, вполне достаточно для рядовых целей.
Диапазон, правда, небольшой, но, скорее всего, несложно расширить с помощью простой школьной арифметики.
И если критична производительность и/или объем кода - то стоит задуматься, а нужен ли тут float ?
Вспомнила, делался какой то показометр на линейке диодов, там логарифмическое что то просили считать. Пришлось туда втулить.[/uquote]
А если некритичны производительность и/или объем кода – то тоже стоит задуматься, а нужен ли тут float?
Как я понял из последней фразы, из-за логарифма вы «втулили» float.
Так в целочисленной арифметике тоже есть логарифм.
Например, в, условно говоря, хорошем ассемблере есть вызов функции логарифма. Одна строчка - и есть готовый логарифм.
По объёму и скорости выполнения программа наверняка будет лучше.
Скорее всего, подойдёт самый простой вариант, где аргумент – 2 байта. У него точность вроде как полпроцента, вполне достаточно для рядовых целей.
Диапазон, правда, небольшой, но, скорее всего, несложно расширить с помощью простой школьной арифметики.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
AQ29, Вам шашечки или ехать?
Суть была в чем - пихать флоаты налево и направо - не стоит. В большинстве (обратите внимание - не всегда) случаев от флоатов можно отказаться. Но иногда с ними проще.
У меня проектов на мелких МК с флоатами - ну вот только один и вспомнился. В остальных случаях получилось уйти к целочисленной математике. Ну там, где вообще надо было к ней уходить.
Касательно флоата и логарифма.
Это заказной проект был. Не особо дорогой. И тратить свое время на какие то изыски - не выгодно было.
Я отдавала себе отчет, что флоаты на авр - не самое лучшее решение...
Но в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм?
Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ?
Куда мне девать эти такты и килобайты? Солить на зиму?
Поэтому проще и быстрее взять флоатный логарифм (заодно не трахаться с пересчетом дробных коэффициентов, участвующих в расчетах, в целочисленные) и получить на выходе нужное мне число. Которое потом округлится в целочисленную переменную и засветится на шкале.
Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались...
Всё остальное процессорное время - в моем распоряжении..... И его для той задачи - много. Там можно считать что угодно, хоть float-ом, хоть double-ом... Подождать флаг прихода данных или обновления АЦП -пересчитать данные и обновить инфу для диодов..
Программа в восьмую мегу поместилась, около 30% флеша свободно осталось, в ТЗ по таймингам - умещалось с запасом.
А, и еще не надо спорить с заказчиком. Им надо было, что б все было точно-точно... Дали ТЗ с формулами - получили результат. Я получила денешшшшку. И все довольны.
Зачем мне тратить свое время в таком случае на придумывание?...
Суть была в чем - пихать флоаты налево и направо - не стоит. В большинстве (обратите внимание - не всегда) случаев от флоатов можно отказаться. Но иногда с ними проще.
У меня проектов на мелких МК с флоатами - ну вот только один и вспомнился. В остальных случаях получилось уйти к целочисленной математике. Ну там, где вообще надо было к ней уходить.
Касательно флоата и логарифма.
Это заказной проект был. Не особо дорогой. И тратить свое время на какие то изыски - не выгодно было.
Я отдавала себе отчет, что флоаты на авр - не самое лучшее решение...
Но в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм?
Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ?
Куда мне девать эти такты и килобайты? Солить на зиму?
Поэтому проще и быстрее взять флоатный логарифм (заодно не трахаться с пересчетом дробных коэффициентов, участвующих в расчетах, в целочисленные) и получить на выходе нужное мне число. Которое потом округлится в целочисленную переменную и засветится на шкале.
Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались...
Всё остальное процессорное время - в моем распоряжении..... И его для той задачи - много. Там можно считать что угодно, хоть float-ом, хоть double-ом... Подождать флаг прихода данных или обновления АЦП -пересчитать данные и обновить инфу для диодов..
Программа в восьмую мегу поместилась, около 30% флеша свободно осталось, в ТЗ по таймингам - умещалось с запасом.
А, и еще не надо спорить с заказчиком. Им надо было, что б все было точно-точно... Дали ТЗ с формулами - получили результат. Я получила денешшшшку. И все довольны.
Зачем мне тратить свое время в таком случае на придумывание?...
Белая и Пушистая
- Eats
- Потрогал лапой паяльник
- Сообщения: 309
- Зарегистрирован: Сб фев 18, 2023 21:51:01
- Откуда: Санкт-Петербург
Re: Нескольно простых вопросов о программировании AVR на Си.
[uquote="Just_Fluffy",url="/forum/viewtopic.php?p=4387329#p4387329"]в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм? Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ? Куда мне девать эти такты и килобайты? Солить на зиму?[/uquote]Вот, кстати, согласен на все 146%.

Аналогичную задачу я решал (и решил) на 13-й тиньке, но (оффтопик!) на ассемблере, поскольку из прикидок на ардуине мне показалось, что на С, да ещё с логарифмом в плавающей запятой я в мелкую тиньку не уложусь: размер кода для 48-й атмеги даже без плавающей запятой был 1864 байта. На асме, конечно, уложился. Объём прошивки стал 760 байт, быстродействие упёрлось в АЦП, а не в процессор, и возник тот же самый вопрос: куда девать лишние такты и лишние байты (25% памяти)???Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались...
Абсолютно справедливая постановка вопроса, ибо никогда не надо забывать про критерий разумной достаточности.Зачем мне тратить свое время в таком случае на придумывание?...
Всего доброго.
Евгений.
Евгений.


