Easyelectronics.ru

Электроника для всех
Текущее время: 16 дек 2017, 23:42

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Помогите организовать прерывание таймера на Cortex-M3
СообщениеДобавлено: 22 дек 2014, 16:39 
Только пришел

Зарегистрирован: 18 дек 2014, 15:11
Сообщения: 6
Уважаемые специалисты,
я имею некоторый опыт работы с AVR и теперь пытаюсь освоить ARM. У меня AT91SAM3X8E и IAR EWARM 7.3.
Благодаря вашей помощи мне удалось продвинуться до рабочего проекта, переключающего состояние линии ввода-вывода, при последовательном опросе события сравнения "RC compare" таймера TC0.
Теперь мне нужно заменить последовательный опрос прерыванием, но я пока не понимаю, как это сделать.
На основании изучения немногочисленных примеров и документации у меня сложились такие представления:
1) нужно сказать TC0->TC_CHANNEL->TC_IER|=0x00000010; // Разрешено прерывание RC compare.
2) Нужно установить глобальный флаг маскируемых перрываний, используя, например, intrinsic функцию (-и) "__enable_interrupt();" и/или "__enable_fiq();" (не понимаю пока, какую или обе ) или ассемблерную вставку (типа asm("sei") в AVR)
3) Нужно написать функцию обработчик, причем пока совершенно не понимаю, как она оформляется. Найденные мной примеры инкапсулируют функционал и предлагают подключать некие библиотеки и действовать через функции в этих библиотеках, чего мне совсем не хотелось бы делать на этапе освоения железа.
4) Правильно ли я понимаю, что за всем блоком TC0 закреплено одно и только одно прерывание, а понять, какое конкретное событие (например, сравнение RC или переполнение), возбудило это прерывание можно только анализируя флаги в регистре статуса внутри обработчика этого прерывания? Если это так, то для всех ли ARM Cortex-Mxx это характерно?

Привожу кусок своего кода:
Код:
#define __SAM3X8E__
#include <iosam3xa.h>

#define BITON(X, N)    (X)|=(1<<(N))
#define BITOFF(X, N)   (X)&=~(1<<(N))
#define GETBIT(X, N)   ((X&(1<<(N)))&&1)

void main(){
  WDT->WDT_MR=0x00008FFF; //Выключить сторожевой таймер
 
  // Переключаемся на внешний кварц (12МГц)
  PMC->CKGR_MOR=0x0137FF01;               // Включить внешний кварц 3-20 MHz (у нас 12 MHz) и выключить внутренний RC-генератор
  while (!(0x00000001&PMC->PMC_SR));      // Дождаться стабилизации кварца
 
 
  // Настройка ФАПЧ
  PMC->CKGR_PLLAR = 0x200A3F03;           // MUL=10, DIV=3 PLLACLK= 12 MHz*(MUL+1)/DIV = 44 MHz (но потом делится пополам в PMC_MCKR - PLLADIV2=1)
  while (!(0x00000002&PMC->PMC_SR));      // Дождаться захвата ФАПЧ
 
  // Выбираем вход Master Clock - PLLA без деления. Установка в 2 этапа - сначала смена делителей, потом смена источника такта
  PMC->PMC_MCKR=0x00001001;               // Выход Master Clock = Main Clock c делителем PLL на 2 (бит PLLADIV2=1)
  while (!(0x00000008&PMC->PMC_SR));      // Дождаться  установки Master Clock
  PMC->PMC_MCKR=0x00001002;               // Выход Master Clock = PLLA c делителем PLL на 2 (бит PLLADIV2=1)
  while (!(0x00000008&PMC->PMC_SR));      // Дождаться  установки Master Clock
 
  PMC->PMC_PCER0=1<<13; // Тактировать PIOC
  PMC->PMC_PCER0=1<<27; // Тактировать TC0
 
  PIOC->PIO_OER=1<<12; // PC12 as output pin
  PIOC->PIO_ODR=1<<13; // PC13 as input pin
  PIOC->PIO_PER=3<<12; // PC12, PC13 as PIO pins
   
  TC0->TC_CHANNEL->TC_RC=1000;         // Загружаем регистр сравнения RC (11MHz/1000 =11000 раз в сек событие сравнения RC)
  TC0->TC_CHANNEL->TC_CMR=0x0000C4000; // Timer_Clock1 selected (MCK/2=11MHz), Waveform Enabled, Up mode with autotrigger (autoreset) on RC

  while (GETBIT(PIOC->PIO_PDSR, 13));  // Ждем, пока не замкнута на GND тактовая кнопка на PC13
  TC0->TC_CHANNEL->TC_CCR=0x00000005;  //CLKEN=1, SWTRG=1 - RESET+Start
 
  while(1){
    if (TC0->TC_CHANNEL->TC_SR&0x00000010){ // Если было сравнение с RC (флаг автоматически сбрасывается после чтения регистра)
      if (GETBIT(PIOC->PIO_ODSR, 12))       // переключаем состояние ноги PC12
        PIOC->PIO_CODR=1<<12;
      else
        PIOC->PIO_SODR=1<<12;
    } 
  }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите организовать прерывание таймера на Cortex-M3
СообщениеДобавлено: 23 дек 2014, 11:44 
Только пришел

Зарегистрирован: 18 дек 2014, 15:11
Сообщения: 6
Мужики, ну подскажите же кто-нибудь, неужели никто на IAR не писал прерывания?! Затык полный, брожу третьи сутки в 3 соснах.
Не уверен, что понимаю, как объявлять обработчик. Судя по тому, что пишут (на сколько я понял), надо объявить функцию-обработчик со строго определенным названием, которое можно почерпнуть в некоем h-файле. Нашел в "sam3x8e.h" раздел "/* Peripherals handlers */", взял оттуда название, написал функцию, но не работает код. Может я неверно разрешаю прерывания? (Разрешить TC0_IRQn в NVIC + поставить флаг разрешения прерывания RC compare в регистрах TC0 + глобально разрешить прерывания - вроде я все выполнил).
Мой неработающий код (настройки портов и тактирования правильные - проверил в режиме последовательного опроса таймера):
Код:
#define __SAM3X8E__
#include <iosam3xa.h>

#define BITON(X, N)    (X)|=(1<<(N))
#define BITOFF(X, N)   (X)&=~(1<<(N))
#define GETBIT(X, N)   ((X&(1<<(N)))&&1)

void TC0_Handler(void){
      if (GETBIT(PIOC->PIO_ODSR, 12))       // переключаем состояние ноги PC12
        PIOC->PIO_CODR=1<<12;
      else
        PIOC->PIO_SODR=1<<12;
     
      //NVIC_ClearPendingIRQ(TC0_IRQn);
}

void main(){
  WDT->WDT_MR=0x00008FFF; //Выключить сторожевой таймер
 
  // Переключаемся на внешний кварц (12МГц)
  PMC->CKGR_MOR=0x0137FF01;               // Включить внешний кварц 3-20 MHz (у нас 12 MHz) и выключить внутренний RC-генератор
  while (!(0x00000001&PMC->PMC_SR));      // Дождаться стабилизации кварца
 
  // Настройка ФАПЧ
  PMC->CKGR_PLLAR = 0x200A3F03;           // MUL=10, DIV=3 PLLACLK= 12 MHz*(MUL+1)/DIV = 44 MHz (но потом делится пополам в PMC_MCKR - PLLADIV2=1)
  while (!(0x00000002&PMC->PMC_SR));      // Дождаться захвата ФАПЧ
 
  // Выбираем вход Master Clock - PLLA без деления. Установка в 2 этапа - сначала смена делителей, потом смена источника такта
  PMC->PMC_MCKR=0x00001001;               // Выход Master Clock = Main Clock c делителем PLL на 2 (бит PLLADIV2=1)
  while (!(0x00000008&PMC->PMC_SR));      // Дождаться  установки Master Clock
  PMC->PMC_MCKR=0x00001002;               // Выход Master Clock = PLLA c делителем PLL на 2 (бит PLLADIV2=1)
  while (!(0x00000008&PMC->PMC_SR));      // Дождаться  установки Master Clock
 
  PMC->PMC_PCER0=1<<13; // Тактировать PIOC
  PMC->PMC_PCER0=1<<27; // Тактировать TC0
 
  PIOC->PIO_OER=1<<12; // PC12 as output pin
  PIOC->PIO_ODR=1<<13; // PC13 as input pin
  PIOC->PIO_PER=3<<12; // PC12, PC13 as PIO pins
   
  TC0->TC_CHANNEL->TC_RC=1000;         // Загружаем регистр сравнения RC (11MHz/1000 =11000 раз в сек событие сравнения RC)
  TC0->TC_CHANNEL->TC_CMR=0x0000C4000; // Timer_Clock1 selected (MCK/2=11MHz), Waveform Enabled, Up mode with autotrigger (autoreset) on RC

  while (GETBIT(PIOC->PIO_PDSR, 13));  // Ждем, пока не замкнута на GND тактовая кнопка на PC13
  TC0->TC_CHANNEL->TC_CCR=0x00000005;  //CLKEN=1, SWTRG=1 - RESET+Start
 
  // Разрешить прерывания
  TC0->TC_CHANNEL->TC_IER|=0x00000010; // Разрешено прерывание RC compare 
  NVIC_EnableIRQ(TC0_IRQn); // Разрешено прерывание TC0 в NVIC
  __enable_interrupt();     // Глобально разрешить маскируемые прерывания
 
  while(1){}
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите организовать прерывание таймера на Cortex-M3
СообщениеДобавлено: 24 дек 2014, 11:20 
Заглядывает иногда

Зарегистрирован: 28 мар 2013, 11:01
Сообщения: 72
Обработчики прерываний находятся в startup-файле. Вся остальная информация есть в документах ARM, которая легко гуглится по запросам типа "cortex-m interrupts" и "cortex-m nvic".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите организовать прерывание таймера на Cortex-M3
СообщениеДобавлено: 25 дек 2014, 07:27 
Только пришел

Зарегистрирован: 18 дек 2014, 15:11
Сообщения: 6
Тема закрыта, разобрался


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите организовать прерывание таймера на Cortex-M3
СообщениеДобавлено: 25 дек 2014, 09:29 
Старожил
Аватара пользователя

Зарегистрирован: 17 апр 2010, 08:38
Сообщения: 4630
Откуда: Усинск, республика Коми
Anatoly писал(а):
Тема закрыта, разобрался

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

_________________
хаос это непознанный порядок


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помогите организовать прерывание таймера на Cortex-M3
СообщениеДобавлено: 25 дек 2014, 19:50 
Только пришел

Зарегистрирован: 18 дек 2014, 15:11
Сообщения: 6
здесь описал результаты своих экзерсисов: http://electronix.ru/forum/index.php?s= ... &p=1301620
Всем счастливо!


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB