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

Прерывание (Irq-Interupt) В Arm-Контоллере


Рекомендуемые сообщения

Каким образом и как часто вызывается прерывание(IRQ-Interupt) в следующей С-программе для LPC 2xxx-контроллера. Правильно ли я понял, что прерывание вызывается только один раз, а потом выполняется бесконечный цикл?:

#include"LPC210x.h"
void Initialize(void);
/* I2C ISR */
__irq void I2C _ISR(void);
/* Master Transmitter states */
void ISR_8(void);
void ISR_18(void);
void ISR_28(void);
/*************************** MAIN ************************/
int main()
{
  /* Initialize system */
  Initialize ();
  /* Send start bit */
  I2C ONSET=0x60;
  /* Do forever */
  while(1)
  {
     IOCLR=0x40;
     IOSET=0x40;
  }
}
/*************** System Initialization ***************/
void Initialize()
{
  /* Remap interrupt vectors to SRAM */
  MEMMAP=0x2;
  /* Initialize GPIO ports to be used as indicators */
  IODIR=0xF0;
  IOSET=0xF0;
  /* Initialize Pin Connect Block */
  PINSEL0=0x50;
  /* Initialize I2C */
  I2CONCLR=0x6c; /* clearing all flags */
  I2CONSET=0x40; /* enabling I2C */
  I2SCLH=0xC; /* 100 KHz */
  I2SCLL=0xD;
  /* Initialize VIC for I2C use */
  VICINTSEL=0x0; /* selecting IRQ */
  VICINTEN= 0x200; /* enabling I2C */
  VICCNTL0= 0x29; /* highest priority and enabled */
  VICVADDR0=(unsigned long) I2C_ISR;
  /* ISR address written to the respective address register*/
}
/********************** I2C ISR **************************/
__irq void I2C_ISR()
{
  int temp=0;
  temp=I2STAT;
  switch(temp)
  {
     case 8:
        ISR_8();
        break;
     case 24:
        ISR_18();
        break;
     case 40:
        ISR_28();
        break;
     default :
        break;
   }
VICVADDR=0xFF;
}
/* I2C states*/
/* Start condition transmitted */
void ISR_8()
{
  /* Port Indicator */
  IOCLR=0x10;
  /* Slave address + write */
  I2DAT=0x74;
  /* Clear SI and Start flag */
  I2CONCLR=0x28;
  /* Port Indicator */
  IOSET=0x10;
}
/* Acknowledgement received from slave for slave address */
void ISR_18()
{
  /* Port Indicator */
  IOCLR=0x20;
  /* Data to be transmitted */
  I2DAT=0x55;
  /* clear SI */
  I2CONCLR=0x8;
  /* Port Indicator */
  IOSET=0x20;
}
/* Acknowledgement received from slave for byte transmitted from master. Stop
condition is transmitted in this state signaling the end of transmission */
void ISR_28()
{
  /* Port Indicator */
  IOCLR=0x80;
  /* Transmit stop condition */
  I2CONSET=0x10;
  /* clear SI */
  I2CONCLR=0x8;
  /* Port Indicator */
  IOSET=0x80;
}

Программа взята от сюда: стр. 11-14

Изменено пользователем mikro_man
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Прерывание происходит каждый раз, когда в аппаратном блоке I2C происходит какое небудь событие. (если грубо)

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Прерывание происходит каждый раз, когда в аппаратном блоке I2C происходит какое небудь событие. (если грубо)

