По статье о микроконтролерах

Здесь принимаются все самые невообразимые вопросы... Главное - не стесняйтесь. Поверьте, у нас поначалу вопросы были еще глупее :)
Ответить
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Прогу нашёл. Вопрос такой, что такое стек? Он уже в который раз его упоминает а что это такое не объясняет.
Реклама
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Там где-то было...
Нет времени подробно объяснить, работой завалили... Если не найдёшь до вечера - объясню.
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Ладно я поищу. Если не найду отпишусь. А то у меня ещё один вопрос возник тут.
Друг Кота
Аватара пользователя
Сообщения: 25498
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Сообщение КРАМ »

Стек - это структура данных с ПОСЛЕДОВАТЕЛЬНЫМ доступом через единственное "окно".
Различают два вида стеков: LIFO и FIFO
LIFO - last in - first out - последним зашел - первым вышел (как в обойме пистолета или автомата)
FIFO - first in - first out - первым зашел - первым вышел (сдвиговая задержка)
LIFO обычно применяют для сохранения адресов возврата и контекста, а так же для выделения памяти под локальные переменные при вызовах подпрограмм. Т.е. данные последовательно записываются в стек, а затем при чтении в ОБРАТНОМ порядке оттуда выталкиваются. Непосредственной адресации в этой структуре нет. Только порядок следования. "Окно", через которое происходит запись-чтение, называется вершиной стека (TOS - top of stack).
FIFO применяют в качестве буфера данных (ресивера-накопителя) при невозможности обработать их со скоростью их поступления. Естественно, что средняя скорость данных не должна переполнять этот буфер иначе данные пришедшие первыми будут утеряны (вытолкнуты из буфера).
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

КРАМ писал(а):Стек - это структура данных с ПОСЛЕДОВАТЕЛЬНЫМ доступом через единственное "окно".
Различают два вида стеков: LIFO и FIFO
LIFO - last in - first out - последним зашел - первым вышел (как в обойме пистолета или автомата)
FIFO - first in - first out - первым зашел - первым вышел (сдвиговая задержка)
LIFO обычно применяют для сохранения адресов возврата и контекста, а так же для выделения памяти под локальные переменные при вызовах подпрограмм. Т.е. данные последовательно записываются в стек, а затем при чтении в ОБРАТНОМ порядке оттуда выталкиваются. Непосредственной адресации в этой структуре нет. Только порядок следования. "Окно", через которое происходит запись-чтение, называется вершиной стека (TOS - top of stack).
FIFO применяют в качестве буфера данных (ресивера-накопителя) при невозможности обработать их со скоростью их поступления. Естественно, что средняя скорость данных не должна переполнять этот буфер иначе данные пришедшие первыми будут утеряны (вытолкнуты из буфера).
Благодарю. Доходчиво. :) Ещё тогда вопрос. Команда include подключает к программе текст другой проги находящейся в указанном текстовом файле. Какого формата должен быть текстовый файл чтобы команда сработала? Txt, или специальный какой то? Или вообще любой?
Реклама
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Какого формата должен быть текстовый файл чтобы команда сработала? Txt, или специальный какой то? Или вообще любой?
Формат текстового файла есть текстовый файл :) Может содержимое интересует?
Тут всё просто. Вместо директивы .include тупо вставляется содержимое файла. Это позволяет во-первых сократить большую простыню текста, во-вторых использовать однотипные конструкции (типа макросов) в других проектах просто перебросив нужный файл.

На счет стека: везде, где говорят "стек", касаемо ассемблера, имеют ввиду LIFO.
У контроллера есть такой регистр, который называется указатель стека, обозначается SP. Там хранится адрес в ОЗУ на границу стека (откуда ему расти). Если ОЗУ больше 256 байт, он будет двухбайтный (SPL и SPH).
В самом начале программы необходимо задать эту границу, записав адрес в этот регистр(ы). Так как указатель всегда растёт вниз, обычно задают адрес последнего байта ОЗУ, он обычно уже задан константой RAMEND. Вот пример инициализации стека какой-нибудь меги:

