Страница 3 из 4

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 21:59:23
Kavka
В догонку.

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

// Предделитель тактовой частоты - 8
// CLKPR=0x80;
asm ("push r20"); // Предварительно сохраняем регистр. Но обычно студия его не использует
asm ("ldi r20, 0x80");
asm ("sts 0x60, r20");
//CLKPR=0x03;
asm ("ldi r20, 3");
asm ("sts 0x60, r20");
asm ("pop r20"); // Загружаем обратно в регистр его исходное значение
Смотрим спецификацию на m2560
Изображение



Да посчитайте же вы такты и разберитесь как оно работает!
ИС-пытатель, учите мат.часть!

Удачи.

Добавил спустя несколько минут:
Хоть оно и заработало в сокращённом варианте, но время между выборками будет много больше того, что "зашито" в таймере.
Время будет ещё и немного разное от раза-к-разу.

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:06:06
ИС-пытатель
Kavka писал(а):В догонку.

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

// Предделитель тактовой частоты - 8
// CLKPR=0x80;
asm ("push r20"); // Предварительно сохраняем регистр. Но обычно студия его не использует
asm ("ldi r20, 0x80");
asm ("sts 0x60, r20");
//CLKPR=0x03;
asm ("ldi r20, 3");
asm ("sts 0x60, r20");
asm ("pop r20"); // Загружаем обратно в регистр его исходное значение
Смотрим спецификацию на m2560
Изображение



Да посчитайте же вы такты и разберитесь как оно работает!
ИС-пытатель, учите мат.часть!

Удачи.
Прошу прощения. CLKPR = 0x61. Сейчас поправлю. ) Но это опять не принципиально! ) Эта ошибка появилась сейчас. потому что я переписывал программу с нуля, по памяти, впопыхах и под пиво. )) Сейчас поправлю. К тому же, в моей изначальной программе предделитель процессора устанавливался именно СИшными командами (а это исключает ошибку). И время срабатывания таймера проверялось по изменяющемуся выводу осциллографом. Все было правильно.

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:13:38
ИС-пытатель
Kavka писал(а):
Да посчитайте же вы такты и разберитесь как оно работает!
Для чистоты эксперимента, вставьте десяток-другой команд Nop между стартом таймера и АЦП. (кстати, такой вариант не проверялся) ;)

А вообще у Вас сейчас 2560 или 168 на руках имеется? проверить в железе можете?

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:18:31
ИС-пытатель
Kavka писал(а): Хоть оно и заработало в сокращённом варианте, но время между выборками будет много больше того, что "зашито" в таймере.
Время будет ещё и немного разное от раза-к-разу.
А как Вы проверяли соотношение времени выборок и времени срабатывания таймера? В симуляторе?

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:28:13
Kavka
Смотрел в симуляторе в 6й студии. В железе нет ни одного из упомянутых МК.
Соотношение времени проверять и не требуется зная как работают прерывания в этом МК.

С исправлением про CLKPR ассемблерный вариант работает?

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:29:48
ИС-пытатель
Кстати, факт входа в прерывание АЦП также можно отследить по какому-либо порту (грубо говоря, помигать светодиодами). И я это делал. И контроллер входил.

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:32:39
ИС-пытатель
Kavka писал(а): С исправлением про CLKPR ассемблерный вариант работает?
Так я еще раз говорю, вариант на сайте - дубликат восстановленный по памяти. В первой версии инициализация предделителя была командами СИ. Ошибка исключена. Ассемблерный вариант работает без инструкций PUSH/POP. С любой из них вылет.

И проверить сейчас на железе не могу. все железо осталось на работе. Я Вас прекрасно понимаю в стремлении найти МОЮ ошибку. сам неделю бился головой об стену, думал, что где-то накосячил. Раз 100 перечитал даташит и евстифеева, перепроверил код. Пересчитал такты срабатывания прерываний и выполнения инструкций. Все в пустую. А потом просто в ассемблерном варианте выкинул все лишнее и начал экспериментировать. И нашел условия появления бага.

