|
Конфликт флагов прерываний SREG- TCCR1A. |
|
|
|
Jun 5 2011, 04:03
|
Группа: Новичок
Сообщений: 8
Регистрация: 5-06-11
Пользователь №: 65 486

|
Конфликт флагов прерываний SREG- TCCR1A. Установлено ПО: WinAVR-20100110, AvrStudio418Setup+ AVRStudio4.18SP1. Программа на AVR GCC. При загрузке регистр TCCR1A=0x02. Последней операцией идёт разрешение прерываний SREG|=(1<<SREG_I);. Пробовал и SREG=0x80; - результат один и тот же: одновременно с флагом I (7-й разряд) устанавливается так же 7-й разряд в TCCR1A. И результат становится TCCR1A=0x82. Кто-нибудь сталкивался с такой проблемой? И как она решается? На форуме уже обсуждался аналогичный вопрос с взаимовлияниями TCCR1A и SREG, но я не понял решения и ситуация там была с выходом из программы, а не во время загрузки. В загрузке я после установки SREG добавил TCCR1A=0x02; - это помогло. Но как этот дефект скажется во время работы программы? Опасаюсь.
|
|
|
|
|
Jun 5 2011, 06:40
|
Местный
  
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140

|
Даташит: Цитата The I-bit can also be set and cleared by the application with the SEI and CLI instructions
|
|
|
|
|
Jun 6 2011, 02:00
|
Группа: Новичок
Сообщений: 8
Регистрация: 5-06-11
Пользователь №: 65 486

|
Цитата(Палыч @ Jun 5 2011, 13:59)  Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A. В силу обстоятельств программу из Ассемблера пришлось переделывать на СИ (AVR GCC). В варианте Ассемблера такого небыло никогда. Программа тупо переделана на СИ. Т.е., порядок загрузок и инициализаций, а также все процедуры. Потому и удивляет такая ситуация. Был у меня эпизод с незаписью ЕЕПРОМ. Оказалось, что это дефекты старой версии, потому я и указал установленные версии. Я перед операцией SREG|=(1<<SREG_I); записал значения TCCR1A и сразу после неё. Именно после установки I происходит запись в TCCR1A. Т.е., вроде прерывания не успевают отработать. Поэтому, складывается впечатление, что запись в 7-й разряд SREG и TCCR1A происходит одновременно.
|
|
|
|
|
Jun 6 2011, 04:48
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(ARV @ Jun 6 2011, 08:38)  поэтому оператор SREG|=(1<<SREG_I); выполняется неатомарно, что может давать странные эффекты. Практически исключено (может кроме нулевого уровня оптимизации). SREG в SFR области и такой код превратится в атомарные инструкции SBI и CBI. Хотя нет я погорячился. SBI и CBI адресуют лишь 32 байта, а SREG за этой границей. Так что очистка-установка битиков регистра SREG по маске в общем случае - неатомарная операция. Также стоит покопать в сторону: Цитата(Палыч @ Jun 5 2011, 10:59)  Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 6 2011, 05:47
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(demiurg_spb @ Jun 6 2011, 07:48)  Хотя нет я погорячился. SBI и CBI адресуют лишь 32 байта, а SREG за этой границей. Так что очистка-установка битиков регистра SREG по маске в общем случае - неатомарная операция. Вы так больше не пугайте  Код sei/cli set/clt sev/clv sen/cln sez/clz sec/clc - что еще забыл? Да и ладно - смысл и так понятен - это атомарные операции.
|
|
|
|
|
Jun 6 2011, 05:56
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(_Pasha @ Jun 6 2011, 09:47)  Код sei/cli set/clt sev/clv sen/cln sez/clz sec/clc - что еще забыл? Все остальные инструкции AVR:)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 6 2011, 10:22
|
Группа: Новичок
Сообщений: 8
Регистрация: 5-06-11
Пользователь №: 65 486

|
Цитата(Палыч @ Jun 6 2011, 12:20)  Хорошо бы узнать: отчего у Вас такое "складывается впечатление"? Каким образом, каким средством Вы проверяете выполнение программы? Симулятор? В "железе"? Как смотрите? Что получаете?
P.S. Хорошо бы было, если бы Вы сообщили: какой AVR применяете? В самом первом своём сообщении я перечислил ПО. Могу повторить: Установлено ПО: WinAVR-20100110, AvrStudio418Setup+ AVRStudio4.18SP1. Программа на AVR GCC. Выполнение программы проверяю на железе. В ячейку памяти пишу данные до операции, в другую - после. Потом читаю данные ячеек через интерфейс. В эти ячейки ничего попасть не может чужого. Вот так: mem1=TCCR1A; SREG|=(1<<SREG_I); mem2=TCCR1A; В результате получаю: mem1=0x02, mem2=0x82. При отладке всегда так делаю. И всегда помогало. И сейчас помогло, когда я догадался, что в этом месте порча регистра TCCR1A. Может, я где-то неправ? Неужели между SREG|=(1<<SREG_I); и mem2=TCCR1A; программа успевает что-то сделать? Вроде логично - может. Но в таком случае как правильно инициализировать TCCR1A и флаг I, чтобы не происходила эта чепуха. Причём, если я не сделаю перед циклом SREG|=(1<<SREG_I);, прерывания не работают вообще, так что сам флаг не устанавливается.
|
|
|
|
|
Jun 7 2011, 03:53
|
Группа: Новичок
Сообщений: 8
Регистрация: 5-06-11
Пользователь №: 65 486

|
Цитата(VladislavS @ Jun 6 2011, 18:12)  1. Смотри ассемблерный код. Чудес не бывает. 2. Использовать sei() и cli() религия не позволяет? sei() и cli() религия позволяет. Пробовал. Но на старой версии 2006. Там их нет, ПО ругалось. В новой версии 2010 не попробовал, считал что будет также. Но попробую. Цитата(Палыч @ Jun 6 2011, 19:33)  Закоментируйте всё до приведенной Вами конструкции (сохранение в памяти регистров и глобальное разрешение прерываний). Сравните сохраненные значения, если они равны, то вставляйте частями закоментированные куски... Ищите где происходит "бяка". Спасибо, попробую. Но я думал, что кто-нибудь уже сталкивался с этим. Ведь была же ошибка при записи в ЕЕПРОМ. Я по рекомендации обновил версии и эта ошибка исчезла. А с конфликтом этих регистров - может у них опять ошибка?
|
|
|
|
|
Jun 7 2011, 04:28
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(mogikanin @ Jun 7 2011, 07:53)  sei() и cli() религия позволяет. Пробовал. Но на старой версии 2006. Там их нет, ПО ругалось. В новой версии 2010 не попробовал, считал что будет также. Но попробую. На любой версии есть. Код #include <avr/interrupt.h> Цитата(mogikanin @ Jun 7 2011, 07:53)  Ведь была же ошибка при записи в ЕЕПРОМ. Это не ошибка, а особенность. И никуда ничего не делось и не исправилось. Просто включайте brown-out detector и всё. Цитата(mogikanin @ Jun 7 2011, 07:53)  может у них опять ошибка? У кого у них? В 99,9% ошибка у Вас в голове...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|