Код: Выделить всё

  ldi r16, high(RAMEND) ; Взяли старший байт константы RAMEND
  out SPH,r16 ; Записали его в старший байт указателя стека
  ldi r16, low(RAMEND) ; Аналогично младший
  out SPL,r16 
А дальше самое интересное. Если вызвать подпрограмму XXX, то после её выполнения контроллер должен вернуться в то место (на следующую команду), откуда он её вызвал. Но как ун узнает, куда возвращаться? Всё просто: при вызове подпрограммы (rcall XXX), адрес XXX помещается в стек, при этом указатель стека становится на два меньше (адрес - два байта). Подпрограмма выполнилась (наткнулась на ret), эти два байта извлекаются из стека, увеличиваются на один и записываются в счетчик команд (PC), при этом PC будет указывать на следующую после rcall команду, получается мы вернулись на место и пошли дальше.

Так же стек удобно использовать в своих целях. Например в подпрограмме YYY много раз используются регистры R16 и R17. Но их содержимое нельзя терять (оно нужно) после вызова YYY. Их куда-то надо сохранить на время. Опять спасёт стек:

Код: Выделить всё

push R16
push R17
rcall YYY
pop R17
pop R16
Сначала запихиваем R16 в стек. SP уменьшается на 1. Затем R17. Указатель еще на 1 вниз. Переходим к подпрограмме - еще на два. Итого 4 байта. Когда подпрограмма выполнится - SP поднимется на два байта и будет указывать на данные, которые были в R17. Достаём, и аналогично с R16.
Еще пример:

Код: Выделить всё

push R16
pop R17
Просто перебросили данные между регистрами. Засунули содержимое R16 и достали его в R17. Смысла не имеет, т.к. лучше пользоваться командой mov, это я так, для понимания.

Есть еще непонятки?
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Вы похоже думаете что я знаю ассм. Я его не знаю, я до этого только на паскале и вдельфи писал. В ассме только команды разучивать начал. :oops: Что такое подпрограмма?
ЗЫ. Но в целом я понял и что такое стек и про что вы мне писали, я не совсем тормоз. :)
Ещё. Вопрос по вот этой статье http://radiokot.ru/start/mcu_fpga/avr/06/ , начальный адрес для чего задаётся? Я думал в счётчике команд изначально и так 0 записан. Или эта команда обнуляет его при каждом новом запуске программы?
И ещё, почему перед некоторыми командами стоит точка и перед некоторыми нет в коде программы.
Ещё, как командой brne пользоваться? Можно пример? Насколько я понял ей должна предшествовать команда с каким то логическим или арифметическим действием и в зависимости от результата этого действия brne либо сделает переход к метке, либо нет. Так?
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

я до этого только на паскале и вдельфи писал.
Коллега! :)
Это самое главное. В смысле, что на чём-то писал.
В асме только команды разучивать начал.
Их не надо изучать. Вообще. Надо знать архитектуру контроллера (она довольно простая у АВР), и просто иметь под рукой даташит. Список команд с описанием там есть.
начальный адрес для чего задаётся? Я думал в счётчике команд изначально и так 0 записан
Так и есть, в PC изначально ноль. А директивой .org мы говорим компилятору откуда (с какого адреса) размещать следующий код.
Или эта команда обнуляет его при каждом новом запуске программы?
Это не команда, а директива компилятора. Контроллер её не знает. Ну например, в первой колонке адрес памяти контроллера, во второй - команды.
Для .org 0

Код: Выделить всё

00  ldi r16,5
01  out portd,r16
02  ldi r17,255
03  out portb,r17
04  clr r18
05 ...
Для .org 3

Код: Выделить всё

00
01
02
03  ldi r16,5
04  out portd,r16
05  ldi r17,255
Ещё, как командой brne пользоваться?
Опять же, есть краткое описание в даташите. Это переход, если НЕ установлен флаг Z, или флаг нуля (zero). Флаг может быть установлен предыдущей командой. В данном примере мы уменьшаем какой-нибудь регистр, и как только он опустошится (станет 0), установится флаг Z, и команда brne не сработает, т.е. цикл провернётся ровно столько раз, какое число было в регистре.
Так же желательно приводить куски кода, а то я опять телепатирую... :)
Насколько я понял ей должна предшествовать команда с каким то логическим или арифметическим действием и в зависимости от результата этого действия brne либо сделает переход к метке, либо нет. Так?
Именно! Каждое действие устанавливает какие-то флаги, а какие - описано в даташте. Например:

Изображение

Обрати внимание на логические AND, OR и арифметические ADD, SUB - колонка Flags. Первые устанавливают три флага (Z,N,V), остальные - пять.
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Их не надо изучать. Вообще. Надо знать архитектуру контроллера (она довольно простая у АВР), и просто иметь под рукой даташит. Список команд с описанием там есть.
Ну там дофига команд.Самые основные то надо знать, чтобы знать какими возможностями в ассме я вообще располагаю. Например я знал про ветвящиеся алгоритмы но здесь они делаются несколько иначе нежели в паскале (хотя мне в ассме больше понравилось как их можно осуществить :) здесь ведь с помощью переходов можно создать и цикл и условие).
Так и есть, в PC изначально ноль. А директивой .org мы говорим компилятору откуда (с какого адреса) размещать следующий код.
А зачем размещать код не с нулевого адреса а с какого-то другого?

Кстати. Т.е. насколько я понял то перед чем стоит точка это директива компилятора т.е. команда компилятору указывающая как он собссна текст программы скомпилит, а то перед чем нет точки это команды непосредственно для микроконтроллера. Так?
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Начну с конца:
Т.е. насколько я понял то перед чем стоит точка это директива компилятора т.е. команда компилятору указывающая как он собссна текст программы скомпилит, а то перед чем нет точки это команды непосредственно для микроконтроллера. Так?
Точно! Так и есть.
А зачем размещать код не с нулевого адреса а с какого-то другого?
Причин много. Например разместить какой-нибудь кусок с данными. Думаешь, программы сложнее мигания светодиодами на ассемблере не пишут?
Например я знал про ветвящиеся алгоритмы но здесь они делаются несколько иначе нежели в паскале
Где "здесь"? Паскаль (компилятор) есть и для контроллеров. И, кстати, неплохо работает.
Но ассемблер и ЯВУ (языки высокого уровня) - это совсем разные вещи.
Ну там дофига команд.
Около 120. Именуются очень понятно, лекго запомнить. Некоторые повторяют друг друга. Просто начни писать, дальше проще будет!
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Причин много. Например разместить какой-нибудь кусок с данными. Думаешь, программы сложнее мигания светодиодами на ассемблере не пишут?
Нет, так я не думаю. Но я ж ещё только учиться начал. Мне до сих пор кажется что я до конца не представляю всех возможностей микроконтроллеров.
Где "здесь"? Паскаль (компилятор) есть и для контроллеров. И, кстати, неплохо работает.
А в статье у DI HALT написано что паскалевский компилятор есть только для очень популярных МК, тех которыми могут не только профессионалы но и любители заинтересоваться. Но не для всех ведь.
Но ассемблер и ЯВУ (языки высокого уровня) - это совсем разные вещи.
Секунду, ассм это же язык низкого уровня кажется. Т.е. он на ступеньку повыше написания программы непосредственно машинными кодами.
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Мне до сих пор кажется что я до конца не представляю всех возможностей микроконтроллеров.
Я сам порой удивляюсь, читая возможности новинок :)
А в статье у DI HALT написано что паскалевский компилятор есть только для очень популярных МК, тех которыми могут не только профессионалы но и любители заинтересоваться. Но не для всех ведь.
Для AVR есть.
Но я бы советовал начинать с ассемблера. МК это не "большой брат", и в ассемблерный листинг придётся заглядывать очень часто, даже программируя на ЯВУ. Да и он очень помогает понять архитектуру.
Секунду, ассм это же язык низкого уровня кажется. Т.е. он на ступеньку повыше написания программы непосредственно машинными кодами.
Его даже языком программирования, в обычном его понимании, назвать сложно. Это просто мнемоники машинных команд.
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

У меня возник вопрос по статье http://radiokot.ru/start/mcu_fpga/avr/11/
Счётчик начинает считать с момента выхода программы из прерывания или сразу же параллельно выполнению программы обработчика прерывания? И, насколько я знаю, есть МК у которых на счётчики можно подавать сигнал с постороннего кварца, как счётчики работают там? (В смысле когда начинают считать)
И еще вопрос, может ли на одну метку ссылаться несколько переходов из разных частей программы? Или чтобы на одно и то же место программы перейти надо в этом месте несколько меток ставить по одной для каждого отдельного перехода?
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Счётчик начинает считать с момента выхода программы из прерывания или сразу же параллельно выполнению программы обработчика прерывания?
Счетчик начинает считать с момента подачи тактового сигнала на его вход, и считает до тех пор, пока его не убрать. Он же железный. (внутри МК реальная схема счетчика). Включается и останавливается счетчик, в данном примере, регистрами TCCR, установкой соответствующих битов.
И, насколько я знаю, есть МК у которых на счётчики можно подавать сигнал с постороннего кварца, как счётчики работают там? (В смысле когда начинают считать)
А точно так же. Соответствующей настройкой асинхронного (не связанного с тактовой шиной МК) режима.
И еще вопрос, может ли на одну метку ссылаться несколько переходов из разных частей программы? Или чтобы на одно и то же место программы перейти надо в этом месте несколько меток ставить по одной для каждого отдельного перехода?
Конечно можно. Простой пример задержки:

Код: Выделить всё

delay:
  clr r16
  clr r17
  ldi r18,150
del0:
  dec r16
  brne del0  

  dec r17
  brne del0

  dec r18
  brne del0
ret
Три части кода ссылаются на метку del0. Можно назвать аналог в паскале - goto. Можно сколько угодно переходить куда угодно.
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Ага. Понятно, благодарю. :)
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

У меня вопрос как прошить фьюзы? Прямо по шагам можно расписать? Читал что сначала надо считать те фьюзы которые уже стоят и только потом что-то менять. Знаю можно в командную строку задать команду читать. Но куда сохранится считанное, как его читать? И прочитав что потом делать. Есть также fuse калькулятор http://www.engbedded.com/fusecalc/. Объясните пожалуйста как им пользоваться.
Модератор
Аватара пользователя
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Сообщение ploop »

Советую оболочку к Avrdude Avr8 Burn-O-Mat
Она показывает фьюзы в нормальном виде (запрограммирован - галочка), опасные выделены красным и недоступны. Есть дефолтные значения, есть простой конфигуратор всего, что фьюзами настраивается (например выбрал от чего тактироваться - они сами встали)

Изображение
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Не понял как её увязать с avrdude. Когда пытаюсь шить она пишет что программа avrdude.exe не запущена.
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

А нет, извиняюсь, нашёл. :)
Спасибо большое. :beer:
Открыл глаза
Аватара пользователя
Сообщения: 70
Зарегистрирован: Пт фев 04, 2011 18:40:08
Откуда: Самара

Сообщение medius »

Помогите пожалуйста. Я похоже угрохал МК. Перешил фьюзы cksel3...0 в значение 0000 .Т.е. все включил. Хотя теперь понимаю что надо было бы 1000. Хотел чтоб он от внешнего кварца работал. :) И МК шиться теперь не хочет. Что я с ним сделал и можно это ли исправить? МК ATtiny2313V, схема http://radiokot.ru/start/mcu_fpga/avr/05/.
Ответить

Вернуться в «Теория»