Jump to content

COKPOWEHEU

Members
  • Posts

    3151
  • Joined

  • Last visited

Reputation

287 Хороший

1 Follower

About COKPOWEHEU

  • Birthday 02/23/1991

Информация

  • Пол
    Мужчина
  • Город
    московская область

Электроника

  • Стаж в электронике
    6-10 лет
  • Сфера радиоэлектроники
    контроллеры

Recent Profile Visitors

16389 profile views
  1. Я много ваших тем видел. Смысла они обычно не несут. Эти коэффициенты - теоретические константы или калибровки, специфичные для конкретной железяки? Зачастую можно выбрать сдвиг на 1, 2, 3 и т.д. байтов в зависимости от требуемой точности. Вот использование стороннего софта для генерации констант мне не нравится: //доступно для изменения юзеру #define KOEFF1 1.23 #define KOEFF2 3.25 //внутренние константы, рассчитываемые препроцессором #define KOEFF1_8 ((unsigned int)((KOEFF1)*256)) #define KOEFF2_16 ((unsigned long)((KOEFF2)*65536)) ... x = (x*KOEFF1_8)>>8; y = (y*KOEFF2_16)>>16;
  2. В AVR модификатор const не означает размещение во флеш, нужен еще PROGMEM. LiVit, а это Вы поддерживаете? Вариантов много. Самый простой - да, умножить на 384 и делить на 1000 - тогда коэффициент можно задать в человеко-читаемом виде. Если же это просто число, чье представление не несет особого смысла - коэффициент резистивного делителя, например - можно умножить на 98 и поделить на 256. Или умножить на 25166 и поделить на 65536. Домашнее задание: разобраться почему для делителей я выбрал именно эти числа. Кстати, на соседнем форуме сейчас обсуждается подобный подход как замена делению на 10. Потому что умножение действительно оказывается быстрее.
  3. Потому что это особенность хранения чисел в формате ieee 754, а не каких-то конкретных компиляторов
  4. Не знаю что именно у вас не работает. Вот так работает: #include <avr/io.h> #include <util/delay.h> #include "pinmacro.h" #include "uart.h" #include <stdio.h> #define GLED B,5,1 #define YLED D,1,1 static int putchar_uart(char c, FILE *stream){ uart_write(c); return 1; } static int getchar_uart(FILE *stream){ while(uart_is_empty()){} return uart_read(); } static FILE uart = FDEV_SETUP_STREAM( putchar_uart, getchar_uart, _FDEV_SETUP_WRITE | _FDEV_SETUP_READ ); static int putchar_virt(char c, FILE *stream){ if(c == '1')PORT_1(GLED); if(c == '2')PORT_0(GLED); return 1; } static int getchar_virt(FILE *stream){ return '\n'; } static FILE virt = FDEV_SETUP_STREAM( putchar_virt, getchar_virt, _FDEV_SETUP_WRITE | _FDEV_SETUP_READ ); int main(){ DDR_1(GLED); uart_init(96); while(1){ fprintf(&uart, "test\r\n"); fprintf(&virt, "1"); _delay_ms(1000); fprintf(&uart, "test\r\n"); fprintf(&virt, "2"); _delay_ms(1000); } }
  5. Так же, как в компьютерном программировании: через файловые потоки: fprintf( uart1, "text\r\n" ); fprintf( stdout, "text\r\n" ); Насколько помню, все это там поддерживается. Другое дело надо ли вообще тащить такую монструозию как stdio в контроллер?
  6. Сдается мне, "вышки" он просто-напросто купил. Потому что чтобы их получить честно, нужно читать, и весьма немало. Да зачем! Можно ведь на форуме вопрос задать, поклянчить "помогите люди добрые", авось какой дурак да сделает работу Юрий_Нд за него бесплатно. То есть по-вашему форум это место, где бесплатно пересказывают даташит? Нет, не угадали. Форум - это место, где рассматривают места, а документации НЕ освещенные или освещенные слабо. --- Ладно, если вы упорно игнорируете ценные советы, не буду тратить силы попусту. На всякий случай уточню: я не говорил, что не буду писать в этой теме и не говорил, что не буду издеваться над очередным воинствующим неучем. Кстати! Юрий_Нд, вы там неких Ассемблера и pcmax (один на ЛОРе, второй на Киберфоруме) не знаете? А то очень похожи по стилю, только те двое код для stm32 пытались наклянчить, а вы, похоже, в железо ударились.
  7. Вы правы, хвастаться регалиями, которые не подтверждены реальными знаниями, никакого смысла нет. Нет. Во-первых, как уже заметил Starichok, АЦП в m8 всего один. Во-вторых, каналы 6 и 7 там тоже есть, но только в SMD-корпусе. В-третьих, "выжать все" это несколько более широкий термин. Туда может входить и точность измерений, и скорость, и анализ. В даташите, естественно. Там и рекомендуемая частота АЦП указана, и время выборки, и время преобразования. Зачем еще и форум подобным засорять? Что за тема? Скорее всего, она меня просто не заинтересовала. Как и тут: я не знаю в чем у вас была проблема с этими переменными. Сами же видите, что никакой сложной математики нет.
  8. АЦП у нас 10-битный, то есть 0-1023. При сложении 40 измерений получаем диапазон 0*40 - 1023*40 = 0 - 40920. Минимальный тип данных, в который такое число влезает uint16_t (0-65535). Для сложения 100 измерений соответственно 0-102300 - уже в uint16_t не помещается, придется брать uint32_t (0-4*109). Брать знаковые числа в данном случае смысла вообще нет. Что считается вордом? Правильно, но надо помнить, что это именно для AVR. На других архитектурах int может быть и 32, и 64 бита. Именно поэтому я рекомендую пользоваться типами фиксированной размерности: uint16_t и подобными. Кажется, я понимаю, что вы имеете в виду, но все же поправлю терминологию. "Ячейка памяти" это минимальный объем данных, которым может оперировать контроллер. Обычно это байт. А вы, похоже, имеете в виду бит. Обратиться непосредственно к биту ни одна из известных мне архитектур не может. Очень хочется придраться, что раз система у нас 8-битная, то считать она будет в 256-ричной системе. Но подобный философский вопрос все же не для этой ветки. Да, именно так. Я рад, что вы докопались до истины. Если "подобные обвинения" являются лучшим способом подтолкнуть вас к изучению матчасти, мы будем вынуждены ими пользоваться. Дело тут в основном в том, как вы себя позиционируете на форуме - как "безумного идиота, который случайно меняет константы" или как заинтересованного человека, который искренне пытается разобраться в теме. Пока вы каждый пост начинаете с "помогите люди добрые, у меня стандартный код не работает" отношение будет соответствующим. Но если вы попытаетесь сначала свою проблему решить самостоятельно и продемонстрируете ход мыслей и тот тупик, который лбом уже не проламывается, шанс на помощь будет выше. А еще выше шанс, что помощь и не понадобится. Дело в том, что когда (я не слишком оптимистичен?) вы вырастите из типичных задач и углубитесь в малоизученные темы, будет проблемой просто найти человека, который в этой теме что-то знает. Быстрее оказывается найти решение самостоятельно, чем ждать подсказки.
  9. Нет, нужно сначала попытаться решить проблему самостоятельно, и только потом спрашивать. Из чего складывается вывод АЦП на экран? Из измерения, усреднения по 40 точкам и преобразования в строку. В некоторых кривых библиотеках добавляется еще перевод в дробные числа, который, естественно, ухудшает точность и сильно ухудшает скорость. Вот по очереди эти шаги и проверяете. Правильно ли идет оцифровка одного измерения? Правильно ли срабатывает выбор канала (рекомендую проверить не только 0 и 1 каналы, но и остальные. Даже не только проверить, но и исправить чтобы работало)? Правильно ли идет усреднение? Правильно ли идет вывод? Я даже подскажу: проблема в функции readADC(). Ну и в Lcd_printf() - из-за дурацкой идеи преобразовывать целое число в дробное. Подобные вещи всегда считаются в фиксированной точке! Если бы ее заметили вы, сами бы и исправили. А то, что на нее случайно наткнулись, бездумно меняя константы - другой вопрос. Потом решить усреднять не по 40 точкам, а по 256 - "а-а-а, у вас ошибка". Не угадали, процессор 8-битный. Снова не угадали. Потому что деление на степень двойки не требует деления. А сформулировать по-человечески сложно? Количество шагов оцифровки в AVR фиксированное, 12.5 - эта цифра есть в даташите. Выходное значение АЦП физически не может принимать значения за пределами 0-1023. Либо 0-65536 при выравнивании влево. Э нет, это ведь у вас возникло непонимание. Все остальные прекрасно знают откуда и какие ограничения берутся. Вот разберитесь и изложите свое понимание здесь - чтобы мы могли проверить. А лучше на uin16_t из <inttypes.h>
  10. Спрашивать конкретные вопросы, которые у вас появятся при решении конкретной задачи, естественно. Не "Допустим вывели мы на дисплей первое слово, а что дальше? Допустим, изменил я исходный код, а на дисплея висит всё то-же слово.", а хотя бы "Я вывел на дисплей слово. Потом изменил код программы чтобы выводила другое слово, но выводится все равно предыдущее. Я заменил код программы на простую мигалку (чтобы проверить, что дело именно в дисплее) - все равно выводит слово и не мигает. Я проверил правильный ли файл прошивки указан в Протеусе - правильный. Я сравнил размер этого файла и то, что показывает Студия при компиляции - одинаково. А! Это наверное не тот проект открылся случайно" - после чего вопрос решен и его уже можно не задавать на форуме. Видите разницу? Указано неправильное поведение программы, указано желаемое поведение, указаны предпринятые шаги по отладке. ... это Вы о ком? О вас, конечно, о ком же еще. Ну и о других подобных, считающих форум населенным телепатами.
  11. Можно. Спрашивайте по существу. Не абстрактные вопросы, на которые вы бы сами нашли ответ, если бы хоть немного поискали, а конкретные. Даже это лучше текущего "Хелп! У меня ничего не работает". Будет хотя бы схема и программа, которые хотя бы в протеусе работают. Можно будет традиционно послать искать сопли и непропаи, в чем в 90% случаев проблема и окажется.
  12. А вы уже придумали какое именно устройство собираете? Потому что из формулировки вопроса можно сделать предположение, что вы пытаетесь узнать все подробности заранее. И в данном случае это неэффективно: лучше начните собирать устройство в железе, многие вопросы сами отпадут.
  13. Так в коде дробные числа используются. Искать как это отключается в исходной версии лень, поэтому скажу про свою: с поддержкой дробных 3796. Без нее 2838. UPD: отчасти это лечится флагами -fdata-sections -ffunction-sections -Wl,--gc-sections. UPD2: Оказывается, в моем main.c просто использовалось большое количество функций, из-за чего ли6нкер не может их выкинуть. Если привести код к варианту gogaze, размер составляет 1608 Если вы не собираетесь разводить плату, зачем вообще браться за электронику? Не просто же так помигать дисплеем в протезе. В протезе некоторые вещи тестировать проще, чем на железе.
  14. $ make avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=12000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d -c ../main.c ../main.c:3:0: warning: "F_CPU" redefined #define F_CPU 8000000 ^ <command-line>:0:0: note: this is the location of the previous definition avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=12000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT n5110.o -MF dep/n5110.o.d -c ../n5110.c avr-gcc -mmcu=atmega8 main.o n5110.o -o firmware.elf avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature firmware.elf firmware.hex avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex firmware.elf firmware.eep || exit 0 avr-objdump -h -S firmware.elf > firmware.lss AVR Memory Usage ---------------- Device: atmega8 Program: 3620 bytes (44.2% Full) (.text + .data + .bootloader) Data: 526 bytes (51.4% Full) (.data + .bss + .noinit) Проблема все-таки есть. Причем не только в объеме, но и в том, что кто-то пихает F_CPU прямо в код, где ему не место.
  15. Так я же говорил что на Хабре: https://habr.com/ru/users/cokpoweheu/posts/ Там, кстати, почитать стоит независимо от того, чью реализацию будете использовать, потому что я пытался рассмотреть принцип работы и теорию, хотя и кратко. И вариант Эдди, который я упоминал. Вдруг больше понравится: https://github.com/eddyem/stm32samples/tree/master/F1-nolib А вот это (https://habr.com/ru/post/560048/) кажется на С++ сделано. Не уверен что сделано качественно, поскольку в С++ я не шарю.
×
×
  • Create New...