Обсуждаем контроллеры компании Atmel.
Ответить

Проблема с Atmega328P

Вс сен 05, 2021 11:44:49

Делаю ребёнку игрушку с часами.
Может кто сталкивался. Задача простейшая: считывание данных по I2C c DS1307 с использованием прерываний TWI. В алгоритме чтения используется повторный старт. Последовательные коды на входе прерывания в регистре статуса TWSR при использовании алгоритма с повторным стартом должны быть : 08 18 28 10 40 58. У меня же не формируется код 10. Последовательность получается 08 18 28 28. Причём, если контроллер стартует после записи программатором - всё работает как должно. Если контроллер стартует после включения питания - происходит вышеописанная ситуация. Пока проект в стадии исследования - не всё что хотел сделал. Используются ds1307, графический индикатор 12864B Ver/ 2.0 на базе контроллера ST7920, и соответственно, - atmega 328p с внешним кварцем на 16Мгц.
Может кто сталкивался с похожей проблемой? Куда копать ? Программатор простейший на LPT с использованием 74HC244. К нему вопросов никогда не было.
Вложения
test1.zip
(10.26 KiB) Скачиваний: 240

Re: Проблема с Atmega328P

Ср сен 08, 2021 09:53:48

Первое замечание - выведите знакогенератор в отдельную ЕЕЕПРОМку (или в отдельный файл проекта).
Для работ под ассемблером мега328Р жирновата (надо полную распечатку даташита под рукой иметь да хорошо проработать).
Относительно I2C у 1307...
Следует учесть, что данные могут начинаться "лидирующим нулем" (алгоритмы контроля ACK при рестрате).
У меня для 1307 только программный "ногодрыг" всегда применялся - зачем еще аппаратный модуль под такое дело использовать?.
:roll:

Re: Проблема с Atmega328P

Ср сен 08, 2021 20:42:51

Согласен с бобом. Когда сам раскладываешь пакет по полочкам - всё заводится без проблем. А вот с этим аппаратным TWI чёрт ногу сломит.

Re: Проблема с Atmega328P

Ср сен 08, 2021 21:11:39

у меня на АТмега8 с TWI аппаратным вообще нет проблем.

Re: Проблема с Atmega328P

Ср сен 08, 2021 21:37:07

мега8 значительно проще того, что в 328Р наворочено...
:roll:

Re: Проблема с Atmega328P

Ср сен 08, 2021 21:41:13

так выложи коды-пароли

Re: Проблема с Atmega328P

Чт сен 09, 2021 09:06:04

У меня же не формируется код 10.

Добрый день. В программировании не спец, ради интереса глянул Ваш код. Каким образом после отправки байта в "twi_28_w_3" должно перейти на рестарт? У меня, по обнулению счетчика передаваемых байтов, проверяется счетчик принимаемых - есть байты на прием, переходим опять на старт, без стопа. Т.е. заново ldi temp, 1<<TWINT|(1<<TWSTA)|(1<<TWEN)|1<<TWIE
out TWCR, temp ; условия для состояния СТАРТ

Re: Проблема с Atmega328P

Пт сен 10, 2021 17:51:20

Спасибо всем. Я заставил работать 328 мегу с DS1307. Знакогенератор, понятно вынесу в отдельный eeprom. Пока он болтается в оснаном коде чтобы не было лишних обращений по TWI шине.
Так же я добился работы со второй mega8L сидящей на этой же шине. По отдельности обе процедуры работают. Не удаётся корректно переключиться в Режим TWI slave receiver. Ситуация следующая: если 328 мегу иницилизировать в режим slave-receiver сразу, а в режим master не пытаться перейти - код работает корректною 328 проходит через состояния автомата TWI 60б 80б А0. На мастере (mega8L) TWI проходит состояния 08б 18, 28. Данные передаются. Далее у неё цикл повторяется . Всё работает корректно. Вторпй вариант - mega328 инициализируется мастером для чтения данных из DS1307/ Здесь мега проходит состояния 08 18 28 10 40 58 - т.е. работа через повторный старт с переходом в master-receiver. Вообще идея была такая - 1.опросить регистры ds1307, 2. вывод на экран, далее назад в Пункт 1. Кроме того - после опроса ds1307 переключить Мегу 328 в режим slave-receiver чтобы пока экран выводится она смогла принять данные с mega 8L. далее по началу цикла она должна переключиться в mfster-transmitter.
В коде для mega 328 то что закоментированно восклицательными знаками, если раскоментировать - получится вариант (причём работающий) "slave-receiver". Есди оставить закомментированным - будет вариант master - transmitter для чтения из ds 1307 через повторный старт регистров ds1307. То что помечено знаками вопроса (?) должно переключить мегу з28 в режим slave - receiver. Это тот же самый кусок кода который выше помечен был восклицательными знаками и в одиночку сам по себе работал. Причем если его закомментить, вторая мега8, которая всё время пытается достучаться до слейва нормально проходит по состояниям 08, 20, далее опять, 08, 20 и т.д. Ну не отвечает ей мега 328, не входит в режим slave-receiver. Ежели этот кусок кода оставить без комментариев (подключить) то mega 8L (ЕЦШ автомат) вешается. после состояния 20. Дальнейших попыток достучаться не наблюдается. Отдельные извинения - у меня старая AVR Studio - она курочит табуляцию и с русским языком не дружит.
Так же есть одна ещё непонятка: в обработчике статусного кода TWI 0x58 в даташите явно не указывается какое значение нужно грузить в TWCR для флага TWEN. Если грузить 1, то по осциллографу видно что SCL между циклами виснет в "0". Если писать 0 - то тогда на SCL - лог. 1. Вопрос на сколько это правильно И почему в случае когда ставлю (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(0<<TWEA)|(0<<TWSTA)|(1<<TWSTO)|(0<<TWWC) шина не релизится , хотя TWSTO = 1 ?
Вложения
sources.zip
исходники здесь
(16.62 KiB) Скачиваний: 141

Re: Проблема с Atmega328P

Сб сен 11, 2021 16:01:24

Была у меня меня мега, пока игрался i2c сдох, заменил мегу.
Возможно можно както програмно приделать 1307, но это не мой уровень

Re: Проблема с Atmega328P

Вс сен 12, 2021 23:11:09

Ну в общем, заставил я работать Mega328p в режиме Master и в режиме Slave. Вернее, как правильно переключиться из режима мастера в слейв и обратно. У меня 328-я мастером читает по одному регистры ds1307, потом переключается в слейв и начинает принимать запросы (цикл передачи одного байта) от mega8L. Параллельно работая слейвом она выводит прочитанные данные на LCD дисплей на базе ST7920 (128X64 пикселей). После того как вывод на дисплей закончится, цикл повторяется. В даташите ничего нет о том как переключить в слейв модуль TWI. Есть несколько переходов в неадресуемый слейв из некоторых состояний автомата TWI в процессе передачи . Но ничего нет о том как это сделать из основного кода а не из обработчика прерываний TWI. В общем случае, если после сброса NWI инициализируется слейвом, то в TWCR пишется следующее:
ldi r16, THIS_SLAVE_ADDRES
uout TWAR, r16
ldi r16,0x45
uout TWCR, r16
Далее автомат готов к приему входящих последовательностей по шине в режиме прерываний.

Тоже самое надо выдавать для перехода в режим слейва после работы мастером.
У меня режимы переключаются обработчиком таймера по флажку TWI_BUSY. Если TWI_BUSY = 0 включится режим мастера, Если TWI_BUSY=6 включится режим слейва на прием.
Текст прилагается. Может кому пригодится. Там надо дописать арбитраж.
Вложения
mega328p_v2.zip
(11.15 KiB) Скачиваний: 123

Re: Проблема с Atmega328P

Пн сен 13, 2021 09:31:33

В программировании есть прием - "условный возврат" - или из прерывания, или из подпрограммы (даже если в наборе команд нет явно определенных спецкоманд на такой случай).
Как организовать - это уже в зависимости от используемых ресурсов и текущих задач.
Часто стек используется и/или дополнительный буфер/указатель адреса.
8)

Re: Проблема с Atmega328P

Чт сен 16, 2021 17:44:51

Приемов много разных есть. Я специально использую ограниченный набор инструкций для читаемости кода. Не использую ничего кроме BREQ, BRNE, CPI, LD, LDS и т.п. "явных" инструкций. Стараюсь использовать линейные конструкции там где это только возможно. Экономия памяти на современном железе как правило не требуется. Бывают узкие места где не обойтись без оптимизации по быстродействию. Но, обычно, если таковое требуется применять, - следует подумать о переходе на более производительное железо, если это возможно.
С- и прочие языки высокого уровня недолюбливаю . Ибо иногда отладка превращается в реверс-инженеринг а-ля " А чего-й то нам там родил компилятор и как это работает". Хотя и могу на них писать свободно без проблем всё что угодно. Хоть на С, хоть на С++, хоть на С#.

Добавлено after 24 minutes 15 seconds:
Про флаги.
read_ds1307_register:



sts NUMBER_REGISTER_TO_READ, r16

twi_rd_free_wait_1:

cli

lds r16, TWI_BUSY
cpi r16, 0
breq twi_rd_free_wait_2
sei
jmp twi_rd_free_wait_1

twi_rd_free_wait_2:


ldi r16, DS1307_I2C_ADDRES
sts I2C_DEVICE_ADDRES, r16
ldi r16,1
sts TWI_BUSY, r16

sei

ret
Флажёк занятости TWI (у меня TWI_BUSY) должен опрашиваться и изменяться атомарно. Поэтому в примере выше такое хитропопое расположение инструкций CLI и SEI. Это то о чём все всегда забывают. А потом жалуются что всё работает с глюками :( . Любые флаги которые используются для изменения логики работы любого обработчика прерывания должны читаться-модифицироваться-сохранятся атомарно (с запрещёнными прерываниями), но при этом фоновые по отношению к текущему процессы не должны вешаться наглухо. Именно для этого в коде стоит первая по текстк инструкция SEI (в части которая занимается опросом флага перед его модификацией).

Re: Проблема с Atmega328P

Чт сен 16, 2021 19:28:29

У меня для связи между двумя МК (как разных семейств так и разного быстродействия в одном проекте) простой программный обмен с побитовой синхронизацией - ничему не мешает.
Единственно три линии задействованы - но в SPI в принципе столько же.
Не слишком шустро - но допускается хоть полная остановка на неопределенное время.
8)

Re: Проблема с Atmega328P

Пт сен 17, 2021 02:59:49

Следующая версия для Mega328p. Упорядочен обработчик прерывания TWI и коды состояния автомата TWI_BUSY.
Модифицирован следующий кусок кода (обработчик кода статуса A0):

twi_slave_r_A0:

ldi r16, 6
sts TWI_BUSY, r16
ldi r16, 0x85 ;(1<<TWINT)|(0<<TWEA)|(0<<TWEN)|(0<<TWIE) ;stop has been received,
uout TWCR,r16

jmp L_TWSI_END

ранее было:

twi_slave_r_A0:

ldi r16, 6
sts TWI_BUSY, r16
ldi r16, 0xC5 ;(1<<TWINT)|(1<<TWEA)|(0<<TWEN)|(0<<TWIE) ;stop has been received,
uout TWCR,r16

jmp L_TWSI_END

Разница в TWEA, признак говорящий автомату TWI надо ли далее реагировать на собственный SLA+W или нет. Видимо, сразу нельзя. Теперь данное разрешение устанавливается в части кода которая обрабатывает состояние TWI_BUSY = 6.
После модернизации пропали подвисания автомата через 5-6 минут работы. В даташите по этому поводу, как обычно, ровно ничего кроме констатации что можете сделать либо так, либо этак :( .
Далее будет производится тестирование имеющегося кода mega328p и будет доработка кода mega8L. Там радо дописать в обработчике мастера работу с кодами арбитража и нот акнолиджами со стороны mega328p.

Добавлено after 10 minutes 20 seconds:
У меня для связи между двумя МК (как разных семейств так и разного быстродействия в одном проекте) простой программный обмен с побитовой синхронизацией - ничему не мешает.
Единственно три линии задействованы - но в SPI в принципе столько же.
Не слишком шустро - но допускается хоть полная остановка на неопределенное время.
8)


Отвечу вам следующим из даташита меги:
 High Performance, Low Power AVR® 8-Bit Microcontroller Family
 Advanced RISC Architecture
̶ 131 Powerful Instructions – Most Single Clock Cycle Execution
̶ 32 x 8 General Purpose Working Registers
̶ Fully Static Operation
̶ Up to 20 MIPS Throughput at 20MHz
̶ On-chip 2-cycle Multiplier
 High Endurance Non-volatile Memory Segments

Т.Е. мегу можно остановить сняв тактовую частоту, подержать в таком состоянии сколь угодно долго, затем, подать частоту, и она пойдет дальше ровным счётом ничего не заметив. Ну это верно абсолютно, если исключаются всякие внешние временные возмущения вроде прерываний и внешнего тактирования таймеров.
Т.Е. там внутри нет динамических элементов. Всё сделано на статике.



Модераторы - не наказывайте плз. за цитирование, - пока не разобрался как процитировать часть поста.
Вложения
mega328_v3.zip
(11.85 KiB) Скачиваний: 118

Re: Проблема с Atmega328P

Пт сен 17, 2021 06:19:26

vlt999 писал(а):как процитировать часть

или удалить вручную лишнее, или после ОТВЕТИТЬ выделить нужную часть, а потом ЦИТАТА....

Re: Проблема с Atmega328P

Пт сен 17, 2021 07:06:32

vlt999 писал(а):twi_rd_free_wait_1:

cli

lds r16, TWI_BUSY
cpi r16, 0
breq twi_rd_free_wait_2
sei
jmp twi_rd_free_wait_1
vlt999 писал(а):Флажёк занятости TWI (у меня TWI_BUSY) должен опрашиваться и изменяться атомарно. Поэтому в примере выше такое хитропопое расположение инструкций CLI и SEI. Это то о чём все всегда забывают. А потом жалуются что всё работает с глюками

а в чем хитропопость?
это типа так, если по-людски:
Код:
do {sei(); cli();} while (TWI_BUSY);

Re: Проблема с Atmega328P

Пт сен 17, 2021 11:41:42

Человек под ассемблером "гранит грызет"(скорее начинает грызть :wink: ) - оттого и вопросы/решения соответствующие.
8)

Re: Проблема с Atmega328P

Пт сен 17, 2021 12:41:56

Человек под ассемблером "гранит грызет"(скорее начинает грызть :wink: ) - оттого и вопросы/решения соответствующие.
8)


Ну как бы грызть всё равно чем. Печально что приходится грызть почти вслепую, ибо datasheet, по сути shit.

Re: Проблема с Atmega328P

Пт сен 17, 2021 13:45:15

Если к тому еще добавить неполное понимание сути вопроса...
То будет совсем плохо.
8)
Я ведь привел возможность приостановки протокола как возможность персечения обмена прерываниями от других процессов (при работающем МК), а в ответ получил цитату о возможности приостановки МК.
:wink:
Вообще-то не с таких "жирных" кристаллов надо изучение начинать - 328я для разборок под ассемблером с ее аппаратными модулями явно пока для вас сложновата.
Как и работа с самим компилятором ассемблера.
Однако не опускаем лапки - "дорогу освоит идущий".
:beer:

Re: Проблема с Atmega328P

Пт сен 17, 2021 17:26:57

Не, ну понимаю когда протокол самопальный и программно-реализованный. Это ведь ваш случай? :lol:
А вот когда вместо описания аппаратной реализации протокола и графа переходов состояний автомата даётся голый набор состояний автомата, да ещё и коды реакции даются не в полном объёме.....ну тут совсем беда.
Понятно, хотели получить некую универсальную штуку, и вроде даже сделали её, но вот документацию к ней как сделали во времена оные для меги8А, так с тех пор никто и не попытался даже что-либо с этим сделать.
Типа микрочип купил конкурента для того чтобы убить, но убить не получилось :) .
Понятно что можно строить различные диаграммы обмена. Но вот какой (здесь должно быть грязное ругательство) забыл написать в даташите, что в TWBR надо грузить такой код, чтобы частота TWI ведомого была не ниже частоты ведущего. Иначе будут весёлые глюки с повисающим бессистемно автоматом. :evil: В идеале они должны быть как можно более близки.
И таких глюков полно.
И да где там программный сброс автомата в исходное состояние коли это встроенная периферия и лапки reset там не предусмотрено :shock: ?
Люди не от хорошей жизни делают программную реализацию интерфейсов обмена.
Вот и вы, видимо, провозившись с аппаратной реализацией плюнули и написали самопальную программную.
Ответить