То есть? Я не совсем понимаю:( Здесь я посылаю информацию(биты) на подключенную память и принимаю Acknowledgе бит. Что тогда в этом конкретном случае вызывает Interupt? Клок?

Изменено пользователем mikro_man
Ссылка на комментарий
Поделиться на другие сайты

Hongfa для различных применений в Компэл. Большой выбор в наличии!

Компания HONGFA - это не только крупнейший в мире производитель электромеханических реле, но также производитель конденсаторов, вакуумных прерывателей, трансформаторов и низковольтного коммутационного оборудования. На складе КОМПЭЛ регулярно поддерживаются около 100 самых популярных позиций электромеханических реле. Реле Hongfa могут заместить многие изделия производства недоступных брендов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Убегаю поэтому в крации

Дали команду сформировать "старт" по окончанию формирования получили прерывание и код статуса в I2STAT

Дали команду сформировать "адрес устройства и режим обмена" по окончанию формирования получили прерывание и код статуса в I2STAT

ИТД

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

Тренды и лучшие решения для разработки зарядных станций в России

К 2029 году в России прогнозируется увеличение числа зарядных станций до 40 000. При этом отечественный рынок электротранспорта имеет климатические, потребительские и географические особенности. Для успешной разработки и построения инфраструктуры станций заряда в России идеальным вариантом является использование решений и электронных компонентов китайских производителей – лидеров индустрии электротранспорта и возобновляемой энергетики, которые уже представлены в КОМПЭЛ. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Всё равно не догоняю :( Давайте рассмотрим конкретно эту программу: в начале идёт инициализация: Initialize (); В ней мы пишим: I2CONSET=0x40;

VICINTSEL=0x0; /* selecting IRQ */

VICINTEN= 0x200; /* enabling I2C */

VICCNTL0= 0x29; /* highest priority and enabled */

VICVADDR0=(unsigned long) I2C_ISR;

чем разрешаем прерывание, но это мы делаем только один раз и не в цикле. :rolleyes:

и потом мы посылаем стартбит:

I2C ONSET=0x60;

или как раз посли того, как послали стартбит всё работает автоматически? И как долго это работает? Пока все состояния из команды switch(temp) не будут выполнены, или эти команды постоянно повторяется?

Прошу простить за глупые вопросы, но я совсем чайник в микроконтроллерах.

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

Секреты депассивации литиевых батареек FANSO EVE Energy

Самыми лучшими параметрами по энергоемкости, сроку хранения, температурному диапазону и номинальному напряжению обладают батарейки литий-тионилхлоридной электрохимической системы. Но при длительном хранении происходит процесс пассивации. Разберем в чем плюсы и минусы, как можно ее избежать или уменьшить последствия и как проводить депассивацию батареек на примере продукции и рекомендаций компании FANSO EVE Energy. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Вы принципиально неверно мыслите.

При работе основного кода (main) никаких программных переходов на интеррапт не может быть по определению. Все что может мэйн - это разрешить аппаратные прерывания от периферии.

Как только возникает требование прерывания (интеррапт реквест), его создает АППАРАТНО один из периферийных модулей или этот сигнал подается прямо на ногу МК, контроллер завершает очередной машинный цикл, записывает в стек следующий адрес программной памяти и переходит по адресу обработчика (вектору прерывания). Вот по этому самому вектору (адресу) и компилируется обработчик (ISR).

По завершении обработчика стоит команда возврата (return). Она автоматически вставляется компилятором Си в конец кода обработчика. И программа таким образом возвращается в то место, откуда была прервана. При этом из стека извлекается тот самый адрес, который был записан при входе в прерывание. С этого адреса будет продолжено исполнение.

Таким образом main вообще не видит когда срабатывает обработчик. Для него время работы прерывания является "черной дырой"...

Изменено пользователем my504

戦う前に相手のベルトの色に注目

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

Спасибо за ответ!

Т.е. если программируешь в Си, то не не знаешь когда произойдёт интерапт? Вопрос, на который я всё ещё не получил ответ: в случае с моей конкретной программой, та последовательность команд которая вызвается в рутине прерывания, а именно: 1.Стартбит, 2.Слэйвадрес+W, 3.Данные, 4.Стопбит. Она вызывается один раз? Т.е. данные посылаются только один раз? Или всё таки последовательность команд:1,2,3,4 вызывается постоянно через какой то определённый период?.. Или чтобы эти данные послыть постояно через какой то определённый период, я должен создать счётчик таймера? Чтобы он постоянно вызывал интерапт-рутину через какой то определённый промежуток времени? Проблема в том, что эта программа написана для моего микроконтроллера, но для другого переферийного устройства. Мне надо запрограммировать LCD-дисплэй через I2C-бус, поэтому я не могу испытать программу на моём устройстве, но принцып программы мне подходит, просто я хочу понять как она работает. До этого железо я к сожалению никогда не программировал, но очень хочу научиться :) Чайник я..

Изменено пользователем mikro_man
Ссылка на комментарий
Поделиться на другие сайты

Приведу пример. Вы запускаете из мэйна прием на УАРТ. Как только буфер УАРТа будет полон (это отслеживается аппаратно), так модуль УАРТ выдаст прерывание по своему вектору. А программа обработки этого прерывания уже снимет данные из буфера и разместит их в ОЗУ. Мэйн будет только видеть "волшебным" образом возникающие в ОЗУ обновляемые данные...

Тоже самое и для I2C. Запуск обмена одиночным байтом программный, а готовность и съем данных через ISR. Это освобождает контроллер от необходимости следить за процессом обмена, не допуская переполнения буфера приема (или передачи). Все происходит на аппаратном уровне через прерывание.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

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

Меня сейчас больше отдача интересует, чем приём: я должен послать данные на LCD-дисплей, чтоб на нём буковки и фигурки засветились, и поcылать я их должен постоянно через определённый период.. Пoэтому я и спрашиваю: посылает ли эта программа данные регулярно или только один раз?

Изменено пользователем mikro_man
Ссылка на комментарий
Поделиться на другие сайты

Внимание это не готовы код а принцип

Создайте буфер передачи (массив) и счетчик переданных байт что то типа

#define LEN_BUFF_OUTPUT 10

BYTE BuffOutput[LEN_BUFF_OUTPUT];

int count_buffer_output;

Далее в программе нужные для передачи данные заливаем в буфер

count_buffer_output = 0;

BuffOutput[0] = нужные данные;

BuffOutput[1] = нужные данные;

итд

запускаем передачу ISR_8();

в обработчик прерывания дописываем что то типа

if(count_buffer_output < LEN_BUFF_OUTPUT)

{

I2STXFIFO = BuffOutput[count_buffer_output++];

}

else

{

попросить сформировать "стоп"

}

Код в основном цикле выполняется далее, а I2C пересылает данные по шине

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

Спасибо большое, но у контроллера LPC2138 уже есть I2C-порты с соответствующими регистрами, т.е. там можно без буфера обойтись.. Да и вопрос мой заключается не в этом. А в следующем: создавать мне счётчик таймера, чтобы микроконтроллер при помощи прерывания через определённый постоянный период посылал данные на LCD или можно обойтись без счётчика?

..посмотрите пожалуйста ещё раз программу, а именно int main(), void Initialize() и __irq void I2C_ISR()

Изменено пользователем mikro_man
Ссылка на комментарий
Поделиться на другие сайты

Программу для контроллера без ОС проектируют примерно следующем образом

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

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

.

while(1)

{

действие1

действие2

if(событие1 == ON)

{

действие3

}

if(событие2 == ON)

{

действие4

}

}

Допустим действие1 – проверка клавиатуры, а действие2 обновление индикатора. Мы можем подсчитать (зная скорость выполнения каждого действия) минимальный и максимальный(событии не происходили или произошли) интервал их наступления. Обычно так размещают то что надо выполнять постоянно и быстро.

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

while(1)

{

if(событие1 == ON)

{

действие3

}

if(событие2 == ON)

{

действие4

}

}

__irq Timer()

{

действие1

действие2

}

а еще правильней (хотя здесь спорный вопрос) сделать вот так

while(1)

{

if(событие1 == ON)

{

действие3

}

if(событие2 == ON)

{

действие4

}

if(событие3 == ON)

{

действие1

действие2

}

}

__irq Timer()

{

событие3 = ON

}

Изменено пользователем rtfcnf

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

Выяснил я наконец, когда вызывается интерапт: функцыя Initialize() устанавливает соответствующие регистры, которые разрешают интерапт, а после записи в регистер: I2CONSET=0x60; посылается стартовый бит на I2C и тем самым вызывает рутину прерывания(функцию прерывания): __irq void I2C_ISR(). Потом по очереди выполняются все три состояна функции прерывания I2C_ISR(), а именно:

case 8:

ISR_8();

break;

case 24:

ISR_18();

break;

case 40:

ISR_28();

break;

В регистор указывающий на функцию прерывания записывается другое значение: VICVADDR=0xFF;

программа возвращается назад и выполняется бесконечный цикл. Всё.

Может кому пригодится.

Изменено пользователем mikro_man
Ссылка на комментарий
Поделиться на другие сайты

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Под "начинай - поможем" здесь имеется в виду: вы демонстрируете результаты своих потуг на самостоятельное решение задачи, а желающие помочь указывают на ошибки и направляют в нужную сторону. А не делают вашу работу за вас, это в другой раздел форума.
    • Вам удалось победить это? Я так и не смог научиться компилировать. Давно купил SH1106 и SSD1306,  всё получилось с авторскими hex. Работает отлично.  Но вот сейчас купил SH1106  которые, почему-то, работают с hex для 1306(с 1106 не работают), но  справа полоса засвечивается, очевидно что под названием 1106 китайцы продают что-то иное. На Гитхабе писали что 1309. Вот и вопрос к коллегам: если есть возможность, можете скомпилировать hex  под Атм328 на разные типы индикаторов(1305 и 1309), кроме тех, которые уже есть(1106 и 1306)?  Готов раскошелиться на бутылку рома. 
    • Вечерами по неделе на каждый шар ушло(вернее не шар, а яйцо, т.к. папье маше слоями обклеивался обычный воздушный шарик) , потом после просушки ещё покрытие стеклотканью с эпоксидкой, грунтовкой, покраска рояльным лаком, и окончательная сборка акустики. В общем примерно за месяц с небольшим с той каторжной работой управился. В итоге, доказав себе,типа - я смог это сделать; наслушавшись и нахвастовавшись перед друзьями висящими на растяжках в углах зала яйцами, по случаю продал их одному небедному любителю подобных эксклюзивных изделий за 300 баксов(если помнишь, в конце 90-ых бакс резко попёр по цене в верх, и я не смог устоять перед искушением подержать псыцу счастья за хвост... и не удержал ).  
    • Доброго всем здравствуйте. Подскажите пожалуйста куда можно подать питание 5в. на эту блютуз модуль, чтобы работал только от сети, помимо заряда на аккумулятор. Фото выкладываю. Оторвался микроуизби. 
    • Да он скорее всего поторопился.  Долго изготавливал? Как то пытался тоже,но не срослось
    • Здраствуйте,собрал липина из первого поста,все отлично заработал без танцев с бубном,первое включение через латр смотря за сколом на коллекторе нижнего ключа,далее на балласте и на сварку варил замечательно,но включил его через несколько дней ключи тихо умерли,заменил запускаю через латр подымаю потихоньку напряжение все отлично,в первый раз подумал что частота уплыла и ключики из-за этого стрельнули но нет частота как была 38-39 кГц так и осталась полка так же есть только думаю она завышена на половину амплитуды регулировал ее путем подбора сопротивления на дед тайм,так вот через латр все отлично запускается подымаю до 310 на ключе,но дежурка подключена отдельно так вот когда отключаеш ключи в этот момент как я понял стреляют,даже в сборе когда дежурка запитана от основного питания как по схеме при включении сразу в сеть начало стрелять,думал может когда устанавливал крышку трансформатор повредил,нет же индуктивность проверил 3900 мкГн первичка,ток намагничивания насколько помню 0.7…0.8 ампер Снабера по ключам в норме проверял C метром,1 мкФ пленка по питанию около ключей в норме Осцилка приведу позже, сейчас на работе Возможно ли быть такое что после выключения от сети сигнал с затвора пропадает ,и он повисает в воздухе,хотя в принципе по схеме он подтянут резистором к эммитеру,да и работало же как-то да и у всех работает
×
×
  • Создать...