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

Прерывание (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
Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

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

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

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

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

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

ИТД

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

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

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 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) не будут выполнены, или эти команды постоянно повторяется?

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

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

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

При работе основного кода (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 пользователей онлайн

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

    • Ну кому как, у меня до этого были акустики Sven и топу подобные, так что для меня эти усилки звучат получше. Кроме этих двух есть еще ZK-XPSM на TDA7498E, стоит со стерео колонками HOLLEBERG X-2033BT. Вот в них заводской усилитель не звучал от слова совсем, звучание вызывало рвотный рефлекс. Решил поэкспериментировать, переделать их под внешний усилитель, купил фильтра частот, поставил, с заводским усилителем ничего не поменялось. Продал заводской усилитель и купил с али ZK-XPSM с блоком питания 32V 5A, подключил его и был удивлен тем, как изменилось качество звука. Появился сочный басс, заиграли верха. Эта стерео акустика зазвучала просто идеально под мои уши. Пробовал этот усилитель подключить к колонкам на 16 см динамиках и рупорах, звук совсем другой, гораздо хуже, чем на тех колонках, и шумы очень сильные, хотя с теми колонками вполне все в норме. Еще есть усилитель сабвуфера Aiyima A3001, также его можно и как моно на колонку использовать, с ним вот шум на колонках с 16 см динамиками вполне в норме. Так что тут еще есть зависимость и от колонок, с одними шумы есть, с другими нет.
    • @dolmatovva  у аурдинках  тама  яшибочяк  большя  чям  , если умом по разуму пришешь программу  
    • сказал бы ещё что презреваешь колесо, но ездишь на автобусе.
    • Да кроме ногодрыга ничего не освоил...(по прошлым проектам)
    • Всем здравствуйте! Вставлю и я свои 1.5 копейки. Давно была идея собрать себе усилитель. Как раз попались на барахолке заводские ПП ОМ2.7, далее через автора вышел на сайт паяльника, где и закупился дополнительными блоками усилителя. Ну и соответственно, все это нужно красиво упаковать в корпус. Так собственно я и попал к вам в тему корпусов. Пересмотрел, что-то читал, от сюда и пока до 750 страницы, все наслаждаюсь видами. Поэтому сразу скажу, с дядьками аудиоманьяками тягаться не по силам))) некоторые экземпляры прямо-таки цеплялись за глаз своей безупречностью и неповторимостью.  Собственно по теме, купил за несколько деревянных корпус от Кумира 001. Чуть подрихтовал, зачистил от старой краски. Буду красить черным акрилом из баллончика поверх грунта. На морду и зад заказал алюминиевые пластины 4 и 2 мм соответственно, их оставлю без краски, видел тут способ как их зашкурить. Но возможно залью тоже черным акрилом, посмотрю после примерки.  Радиаторы еще не зачистил, ждут свой очереди, тоже в черный акрил. Все двигается медленно, но уверенно, не хочется ошибиться. По размещению модулей внутри, пока примеряю, наверное нужно расширить пространство в середине, чтобы расположить оба блока питания там. Будет еще модуль Bluetooth и простенький цап. Вот как то так, по мере продвижения буду делиться фотками.  Критика и советы очень приветствуются, все таки первый проект.
    • а вы ими и не пользуетесь. что вы на них реализовали ?   или что атмега 328 на плате с обвязкой дешевле атмеги 16?
    • Спасибо но нет сами пользуйтесь этой ардуиной. Я буду пользоваться AVR микроконтроллерами.
×
×
  • Создать...