Зарегистрирован: Пн мар 07, 2016 14:25:07 Сообщений: 8
Рейтинг сообщения:0
Добрый день. Возникла проблема. Сначала кратко. Есть 2 Atmeg8, которые соединены так, чтобы мастер передавал данные к слейву. Сама проблема - слейв не записывает принятые данные в регистр SPDR. Теперь подробно. На изображениях ниже приведена схема в протеусе и настройки самих микроконтроллеров., . Далее, приведен код прошивки каждого из устройств. Мастер (U1):
. Привожу фотку, на которой показана передача данных, а так же факт того, что данные не записываются в регистр SPDR (U2) - . Прошу помочь понять на каком этапе я ошибаюсь, чтобы исправить проблему. Заранее спасибо!
При окончании приема данных в регистре SPSR выставляется флаг SPIF. В блоке инициализации перед работой с SPI этот флаг нужно сбрасывать записывая в него 1 (даташит). В программе проверяем этот флаг. Если установлен, сбрасываем флаг, считываем содержимое. Если включаем прерывание, то этот флаг сбрасывается аппаратно при входе в прерывание. volatile в вашем случае не обязательно. Можно объявить переменную как extern, но применение глобальных переменных рекомендуется минимизировать. Можно объявить как static. Но нужно учитывать, что static - локальная переменная, и применяется только в своем программном модуле (файле, если программа разбита на модули-файлы). В вашем случае все в одном файле-простыне, так что можно.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Demiurg писал(а):
В блоке инициализации перед работой с SPI этот флаг нужно сбрасывать
Необходимости в этом никакой нет, если инициализация происходит после сброса МК.
Demiurg писал(а):
нужно сбрасывать записывая в него 1 (даташит).
Это в каком ДШ так написано?
Demiurg писал(а):
volatile в вашем случае не обязательно.
Человеку надо было посмотреть что принял МК. Регистр SPDR, по факту буферный на сколько я знаю, чтобы в него попали данные из сдвигового регистра надо его прочитать. Протеус , опять же скорее всего, не отображал принятые данные из сдвигового регистра, кроме того это всего-лишь симулятор. А так как переменная была выкинута оптимизатором, то по факту с регистра ничего не читалось.
Demiurg писал(а):
Можно объявить переменную как extern,
Приведите пример, касательно исходника ТС. Лично я не понял как это.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
volatile в вашем случае не обязательно. Можно объявить переменную как extern
volatile != extern volatile означает, что переменная может измениться в любой момент, и поэтому её нельзя никак кэшировать extern означает лишь объявление переменной где-то в другом модуле, т.е. эта переменная подлежит кэшированию.
в выражении a = b + b + b + b; при extern b компилятор имеет полное право сделать a = b << 2 (для оптимизации по скорости или размеру; более того, если b уже была где-то выше по тексту помещена в промежуточный регистр, все действия компилятор может делать именно с этим регистром), в то время как при volаtile b он не только сложит 4 раза, но и перед каждым сложением будет считывать содержимое соответствующих ячеек памяти.
то есть если предположить, что переменная b=0 инкрементируется в прерывании с очень большой скоростью, с extern вы получите, допустим, 0, а с volatile получите 6.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Необходимости в этом никакой нет, если инициализация происходит после сброса МК.
При работе устройства МК может сброситься (теоретически). Поэтому при работе с периферией этот момент нужно учитывать всегда. Также при работе с периферией нужно учитывать, что в одном регистре ввода-вывода могут висеть несколько периферийных модулей. Есть непосредственная запись значения. Также есть чтение-модификация-запись. Здесь могут быть различные варианты инициализации периферийных модулей. С непосредственной записью значений все понятно. Пусть даже МК сбросился и в регистрах ввода-вывода непонятная каша, мы все равно записываем нужные данные, сбрасывая ненужные биты и выставляя нужные. С вариантом чтение-модификация-запись посложнее. Берем для примера регистр TIMSK. В нем настройка нескольких таймеров. И если у нас работают несколько таймеров, то порядок инициализации в программе должен быть следующий: инициализируем первый таймер (порядок не аппаратный, а по проекту) - непосредственная запись. Инициализация следующих таймеров уже по варианту чтение-модификация-запись. Иначе, если мы будем делать непосредственную запись, мы похерим настройки предыдущего таймера. Но представим следующую ситуацию. МК нештатно сбросился, в регистре каша, а мы делаем чтение-модификация-запись. Сами понимаете, что в этом случае программа будет работать некорректно.
Z_h_e писал(а):
Demiurg писал(а):
нужно сбрасывать записывая в него 1 (даташит).
Это в каком ДШ так написано?
Так как флаги аппаратно сбрасываются при соответствующих включенных прерываниях, то сброс соответствующих флагов при непосредственном опросе - обязанность программиста. При инициализации периферии в таком режиме сброс соответствующих флагов - также обязанность программиста. Во избежание некорректной работы программы.
Z_h_e писал(а):
Demiurg писал(а):
Можно объявить переменную как extern
Приведите пример, касательно исходника ТС. Лично я не понял как это.
Позже, я на работе.
Компилятор выкинул letter по простой причине: эта переменная больше нигде не используется. Да, объявляя ее volatile, вы заставили компилятор не выкидывать соответствующий кусок кода. Но зная, как ведет себя тот компилятор, с которым вы работаете, можете варьировать свою программу при работе с переменными.
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Demiurg писал(а):
...МК нештатно сбросился, в регистре каша, а мы делаем чтение-модификация-запись. ...
Та же чушь, как и про случайные прерывания вдругом топике. Если МК сбросился, значит регистры переинициализированы МК аппаратно.
Demiurg писал(а):
то сброс соответствующих флагов при непосредственном опросе - обязанность программиста.
Я не спрашивал зачем сбрасывать. Вы говорите что сброс данного флага производится записью 1 и ссылаетесь на ДШ. В каком ДШ это написано?
Добавлено after 4 minutes 52 seconds:
Demiurg писал(а):
Да, объявляя ее volatile, вы заставили компилятор не выкидывать соответствующий кусок кода.
Вы невнимательно прочитали вопрос ТС и мое объяснение почему так вышло. ТС не видел принятых данных, наблюдая за регистром SPDR (а на самом деле они были и все работало и так).
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
ТС не видел принятых данных, наблюдая за регистром SPDR
Та же песня и с SDR для USART: протеус (и, если не ошибаюсь, даже студия) не понимает, какое содержимое "двойного" регистра показывать при отладке - то, которое было записано из кода, или то, которое было записано из аппаратуры.
почему разработчики симуляторов не дотумкали отображать сдвоенный регист в виде двух "теневых" - не понятно...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
1 - Я не собираюсь с вами спорить. Это ваши проекты. Что хотите, то и делайте. Ваша ответственность. 2 - Откройте даташит на любой AVR, раздел SPI, сводка регистров, флаг SPIF. Там все увидите.
Цитата:
Bit 7 – SPIF0: SPI Interrupt Flag When a serial transfer is complete, the SPIF Flag is set. An interrupt is generated if SPIE in SPCR is set and global interrupts are enabled. If SS is an input and is driven low when the SPI is in Master mode, this will also set the SPIF Flag. SPIF is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, the SPIF bit is cleared by first reading the SPI Status Register with SPIF set, then accessing the SPI Data Register (SPDR).
3 - Нужно смотреть листинг кода. Либо прогонять программу в симуляторе AVR-Studio. Это товарищ еще неопытный, потому еще и не знает куда смотреть, чтобы понять, что вообще происходит.
Йопт. Походу не совсем еще проснулся. Так, действительно флаг SPIF сбрасывается при чтении SPDR. Но, при ПЕРВОМ чтении! То есть, может быть ситуация, когда флаг нужно сбрасывать. Написал про сброс статусных флагов по привычке, статусные флаги нужно сбрасывать записью в них 1. Так что не совсем ересь. Вы лучше сразу уточняйте в следующий раз. Чем сходу обвинять в ереси.
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Кстати, alarig1995A, Вы молодец и правильно задали свой вопрос. Выложили именно то, что нужно, чтобы получить ответ. Обычно вопросы задают, так что без спиритического сеанса ничего не понятно.
Добавлено after 4 minutes 5 seconds:
Demiurg писал(а):
Так, действительно флаг SPIF сбрасывается при чтении SPDR. Но, при ПЕРВОМ чтении!
Опять неверно. А так как Вы профессионал, объяснять не буду.
Demiurg писал(а):
Вы лучше сразу уточняйте в следующий раз. Чем сходу обвинять в ереси.
Я бы сразу написал, но так уверенно на ДШ ссылались. Но это мелочь в целом. А вот случайные какие-то сбросы МК приводящие к случайным состояниям...
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Должна быть таблица регистров ввода-вывода, сбрасываемых аппаратно при сбросе. Притом должно быть уточнение, по какой причине был сброс. Не могу найти. Я занят, был бы признателен, если вы знаете, где есть такие таблицы. Либо текстовое указание диапазона адресов регистров ввода-вывода, сбрасываемых аппаратно при сбросе.
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Причину сброса выяснить можно, вот для той же меге8 Спойлер
Добавлено after 5 minutes 43 seconds:
Demiurg писал(а):
Должна быть таблица регистров ввода-вывода, сбрасываемых аппаратно при сбросе.
Я не встречал такого. Может есть конечно где. У STM есть такие, только они не обобщенные для всех, а только для конкретной каждой периферии. Но я ими не пользуюсь, по-моему все равно надо смотреть описание каждого регистра отдельно, а на память свою я давно не полагаюсь, очень она у меня ненадежная .
Про initial value забыл. Помню, что где-то была информация, какое значение в регистре при сбросе. Про флаги причины сброса можно было не писать. Кстати, в последней же вашей приведенной картинке указано, что сброс флагов запись 1-цы в соответствующий бит. Я из этого исходил, когда говорил про это. Написал по привычке. Тут есть один нюанс с регистрами ввода-вывода. Часть регистров лежит в определенной области. Начиная с определенного адреса обычными командами до этих регистров не добраться, только через lds-sts.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения