Z_h_e писал(а):Правда мне непонятно почему в формуле 1024, а не 1023.
Может, потому что так оно и есть?.
Любые значения в диапазоне [0..1) - это 0, [1..2) - это 1, ..., [1023..1024) - это 1023, всё выше - тоже 1023.
АЦП изменяет весь диапазон 0..1024, просто именно верхнюю границу отобразить не может. Вот в формуле и фигурирует 1024, что, к счастью, сильно упрощает вычисления.
Возьмем для примера гипотетическое АЦП 2х разрядное (просто на нем нагляднее будет) .
Пускай ИОН 5 В. АЦП выдало код 3. По аналогии считаем 2^2/3*5=6,67В. Плохая математика получается. Конечно чем больше разрядность, тем менее это заметно.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Конечно 0 может быть результатом АЦП. Но я специально привел пример 2х разрядного АЦП, чтобы было понятно что я тут считаю не так с математикой.
В реале, для 10 битного АЦП, да еще и при шумящем младшем бите (это в лучшем случае) - это не имеет особого значения. Просто считайте меня занудой .
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
[uquote="Z_h_e",url="/forum/viewtopic.php?p=3158621#p3158621"]Возьмем для примера гипотетическое АЦП 2х разрядное (просто на нем нагляднее будет) .
Пускай ИОН 5 В. АЦП выдало код 3. По аналогии считаем 2^2/3*5=6,67В. Плохая математика получается. Конечно чем больше разрядность, тем менее это заметно.[/uquote]
Что-то я не совсем понял, что это Вы посчитали.
Формула по аналогии будет ADC = Vin/Vref * 2^2, откуда Vin = ADC * Vref / (2^2)
В нашем гипотетическом случае Vin = ADC * 5 / 4. (Vin = ADC * 5 / 3, если брать 2^2-1).
Как по мне, первая картинка, под первую формулу, правильнее:
Может не совсем в тему, но...
Пишу на с, asm не знаю совершенно, не могу понять почему ATMega32, во время выполнения программы, как будто виснет. Если во время "зависания" была включена отладка и нажать останов, то останавливается вот тут:
--- No source file -------------------------------------------------------------
0000037E LSL R30 Logical Shift Left
0000037F ROL R31 Rotate Left Through Carry
00000380 LPM R0,Z+ Load program memory and postincrement
00000381 LPM R31,Z Load program memory
00000382 MOV R30,R0 Copy register
00000383 IJMP Indirect jump to (Z)
00000384 CLI Global Interrupt Disable
00000385 RJMP PC-0x0000 Relative jump // вот тут получается останов
00000386 NOP Undefined
00000387 NOP Undefined
00000388 NOP Undefined
00000389 NOP Undefined
0000038A NOP Undefined
0000038B NOP Undefined
0000038C NOP Undefined
0000038D NOP Undefined
0000038E NOP Undefined
0000038F NOP Undefined
00000390 NOP Undefined
00000391 NOP Undefined
00000392 NOP Undefined
Правильно ли я понимаю, что "RJMP PC-0x0000" это, что то вроде перехода по адресу относительно команды, а т.к. параметр нулевой, получается переход на саму себя, т.е. вечный while(1)?
Т.к. перед этим стоит CLI - глобальный запрет прерываний, вся эта петрушка вероятно из-за какого то аппаратного сбоя в МК или программе, это своеобразный стоп работы(максимизация ошибки). В самой программе ничего такого нет, т.е. это компиллятор по умолчанию добавляет(Atmel Studio 7.0)?
Если отбросить железные проблемы, то почему такое может происходить?
FeCat писал(а):это компиллятор по умолчанию добавляет
в конце программы, а вот косвенный переход по адресу в указателе Z выбрасывает в заадресное пространство mega32. Как вариант, компилируете для камня с адресным пространством >32к.
[uquote="FeCat",url="/forum/viewtopic.php?p=3158782#p3158782"]...[/uquote]
Этот кусок аварийный. Если какой-нибудь сбой, незапланированное прерывание, то программа уйдет на выполнение этого кода. Глобальный запрет прерываний, cli и rjmp PC+0 - глухое зацикливание программы. Возможно у вас включено какое-то прерывание, а обработчика нет. Компилятор в таких случаях автоматом делает такие программные заглушки.
Demiurg писал(а):Возможно у вас включено какое-то прерывание, а обработчика нет. Компилятор в таких случаях автоматом делает такие программные заглушки.
avr-gcc в этом случае не зацикливает программу, а перебрасывает её на нулевой вектор, т.е. выполняет пересброс.
avr-gcc автоматически генерирует последовательность cli; jmp PC - 0; только в одном месте: там, где происходит выход из main.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
WiseLord писал(а):Как по мне, первая картинка, под первую формулу, правильнее:
Не надо было приводить даже такие картинки, в ДШ есть график на котором указано что Vref выше 0x3FF. И формулу расчета я не пытался оспаривать, как сделали разрабы камня, так и надо считать. Просто мои зачерепные опилки желают, чтобы максимум АЦП соответствовал опоре.
WiseLord писал(а):Что-то я не совсем понял, что это Вы посчитали.
Что тут может быть непонятного, хрень какую-то насчитал я. Хотел показать, что код АЦП не будет соотвествовать ИОН никогда и показал .
Добавлено after 8 minutes 29 seconds:
ARV писал(а):avr-gcc в этом случае не зацикливает программу, а перебрасывает её на нулевой вектор, т.е. выполняет пересброс.
Можно вставить обработчик по умолчанию ISR(__vector_default), но он же тоже не циклит, если сам это не сделаешь.
FeCat писал(а):Если отбросить железные проблемы, то почему такое может происходить?
А Вы запустите в симуляторе код и в окне дизассемблера должно быть указано к какому участку исходного кода соответствует машинный.
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Добавлено after 9 minutes 57 seconds:
Кстати, вот другой кусочек, поясняющий, как avr-gcc обслуживает прерывания, для которых нет обработчика (bad_interrupt):
Вы не учитываете одну очень важную вещь. И это говорит о том, что вы не ассемблерщик. Пусть даже и так, вы обязаны заглядывать в дизасм. Иначе как вы оцениваете работу МК в тяжелых случаях.
Demiurg писал(а):вы не ассемблерщик. Пусть даже и так, вы обязаны заглядывать в дизасм. Иначе как вы оцениваете работу МК в тяжелых случаях
как бы я вам дизасм и привел в качестве подтверждения своих слов. а ассемблер у меня занимает ровно ту нишу, которую и должен - помогает в особо тяжких случаях, а в остальных полагаюсь на Си. перерос я ассемблер...
Demiurg писал(а):Подсказка. Main вызван, а стек сорван
за подсказку спасибо, но теперь подскажите по подсказке: в каком именно месте срывается стек при вызове main? напоминаю код:
В том-то и дело, что стек может сорвать в любой момент. Незапланированное прерывание может быть включено в любой момент. Это может быть ошибка программиста. Сбой по питанию. Именно по этой причине делается переход на такой кусок код. Отключается глобально прерывание и глухое зацикливание. Если watchdog не включен, мк наглухо зависнет. Если включен, то мк зависнет до сработки сторожевого таймера.
akl
Demiurg
ARV
Z_h_e
Спасибо, что откликнулись. Нашёл ошибку... в железе ). Фьюз CKOPT не запрограммировал. В результате на макетке ловил помеху раз в несколько минут.
Demiurg писал(а):Незапланированное прерывание может быть включено в любой момент. Это может быть ошибка программиста. Сбой по питанию. Именно по этой причине делается переход на такой кусок код.
вы о чем вообще говорите? AVR систему исключений (exception) не поддерживает, и запланировать переход на какую-то заглушку в случае незапланированного "срыва стека" невозможно.
я же говорю только о факте: avr-gcc генерирует кусочек кода с запретом прерываний и вечным циклом только в одном месте - после завершения main (туда же передается управление по стандартной функции exit). в качестве обработки необслуживаемых прерываний avr-gcc пересбрасывает программу. оба эти утверждения я сопроводил доказательствами в виде кусков листинга из-под avr-gcc.
ничего иного я не говорил.
если я вас не правильно понял - поясните, что вы имеете ввиду.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...