Re: Внимание!!! Баг контроллера!

Добавлено: Чт мар 13, 2014 22:50:15
Kavka
В железе будете проверять - отключите делитель тактовой CPU...

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 08:25:52
ИС-пытатель
Смотрите. Еще раз железо.
Меняем все команды push/pop в обработчике таймера на команды nop. (по два nop вместо каждой, т.к. длительность команд push/pop 2 такта). Все заработало.
Убираем по две команды nop с пролога и эпилога. и вместо них пихаем Push и Pop регистра r1. Перестало работать.
Далее. Изменение предделителя CPU на работу также не повлияло. (контроллер не работает).

А по поводу тактов. Я подсчитал, действительно прерывание таймера (учитывая пролог обработчика) накладывается на прерывание АЦП. НО!! Таймер срабатывает раз в 16*8=128 тактов контроллера. А сам обработчик таймера "весит" приблизительно 50 тактов. т.е. так как прерывания от таймера и от АЦП возникли в одно время, то первым обрабатывается прерывание от Таймера. (порядка 50 тактов) потом выполняется один jmp основного цикла и остается еще порядка 75 тактов до нового срабатывания таймера, чтобы обработать прерывание от АЦП (А оно тоже около 50 тактов). Принцип очередности прерываний. Пофиг, что наложились, прерывание от АЦП обработается просто позже. И при таком раскладе мы можем получить только не правильный результат АЦП (т.к. запустили его вновь не успев забрать результат), а внутренний счетчик в обработчике АЦП должен нормально работать.
Kavka писал(а):
Загнал Си-шный код в симулятор.
ISR(TIMER0_COMPA_vect) получилась около 45 тактов.
ISR(ADC_vect) получилась около 50 тактов.

Т.е. чаще 90-100 тактов у вас измерять не получиться!

Более того, "таймерный" флаг на прерывание будет уже стоят снова к моменту последующему выходу из ISR(TIMER0_COMPA_vect).
Первый раз попали в прерывание по таймеру - запустили АЦП. Выходим - уже стоит флаг на "таймерное" прерывание. Ну, одна команда CPU выполнилась и снова в обработчик прерывания таймера.
А что же с прерыванием АЦП?! А ничего! Он не будет выполняться вообще!

Укоротив код в ассемблерном представлении вы "впихнули" код во временнЫе рамки и оно заработало.
Здесь Вы не правильно посчитали. Таймер срабатывает раз в 128 тактов контроллера. как раз укладываюсь с измерениями.

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 08:31:08
ИС-пытатель
А по поводу
a_skr писал(а):
Протеус тоже баг эмулирует? ;)
скажу так: Протеус сам один БОЛЬШОЙ-БОЛЬШОЙ БАГ! )))

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 09:38:33
Kavka
ИС-пытатель писал(а):Таймер срабатывает раз в 16*8=128 тактов контроллера.
Вы же поделили тактовую контроллера на 8.
Т.е, повторюсь, такт АЦП == такту таймера == такту CPU и, следовательно, 16 тактов таймера == 16 тактам CPU, а не 128-ми.
ИС-пытатель писал(а):Меняем все команды push/pop в обработчике таймера на команды nop. (по два nop вместо каждой, т.к. длительность команд push/pop 2 такта). Все заработало.
Попробуйте оставить push/pop для r24.

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 09:59:56
ИС-пытатель
Kavka писал(а):
ИС-пытатель писал(а):Таймер срабатывает раз в 16*8=128 тактов контроллера.
Вы же поделили тактовую контроллера на 8.
Т.е, повторюсь, такт АЦП == такту таймера == такту CPU и, следовательно, 16 тактов таймера == 16 тактам CPU, а не 128-ми.
да, я поделил тактовую частоту контроллера на 8. А потом для таймера и АЦП поделил ее еще раз на 8. Предделитель таймера и АЦП делят тактовую чатоту после предделителя CPU, а не ту, которая приходит на него. 128 там тактов.

