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

Обсуждаем контроллеры компании Atmel.
Ответить
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение 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
Изображение



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

Удачи.

Добавил спустя несколько минут:
Хоть оно и заработало в сокращённом варианте, но время между выборками будет много больше того, что "зашито" в таймере.
Время будет ещё и немного разное от раза-к-разу.
Вложения
wdr_clkpr.png
(10.19 КБ) 751 скачивание
Последний раз редактировалось Kavka Чт мар 13, 2014 22:09:59, всего редактировалось 1 раз.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

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. Сейчас поправлю. ) Но это опять не принципиально! ) Эта ошибка появилась сейчас. потому что я переписывал программу с нуля, по памяти, впопыхах и под пиво. )) Сейчас поправлю. К тому же, в моей изначальной программе предделитель процессора устанавливался именно СИшными командами (а это исключает ошибку). И время срабатывания таймера проверялось по изменяющемуся выводу осциллографом. Все было правильно.
Последний раз редактировалось ИС-пытатель Чт мар 13, 2014 22:16:32, всего редактировалось 3 раза.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

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

А вообще у Вас сейчас 2560 или 168 на руках имеется? проверить в железе можете?
Последний раз редактировалось ИС-пытатель Чт мар 13, 2014 22:24:13, всего редактировалось 1 раз.
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Kavka писал(а): Хоть оно и заработало в сокращённом варианте, но время между выборками будет много больше того, что "зашито" в таймере.
Время будет ещё и немного разное от раза-к-разу.
А как Вы проверяли соотношение времени выборок и времени срабатывания таймера? В симуляторе?
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Смотрел в симуляторе в 6й студии. В железе нет ни одного из упомянутых МК.
Соотношение времени проверять и не требуется зная как работают прерывания в этом МК.

С исправлением про CLKPR ассемблерный вариант работает?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Кстати, факт входа в прерывание АЦП также можно отследить по какому-либо порту (грубо говоря, помигать светодиодами). И я это делал. И контроллер входил.
Последний раз редактировалось ИС-пытатель Чт мар 13, 2014 22:33:00, всего редактировалось 1 раз.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

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

И проверить сейчас на железе не могу. все железо осталось на работе. Я Вас прекрасно понимаю в стремлении найти МОЮ ошибку. сам неделю бился головой об стену, думал, что где-то накосячил. Раз 100 перечитал даташит и евстифеева, перепроверил код. Пересчитал такты срабатывания прерываний и выполнения инструкций. Все в пустую. А потом просто в ассемблерном варианте выкинул все лишнее и начал экспериментировать. И нашел условия появления бага.
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

В железе будете проверять - отключите делитель тактовой CPU...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Смотрите. Еще раз железо.
Меняем все команды 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 тактов контроллера. как раз укладываюсь с измерениями.
Последний раз редактировалось ИС-пытатель Пт мар 14, 2014 09:13:25, всего редактировалось 2 раза.
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

А по поводу
a_skr писал(а):
Протеус тоже баг эмулирует? ;)
скажу так: Протеус сам один БОЛЬШОЙ-БОЛЬШОЙ БАГ! )))
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ИС-пытатель писал(а):Таймер срабатывает раз в 16*8=128 тактов контроллера.
Вы же поделили тактовую контроллера на 8.
Т.е, повторюсь, такт АЦП == такту таймера == такту CPU и, следовательно, 16 тактов таймера == 16 тактам CPU, а не 128-ми.
ИС-пытатель писал(а):Меняем все команды push/pop в обработчике таймера на команды nop. (по два nop вместо каждой, т.к. длительность команд push/pop 2 такта). Все заработало.
Попробуйте оставить push/pop для r24.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

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

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

На EEPROM только всегда приходит частота до предделителя CPU
Последний раз редактировалось ИС-пытатель Пт мар 14, 2014 10:09:07, всего редактировалось 2 раза.
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

push r24 тоже не работает.

А еще в 2560 при баге бывает фича, когда в обработчике от АЦП после инкремента переменной добавляешь nop и она начинает считать. Но она как-то через раз работает. Бывает ресанешь - работает. второй раз ресанешь - нет.
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ИС-пытатель писал(а):да, я поделил тактовую частоту контроллера на 8. А потом для таймера и АЦП поделил ее еще раз на 8. Предделитель таймера и АЦП делят тактовую чатоту после предделителя CPU, а не ту, которая приходит на него. 128 там тактов.
:facepalm: Да, тут я дал маху, извините. Не использовал этот делитель (CLKPR) ни разу.
ИС-пытатель писал(а):А еще в 2560 при баге бывает фича, когда в обработчике от АЦП после инкремента переменной добавляешь nop и она начинает считать. Но она как-то через раз работает. Бывает ресанешь - работает. второй раз ресанешь - нет.
Что, IMHO, говорит о ситуации типа "race condition" - проблемы с последовательностью событий, с последовательностью доступа/модификации данных. В случае с МК это связано с прерываниями и независимой работой периферии. Чего-то не учли.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Ну, воооот! ))
Kavka писал(а):
:facepalm: Да, тут я дал маху, извините. Не использовал этот делитель (CLKPR) ни разу.
Учите мат.часть! :))) :))) :)))

P.S. А вообще, с Вами приятно было пообщаться. ) Вы действительно хорошо проанализировали код (даже нашли несколько помарок :oops: )и не выдавали версий наугад. ) Спасибо Вам! )
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ИС-пытатель писал(а):Учите мат.часть! :))) :))) :)))
Ну, собственно, что и сделал. Смотри подпись. :)
Вам бы отладку через JTAG погонять - может что-нибудь удастся поймать.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Ой, если честно сейчас не до этого. Проблем по горло. Тем более что c JTEG не работал ни разу. Пойду учить мат. часть! :)))
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Так заработало или пока решили оставить эту проблему?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Как я понял, это не проблема, а чисто академический интерес.
Мудрый кот
Аватара пользователя
Сообщения: 1811
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение 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:
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Ответить

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