Перейти к содержанию
    

Конфликт флагов прерываний SREG- TCCR1A.

Конфликт флагов прерываний 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; - это помогло. Но как этот дефект скажется во время работы программы? Опасаюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

одновременно с флагом I (7-й разряд) устанавливается так же 7-й разряд в TCCR1A.

Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если вы "тупо" переделали программу на Си, не исключено, что внесли при этом ряд ошибок.

в частности, с SREG-ом в WinAVR напрямую работать нужды почти никогда не возникает, т.к. для разрешения и запрещения прерываний имеются макросы sei() и cli(). все периферийные регистры в WinAVR объявлены как volatile-переменные, поэтому оператор SREG|=(1<<SREG_I); выполняется неатомарно, что может давать странные эффекты.

 

используйте правильные средства - будет правильный результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

поэтому оператор SREG|=(1<<SREG_I); выполняется неатомарно, что может давать странные эффекты.
Практически исключено (может кроме нулевого уровня оптимизации). SREG в SFR области и такой код превратится в атомарные инструкции SBI и CBI.

Хотя нет я погорячился. SBI и CBI адресуют лишь 32 байта, а SREG за этой границей. Так что очистка-установка битиков регистра SREG по маске в общем случае - неатомарная операция.

 

Также стоит покопать в сторону:

Вероятнее всего, что как только Вы разрешили прерывания глобально (бит I в SREG), то какое-то прерывание тут же и случилось... В процедуре обработки этого прерывания был установлен 7-ой бит регистра таймера TCCR1A.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...складывается впечатление, что запись в 7-й разряд SREG и TCCR1A происходит одновременно.
Хорошо бы узнать: отчего у Вас такое "складывается впечатление"? Каким образом, каким средством Вы проверяете выполнение программы? Симулятор? В "железе"? Как смотрите? Что получаете?

 

P.S. Хорошо бы было, если бы Вы сообщили: какой AVR применяете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотя нет я погорячился. SBI и CBI адресуют лишь 32 байта, а SREG за этой границей. Так что очистка-установка битиков регистра SREG по маске в общем случае - неатомарная операция.

Вы так больше не пугайте :)

sei/cli set/clt sev/clv sen/cln sez/clz sec/clc

- что еще забыл? Да и ладно - смысл и так понятен - это атомарные операции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sei/cli set/clt sev/clv sen/cln sez/clz sec/clc

- что еще забыл?

Все остальные инструкции AVR:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо бы узнать: отчего у Вас такое "складывается впечатление"? Каким образом, каким средством Вы проверяете выполнение программы? Симулятор? В "железе"? Как смотрите? Что получаете?

 

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);, прерывания не работают вообще, так что сам флаг не устанавливается.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Смотри ассемблерный код. Чудес не бывает.

2. Использовать sei() и cli() религия не позволяет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Закоментируйте всё до приведенной Вами конструкции (сохранение в памяти регистров и глобальное разрешение прерываний). Сравните сохраненные значения, если они равны, то вставляйте частями закоментированные куски... Ищите где происходит "бяка".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Смотри ассемблерный код. Чудес не бывает.

2. Использовать sei() и cli() религия не позволяет?

sei() и cli() религия позволяет. Пробовал. Но на старой версии 2006. Там их нет, ПО ругалось. В новой версии 2010 не попробовал, считал что будет также. Но попробую.

 

Закоментируйте всё до приведенной Вами конструкции (сохранение в памяти регистров и глобальное разрешение прерываний). Сравните сохраненные значения, если они равны, то вставляйте частями закоментированные куски... Ищите где происходит "бяка".

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sei() и cli() религия позволяет. Пробовал. Но на старой версии 2006. Там их нет, ПО ругалось. В новой версии 2010 не попробовал, считал что будет также. Но попробую.
На любой версии есть.
#include <avr/interrupt.h>

Ведь была же ошибка при записи в ЕЕПРОМ.
Это не ошибка, а особенность. И никуда ничего не делось и не исправилось. Просто включайте brown-out detector и всё.

может у них опять ошибка?
У кого у них?

В 99,9% ошибка у Вас в голове...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А с конфликтом этих регистров - может у них опять ошибка?

Дядя, листинг в студию. И фсё тут.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...