К тому же это проверено осциллографом по частоте срабатывания таймера. Все совпадает.

На EEPROM только всегда приходит частота до предделителя CPU

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 10:06:09
ИС-пытатель
push r24 тоже не работает.

А еще в 2560 при баге бывает фича, когда в обработчике от АЦП после инкремента переменной добавляешь nop и она начинает считать. Но она как-то через раз работает. Бывает ресанешь - работает. второй раз ресанешь - нет.

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 11:34:54
Kavka
ИС-пытатель писал(а):да, я поделил тактовую частоту контроллера на 8. А потом для таймера и АЦП поделил ее еще раз на 8. Предделитель таймера и АЦП делят тактовую чатоту после предделителя CPU, а не ту, которая приходит на него. 128 там тактов.
:facepalm: Да, тут я дал маху, извините. Не использовал этот делитель (CLKPR) ни разу.
ИС-пытатель писал(а):А еще в 2560 при баге бывает фича, когда в обработчике от АЦП после инкремента переменной добавляешь nop и она начинает считать. Но она как-то через раз работает. Бывает ресанешь - работает. второй раз ресанешь - нет.
Что, IMHO, говорит о ситуации типа "race condition" - проблемы с последовательностью событий, с последовательностью доступа/модификации данных. В случае с МК это связано с прерываниями и независимой работой периферии. Чего-то не учли.

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 12:30:27
ИС-пытатель
Ну, воооот! ))
Kavka писал(а):
:facepalm: Да, тут я дал маху, извините. Не использовал этот делитель (CLKPR) ни разу.
Учите мат.часть! :))) :))) :)))

P.S. А вообще, с Вами приятно было пообщаться. ) Вы действительно хорошо проанализировали код (даже нашли несколько помарок :oops: )и не выдавали версий наугад. ) Спасибо Вам! )

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 16:46:14
Kavka
ИС-пытатель писал(а):Учите мат.часть! :))) :))) :)))
Ну, собственно, что и сделал. Смотри подпись. :)
Вам бы отладку через JTAG погонять - может что-нибудь удастся поймать.

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 16:52:49
ИС-пытатель
Ой, если честно сейчас не до этого. Проблем по горло. Тем более что c JTEG не работал ни разу. Пойду учить мат. часть! :)))

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 17:16:57
Kavka
Так заработало или пока решили оставить эту проблему?

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 19:33:15
ploop
Как я понял, это не проблема, а чисто академический интерес.

Re: Внимание!!! Баг контроллера!

Добавлено: Пт мар 14, 2014 20:00:53
Kavka
ИС-пытатель писал(а):Учите мат.часть! :))) :))) :)))
Примите обратно! :))
ADCSRA – ADC Control and Status Register A
...
Bit 4 – ADIF: ADC Interrupt Flag
This bit is set when an ADC conversion completes and the Data Registers are updated. The
ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set.
ADIF is cleared by hardware when executing the corresponding interrupt handling vector. Alter-
natively, ADIF is cleared by writing a logical one to the flag. Beware that if doing a Read-Modify-
Write on ADCSRA, a pending interrupt can be disabled.
This also applies if the SBI and CBI
instructions are used.
Исоответственно если сделать вот так:

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

ISR(TIMER0_COMPA_vect)
{
    ADCSRA = (ADCSRA & ~_BV(ADIF) ) | _BV(ADSC) ;
}
То всё работает.
Вот и развеян ещё один баг контроллера. :)))
ИС-пытатель писал(а): P.S. А вообще, с Вами приятно было пообщаться. ) Вы действительно хорошо проанализировали код (даже нашли несколько помарок :oops: )и не выдавали версий наугад. ) Спасибо Вам! )
Взаимно (про CLKPR) :))

PS: Ставим плюсы, кому не жалко. :tea: