Мелкие вопросы по МК и ПЛИС.

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Мikа писал(а):1). При вызывании прерывания, бит 7 "чистится" аппаратно. Т.е. во время обработки этого прерывания, другое прерывание уже сработать не сможет?
Да, не может. Но вы в обработке прерывания можете выставить бит I, и тогда другое прерывание может произойти.
В любом случае, если во время обработки первого прерывания произошло второе, то от него останется флаг. И после RETI от первого прерывания вызовется второе прерывание. Прерывание прерывания запрерывалось.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

Доброе утро, Mika!
бить не буду)))
1) Да, верно, но только если не разрешить прерывания самостоятельно после входа в обработчик, выставляя бит I регистра SREG.
2) ... все верно, подтверждаю.
3) Утверждение "Бит 7 можно устанавливать и чистить командами SEI и CLI." верно.
НО код

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

ldi Temp, 0b1000000
out SREG, Temp
НЕ ЭКВИВАЛЕНТЕН команде SEI.
В коде Вы не только выставляете 7-ой бит регистра, но и еще СБРАСЫВАЕТЕ ОСТАЛЬНЫЕ, что непременно приведет к ошибке в случае переходов по условию и арифметических операциях.
вот этот код эквивалентен команде SEI:

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

in tmp, SREG
ori tmp, 0b10000000
out SREG, tmp
Следовательно, последовательно эти 2 команды использовать не надо, достаточно одной?
Да, верно, достаточно одной SEI/CLI
as described in the instruction set reference = ... как описано в документе Instruction Set
Ставим плюсы: )
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Сообщение Мikа »

Gudd-Head писал(а):В любом случае, если во время обработки первого прерывания произошло второе, то от него останется флаг.
Флаг - это 1 в регистре GIFR, правильно? Ещё не дочитал до других прерываний, но смею предположить, что раз в GIFR вписаны только прерывания INT, есть регистры с флагами других прерываний?
ibiza11 писал(а):НЕ ЭКВИВАЛЕНТЕН команде SEI.
Про эквивалентность я очень криво выразился. Написав этот кусочек когда я смотрел только на еденицу, а остальные нули держал в уме :) Написал именно так, а не через логическое ИЛИ, т.к. я про него, в принципе, знаю, но пока что на своём макете не использовал и не подумал об этой команде.

Спасибо за ответы, парни, всё прояснилось :) Пойду за новыми знаниями и вопросами :D
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

Мikа писал(а):есть регистры с флагами других прерываний?
Да, верно. У каждого периферийного модуля заведен отдельный регистр под флаги прерываний, аббревиатура которого обычно оканчивается на ..FR(Flag Register) или ..SR(Status Register), но бывают и исключения... наверное))))) не помню сейчас.
Ставим плюсы: )
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Мikа писал(а):Флаг - это 1 в регистре GIFR, правильно?
Флаг — это БИТ, необязательно "1" и необязательно в GIFR. Но таки да, в GIFR (General Interrupt Flag Register) флаги внешних прерываний: "0" — прерывания не было, "1" — было.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Сообщение Мikа »

Привет, коты =) Я почти добрался до прерывания, но есть очередной вопрос.

Сейчас у меня собран макет, в котром участвует:
ATmega32,
Тройной семисегментный индикатор с общим анодом,
Резисторы и провода, импровизированная кнопка.

Всё это должно выполнять следующие действия:
По одному семисегментному индикатору бегает огонёк по направлению a-b-c-d-e-f. Это работает, ничего сложного тут и нет.
При нажатии кнопки должно происходить переключение на следующий индикатор.

Вот текст программый, который есть на данный момент

Да, надо добавить вот что: PB0-PB5 по очереди дают 0, пропуская ноги индикатора к Земле.
PD6 питает общий анод первого индикатора. PD5 ждёт своей очереди для второго. PD2 - ножка прерывания.
Спойлер/*
* Led_01.asm
*
* Created: 15.04.2013 18:19:53
* Author: test3
*/


.include "C:\Program Files (x86)\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRAssembler\2.1.51.64\avrassembler\include\m32def.inc"

.def Temp1=R16 ;присвоение названий регистрам общего назначения
.def Temp2=R17
.def Temp3=R18

.cseg ;начало пограммного сегмента
.org 0

ldi Temp1, high(RamEnd); Установка указателя стека в начало ОЗУ Set Stack Pointer to top of RAM
out SPH, Temp1;
ldi Temp1, low(RamEnd);
out SPL, Temp1;

ldi Temp1, 0b10000000 ;Глобальное разрешение прерываний
out SREG, Temp1

ldi Temp1, 0b01000000 ;Разрешение прерывания на ножке ИНТ0
out GICR, Temp1

ldi Temp1, 0b0000000
out MCUCR, Temp1 ;Прерывание при 0 на INT0

ldi Temp1, 0b11111111 ;Настройка порта B на выход
out DDRB, Temp1

ldi Temp1, 0b1100000 ;Настройка порта D 2 выхода и входы
out DDRD, Temp1

ldi Temp1, 0b1000000 ;Включаем первый дисплей
out PortD, Temp1

begin: ldi Temp1, 0b11111110 ;Включаем Сегмент А
rcall Delay

ldi Temp1, 0b11111101 ;Включаем Сегмент B
rcall Delay

ldi Temp1, 0b11111011 ;Включаем Сегмент C
rcall Delay

ldi Temp1, 0b11110111 ;Включаем Сегмент D
rcall Delay

ldi Temp1, 0b11101111 ;Включаем Сегмент E
rcall Delay

ldi Temp1, 0b11011111 ;Включаем Сегмент F
rcall Delay

rjmp begin ;В начало цикла

Delay: out PortB, Temp1 ; Задержка
ldi Temp1, 0
ldi Temp2, 150

Loop: inc Temp1
brne Loop

inc Temp2
brne Loop

ret

int_0: ldi Temp3, 0b1000000
out PortD, Temp3
Спросить я хотел следующее:
1). Что нужно вписать в ножку PD2 (INT0), которая настроена на вход и ждёт, когда на ней вместо лог 1 будет лог 0 (к нй через 6.9 кОм подведено +5в, при нажатии на кнопку эти 5 через эти 6.9 кОм подсоедиянтся к земле). Так вот, что в неё изначально записать, 1 или 0? Так, стоп. Пока писал, вспомнил, что если порт настроен на вход, то не важно, что ты в него запишешь. Я не удаляю эти мысли в слух, тк ваше подтверждение очень нужно :)

2). Как я понял из прочитанной статьи про бегущей огонёк, то при прерывании по INT0, программа обратится к адресу этого прерывания. По даташиту оно записнао как $002. По этому адресу надо поставить безусловный переход на обработчик этого прерывания. А как это правильно сделать? Я пробовал эксперементировать с командой org, но что-то ничего дельного не вышло.

Если я где-то написал какой-то бред, прошу не бить, а сказать, что именно бред - пойду читать :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Почитайте в ДШ пример кода для вектора прерываний.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Сообщение Мikа »

Спасибо, понял что искать :)

Не могу найти. Может ищу не то? Хочу найти пример кода, в котором найду обработчик прерывания с меткой и то, что отправит программу на эту метку в случае возникновения прерывания. Не то ищу? Сразу скажу, в гугле я гуглил, но там все как один пишут на на С.
Последний раз редактировалось Gudd-Head Пт апр 19, 2013 14:23:15, всего редактировалось 1 раз.
Причина: Нарушение п.2.2 Правил Форума
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

При чём тут гугл? В ДШ есть пример.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Сообщение Мikа »

К Гуглу относится только последнее предложение моего поста. Я не могу найти пример в даташите.ю Сомневаюсь, что я ищу то, что надо. Я написал, что я пытаюсь там найти. Надо искать что-то другое?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Сообщение ibiza11 »

Открываете файл "m32Adef.inc" из папки "...Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes"
нажимаете Ctrl+F, вводите "interrupt vectors", жмете Enter
Видите табличку, каждая строка которой выглядит примерно так
.equ INT0addr = 0x0002 ; External Interrupt Request 0
выделяете всю табличку, копируете себе в исходник.
заменяете все ".equ" на ".org"
"= 0x0002" удаляете во всех строчках
после каждой строчки пишете
jmp <метка>
в самое начало таблицы добавляем две строчки:
.org 0
jmp RESET

Далее каждую метку пишете отдельно ниже таблицы векторов, не забывая после метки ставить двоеточие.
После этого пишете команду reti. Это буде заглушка для всех прерываний.
после этого пишете
RESET:
и после этой метки вставляете свою программу. Должно получиться вот так:
Спойлер

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

; ***** INTERRUPT VECTORS ************************************************
.org 0
   jmp RESET
.org INT0addr; External Interrupt Request 0
   jmp INT0_IRQ
.org INT1addr; External Interrupt Request 1
   jmp INT1_IRQ
.org INT2addr; External Interrupt Request 2
   jmp INT2_IRQ
.org OC2addr ; Timer/Counter2 Compare Match
   jmp OC2_IRQ
.org OVF2addr; Timer/Counter2 Overflow
   jmp OVF2_IRQ
.org ICP1addr; Timer/Counter1 Capture Event
   jmp ICP1_IRQ
.org OC1Aaddr; Timer/Counter1 Compare Match A
   jmp OC1A_IRQ
.org OC1Baddr; Timer/Counter1 Compare Match B
   jmp OC1B_IRQ
.org OVF1addr; Timer/Counter1 Overflow
   jmp OVF1_IRQ
.org OC0addr ; Timer/Counter0 Compare Match
   jmp OC0_IRQ
.org OVF0addr; Timer/Counter0 Overflow
   jmp OVF0_IRQ
.org SPIaddr ; Serial Transfer Complete
   jmp SPI_IRQ
.org URXCaddr; USART, Rx Complete
   jmp URXC_IRQ
.org UDREaddr; USART Data Register Empty
   jmp UDRE_IRQ
.org UTXCaddr; USART, Tx Complete
   jmp UTXC_IRQ
.org ADCCaddr; ADC Conversion Complete
   jmp ADCC_IRQ
.org ERDYaddr; EEPROM Ready
   jmp ERDY_IRQ
.org ACIaddr ; Analog Comparator
   jmp ACI_IRQ
.org TWIaddr ; 2-wire Serial Interface
   jmp TWI_IRQ
.org SPMRaddr; Store Program Memory Ready
   jmp SPMR_IRQ
; ************************************************************************

INT0_IRQ:
INT1_IRQ:
INT2_IRQ:
OC2_IRQ:
OVF2_IRQ:
ICP1_IRQ:
OC1A_IRQ:
OC1B_IRQ:
OVF1_IRQ:
OC0_IRQ:
OVF0_IRQ:
SPI_IRQ:
URXC_IRQ:
UDRE_IRQ:
UTXC_IRQ:
ADCC_IRQ:
ERDY_IRQ:
ACI_IRQ:
TWI_IRQ:
SPMR_IRQ:
   reti

RESET:
   rjmp PC
при необходимости ввести какое-либо прерывание, определяем соответствующую ему метку и комментируем(или удаляем) ее в списке заглушек и где-нибудь ниже таблицы векторов отдельно ее описываем. После этой метки должен идти код обработчика прерывания. В конце не забываем ставить reti. Пример:
Спойлер

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

OC0_IRQ:
   clr tmp
   out TCCR1A, tmp
   ser tmp
   out TCCR1B, tmp
   reti
В основной программе настраиваем периферийный модуль на генерацию прерывания, разрешаем глобальные прерывания. Вроде все.
Ставим плюсы: )
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Вот, раздел Interrupts ДШ:
Изображение
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Сообщение Мikа »

Всё заработало, огромное спасибо, ibiza11! Щас буду облагораживать программу :)
Gudd-Head, да, я нашёл это в даташите. Но понимания этого не добавило. Поэтому выше я и написал, что:
Мikа писал(а): ... Не могу найти. Может ищу не то? Хочу найти пример кода, в котором найду обработчик прерывания с меткой и то, что отправит программу на эту метку в случае возникновения прерывания. Не то ищу? ...
Да, сорри за п 2.2. нарушил его, чтобы в теме засветилось непрочитанное сообщение. Не знаю наверняка, делает ли сообщение "не прочитанным" обновление последнего сообщения в теме.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Друг Кота
Аватара пользователя
Сообщения: 20117
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Сообщение Gudd-Head »

Мikа писал(а):Не знаю наверняка, делает ли сообщение "не прочитанным" обновление последнего сообщения в теме.
Удаляйте своё последнее и пишите заново. Тогда засветит.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Сообщение Мikа »

Gudd-Head, может я опять не вижу чего-то, может быть не там смотрю, но у меня из возможностей относительно сообщения только это:
Изображение

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

Лично я, как модер, на это накалывался :beer:
Раз уж нафлудил не по теме, то заодно пожелаю всем хороших выходных, коты!

ibiza11, ещё раз огромное спасибо, вы открыли мне новое поле для деятельности и изучения!
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Держит паяльник хвостом
Аватара пользователя
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

Сообщение gauss »

Изображение

Читал про R-2R преобразователи и так и не понял, как формируется напряжение на ваыходе :facepalm:
Объясните чайнику, пожалуйста
:idea:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

кто может по простому растолковать: зачем нужна двойная буферизация в режиме Fast PWM в МК ATmega8 ?
Tell Me The Truth
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Чтобы не наткнутся на неполный цикл когда меняешь значение. Отрабатывает цикл до конца, только потом применяется установленное значение.

не понял, как формируется напряжение на ваыходе
путем замыкания части резисторов на землю, либо на +5В они образуют сложный делитель в результате которого двоичный код можно линейно преобразовать в напряжение.
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

Сообщение gauss »

Там получается сложный делитель, который я НУ НИКАК не могу понять :facepalm: :facepalm:
:idea:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

А чего их понимать... рисуешь схему где резисторы подключены одни на 0 другие на +5В и сидишь считаешь какое напряжение на выходе будет. Проще конечно пощупать в протеусе или чем-то подобном, с наглядными переключателями. Вобщем, оно работает!
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»