mogikanin 0 5 июня, 2011 Опубликовано 5 июня, 2011 · Жалоба Конфликт флагов прерываний 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; - это помогло. Но как этот дефект скажется во время работы программы? Опасаюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 5 июня, 2011 Опубликовано 5 июня, 2011 · Жалоба Даташит: The I-bit can also be set and cleared by the application with the SEI and CLI instructions Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 11 5 июня, 2011 Опубликовано 5 июня, 2011 · Жалоба одновременно с флагом I (7-й разряд) устанавливается так же 7-й разряд в TCCR1A. Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mogikanin 0 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A. В силу обстоятельств программу из Ассемблера пришлось переделывать на СИ (AVR GCC). В варианте Ассемблера такого небыло никогда. Программа тупо переделана на СИ. Т.е., порядок загрузок и инициализаций, а также все процедуры. Потому и удивляет такая ситуация. Был у меня эпизод с незаписью ЕЕПРОМ. Оказалось, что это дефекты старой версии, потому я и указал установленные версии. Я перед операцией SREG|=(1<<SREG_I); записал значения TCCR1A и сразу после неё. Именно после установки I происходит запись в TCCR1A. Т.е., вроде прерывания не успевают отработать. Поэтому, складывается впечатление, что запись в 7-й разряд SREG и TCCR1A происходит одновременно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ARV 1 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба если вы "тупо" переделали программу на Си, не исключено, что внесли при этом ряд ошибок. в частности, с SREG-ом в WinAVR напрямую работать нужды почти никогда не возникает, т.к. для разрешения и запрещения прерываний имеются макросы sei() и cli(). все периферийные регистры в WinAVR объявлены как volatile-переменные, поэтому оператор SREG|=(1<<SREG_I); выполняется неатомарно, что может давать странные эффекты. используйте правильные средства - будет правильный результат. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба поэтому оператор SREG|=(1<<SREG_I); выполняется неатомарно, что может давать странные эффекты.Практически исключено (может кроме нулевого уровня оптимизации). SREG в SFR области и такой код превратится в атомарные инструкции SBI и CBI. Хотя нет я погорячился. SBI и CBI адресуют лишь 32 байта, а SREG за этой границей. Так что очистка-установка битиков регистра SREG по маске в общем случае - неатомарная операция. Также стоит покопать в сторону: Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 11 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба ...складывается впечатление, что запись в 7-й разряд SREG и TCCR1A происходит одновременно.Хорошо бы узнать: отчего у Вас такое "складывается впечатление"? Каким образом, каким средством Вы проверяете выполнение программы? Симулятор? В "железе"? Как смотрите? Что получаете? P.S. Хорошо бы было, если бы Вы сообщили: какой AVR применяете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба Хотя нет я погорячился. SBI и CBI адресуют лишь 32 байта, а SREG за этой границей. Так что очистка-установка битиков регистра SREG по маске в общем случае - неатомарная операция. Вы так больше не пугайте :) sei/cli set/clt sev/clv sen/cln sez/clz sec/clc - что еще забыл? Да и ладно - смысл и так понятен - это атомарные операции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба sei/cli set/clt sev/clv sen/cln sez/clz sec/clc - что еще забыл? Все остальные инструкции AVR:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mogikanin 0 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба Хорошо бы узнать: отчего у Вас такое "складывается впечатление"? Каким образом, каким средством Вы проверяете выполнение программы? Симулятор? В "железе"? Как смотрите? Что получаете? 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);, прерывания не работают вообще, так что сам флаг не устанавливается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба 1. Смотри ассемблерный код. Чудес не бывает. 2. Использовать sei() и cli() религия не позволяет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 11 6 июня, 2011 Опубликовано 6 июня, 2011 · Жалоба Закоментируйте всё до приведенной Вами конструкции (сохранение в памяти регистров и глобальное разрешение прерываний). Сравните сохраненные значения, если они равны, то вставляйте частями закоментированные куски... Ищите где происходит "бяка". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mogikanin 0 7 июня, 2011 Опубликовано 7 июня, 2011 · Жалоба 1. Смотри ассемблерный код. Чудес не бывает. 2. Использовать sei() и cli() религия не позволяет? sei() и cli() религия позволяет. Пробовал. Но на старой версии 2006. Там их нет, ПО ругалось. В новой версии 2010 не попробовал, считал что будет также. Но попробую. Закоментируйте всё до приведенной Вами конструкции (сохранение в памяти регистров и глобальное разрешение прерываний). Сравните сохраненные значения, если они равны, то вставляйте частями закоментированные куски... Ищите где происходит "бяка". Спасибо, попробую. Но я думал, что кто-нибудь уже сталкивался с этим. Ведь была же ошибка при записи в ЕЕПРОМ. Я по рекомендации обновил версии и эта ошибка исчезла. А с конфликтом этих регистров - может у них опять ошибка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 7 июня, 2011 Опубликовано 7 июня, 2011 · Жалоба sei() и cli() религия позволяет. Пробовал. Но на старой версии 2006. Там их нет, ПО ругалось. В новой версии 2010 не попробовал, считал что будет также. Но попробую.На любой версии есть.#include <avr/interrupt.h> Ведь была же ошибка при записи в ЕЕПРОМ.Это не ошибка, а особенность. И никуда ничего не делось и не исправилось. Просто включайте brown-out detector и всё. может у них опять ошибка?У кого у них? В 99,9% ошибка у Вас в голове... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 7 июня, 2011 Опубликовано 7 июня, 2011 · Жалоба А с конфликтом этих регистров - может у них опять ошибка? Дядя, листинг в студию. И фсё тут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться