Телефонуйте » (+38) 096 227 41 41

Метою лабораторної роботи є вивчення переривань процесора, використання таймерів процесора та інтерфейсу введення/виведення загального призначення (GPIO).

Переривання

Апаратним перериванням (далі по тексту - переривання) називається механізм реакції на подію, що виникає у внутрішніх або зовнішніх, по відношенню до процесора, периферійних пристроях. Сигнал, який інформує про настання такої події, називається «запитом на переривання». Під час отримання запиту на переривання, процесор припиняє виконання основної програми і переходить до виконання підпрограми обробки переривання. Після завершення обробки переривання, процесор повертається до виконання основної програми. Чим швидше процесор обслуговує запити на переривання, тим краще він підходить для вирішення завдань в реальному масштабі часу.
Процесор C6678 містить векторний контролер переривань (C66x CorePac Interrupt Controller). Переривання з найвищим пріоритетом – це RESET, яке підключається до контакту апаратного скидання (reset) і не може бути замасковане.

Примітка: Маскування - це заборона на переривання. Якщо переривання замасковане і надійшов запит на нього, то воно або чекає, поки зможе бути прийняте, або втрачається. Замаскованими можуть бути переривання від пристроїв введення/виведення, зовнішні переривання, частина програмних переривань і переривання від схем контролю.

Зазвичай, сигнал RESET генерується в момент подачі живлення на процесор. Іншим джерелом сигналу RESET може служити внутрішній сторожовий таймер процесора (Watchdog Timer). При переповненні підрахункового регістру даного таймера відбувається генерація сигналу апаратного скидання, який надходить в центральне процесорне ядро. Наступне за пріоритетом переривання - це немасковане переривання (NMI), яке зазвичай використовується для попередження процесора про серйозні апаратні проблеми, наприклад, збій живлення.

Примітка: Обробка немаскованих переривань не може бути заборонена користувачем. Поява запиту на переривання обов'язково викликає зупинку виконання основної програми і перехід на підпрограму обробки даного переривання.

Також є 12 маскованих переривань з нижчим пріоритетом INT4-INT15 (INT4 має найвищий, а INT15 - найнижчий пріоритет). За допомогою контролера можна запрограмувати 128 системних подій на будь-якому з входів для цих дванадцяти переривань. Для TMS320C6678 джерелами переривань можуть бути зовнішні контакти модуля GPIO і такі внутрішні периферійні пристрої, як таймери, McBSP послідовні порти, McASP послідовні порти, канали EDMA, інтерфейс хост-порта.

Наявність великої кількості джерел переривання (128 джерел), а також обмежена кількість наявних ліній прийому запитів на переривання (тільки 12 маскованих переривань), змушує застосовувати спеціальний механізм управління обробкою переривань (Interrupt Management). Ідея його полягає в додаванні мультиплексора, який називається селектором переривань і який дозволяє користувачеві вибрати та підключити джерело переривань від INT4 до INT15.

Регістри переривань і їх призначення наведені в таблиці 4.1. Повна інформація про розташування регістрів представлена в TMS320C6000 CPU and Instruction Set Reference Guide. Бібліотека CSL надає функції для взаємодії з цими регістрами.

Таблиця 4.1: Регістри керування перериваннями

Біт 0 в Control Status Register (CSR) є Global Interrupt Enable (GIE) бітом. Всі масковані переривання заборонені, якщо GIE = 0, і дозволяються, якщо GIE = 1. Біт 1 - це Previous GIE (PGIE), який зберігає значення GIE, коли виконується переривання.

Біти з 0 по 15 регістру Interrupt Enable Register (IER) відповідають 16 перериванням центрального процесора CPU. Переривання дозволяються встановленням біта в 1 і забороняються встановленням біта в 0. Біт 1 є бітом Nonmaskable Interrupt Enable (NMIE). NMIE повинен бути встановлений, тобто NMIE = 1, для маскованих переривань. Для роботи використовуються біти з 4 по 15. Якщо NMIE = 0, жодне з маскованих переривань не буде обслуговуватися.

Коли відбувається переривання, відповідний біт встановлюється в регістрі Interrupt Flags Register (IFR), щоб зафіксувати переривання. Це відбувається незалежно від того чи дозволене переривання і дозволяє очікувати переривання, яке буде оброблене з часом, якщо воно не дозволене на даний момент. Переривання обслуговуються в порядку їх пріоритету.

Біт в IFR можна задати вручну, записавши значення 1 відповідного біта в регістрі Interrupt Set Register (ISR). Біт в IFR може бути скинутий (обнулений) шляхом запису 1 у відповідний біт регістра Interrupt Clear Register (ICR).

Коли обробляється переривання, програма переходить до процедури обслуговування переривання. Вона повинна знати, куди повернутися після того, як  завершиться. Регістр Interrupt Return Pointer( IRP) зберігає адресу повернення. Nonmaskable Interrupt Return Pointer (NRP) виконує ту ж функцію для немаскованих переривань.

Регістр Interrupt Service Table Pointer (ISTP) містить адресу таблиці обслуговування переривання. Коли на ЦСП подається живлення, адреса за замовчуванням ініціалізується 0 на початку пам'яті.

Що відбувається, коли виникає переривання

Щоб масковане переривання виникло, повинні бути істинними наступні умови:

·    Біт global interrupt enable (GIE), який є нульовим бітом в регістрі control status register (CSR) встановлений в 1. Якщо  GIE = 0, немасковане переривання не може відбутися.
·    Біт nonmaskable interrupt enable (NMIE) в регістрі interrupt enable register (IER) встановлений в 1. Масковане переривання не може відбутися, якщо NMIE = 0.
·    Біт, що відповідає необхідному перериванню, встановлений в 1 в IER.
·    Відбувається потрібне переривання, яке встановлює відповідний біт в регістрі interrupt flags register (IFR) в 1, і не є вищим за пріоритетом переривання з 1 в IFR.

DSP виконує наступні дії при виникненні переривання:

• Встановлюється в 1 відповідний прапор в регістрі interrupt flags register (IFR).
• Якщо GIE = NMIE = 1 і переривання вище за пріоритетом не знаходяться на обслуговуванні, переривання починає обслуговуватися:

-    GIE копіюється в PGIE (previous global interrupt enable біт) і GIE обнуляється, щоб виключити можливість інших переривань. GIE можна встановити вручну, щоб дозволити процедуру обслуговування переривання для переривання себе.
-    Прапор біта в IFR обнуляється, щоб показати, що переривання було оброблене.
-    Адреса повернення записується в регістр interrupt return pointer (IRP).
-    Виконання переходить до відповідного місця з таблиці переривань (IST).
-    Підпрограма обслуговування повинна зберегти стан CPU на вході і відновити його на виході.
-    Повернення з маскованих переривань здійснюється за допомогою інструкції згідно коду:

B IRP; return, moves PGIE to GIE
NOP 5 ; delay slots for branch

Розширення TI для C підпрограми обробки переривань

Компілятор Texas Instruments включає в себе розширення для стандарту C для обробки переривань. Для того, щоб компілятор використовував ці розширення при написанні підпрограми обробки переривання на C, оголосіть функцію ISR за допомогою ключового слова interrupt. Наприклад, оголосіть your_isr_name() для ISR інструкцією:

interrupt void your_isr_name(){...}

де точки в фігурних дужках являють собою вихідний код. Ви можете також використовувати pragma переривання (директива препроцесора, яка вказує компілятору, як треба трактувати конкретний оператор програми), як показано в наступному рядку:
#pragma INTERRUPT(your_isr_name)

Компілятор C автоматично згенерує код для:

1. Збереження регістрів процесора, що використовуються ISR на стеці. Якщо ISR викликає іншу функцію, всі регістри зберігаються.
2. Відновлення регістрів перед поверненням з інструкції в IRP.

Ви не можете передавати параметри, або повертати значення з підпрограми обслуговування переривання.

Примітка: При використанні бібліотеки Chip Support (CSL) і DSP/BIOS запис для ISR відрізняється. Ключове слово interrupt  не повинно використовуватися і ISR може передавати аргументи. Див. [TMS320C6000 DSP/BIOS, SPRU303] для більш детального ознайомлення.

Використання CSL API

В PDK є конкретний модуль (бібліотека Chip Support (CSL)), який містить відповідні API інтерфейси для програмування переривання. CSL API-інтерфейси для контролера переривань CorePac Interrupt Controller (INTC) мають вигляд CSL_intcxxx і для контролера переривань Chip-level Interrupt Controller (інакше, CIC) мають вигляд CSL_CPINTCxxx.

Загальний підхід CSL для роботи з перериваннями для INTC показано в фрагменті коду нижче. У цьому прикладі події з ID 63 обробляється вектором переривання 4. Якщо ви хочете змінити подію, яка викликає переривання, спочатку виконайте пошук ідентифікатора події, який зазначено в посібнику даних для конкретного пристрою (для 6678 це Таблиця 7-38 в [C6678 Data Manual http://www.ti.com/lit/ds/symlink/tms320c6678.pdf]). Після того, як ви визначили ідентифікатор події (наприклад, хх), змініть фрагмент коду нижче CSL_INTC_EVENTID_63 на CSL_INTC_EVENTID_xx в другому аргументі у функції CSL_intcOpen. Аналогічно, якщо хочете змінити вектор переривання 4 на інший номер вектора (від 4 до 15), назначте новий вектор переривання CSL_INTC_VECTID_xx змінній vectId в коді нижче:

{
   CSL_IntcObj intcObj63p;
   CSL_IntcGlobalEnableState state;

   CSL_IntcContext context;


   CSL_Status intStat;
   CSL_IntcParam vectId;

   context.numEvtEntries = 0;
   context.eventhandlerRecord = NULL;

   CSL_intcInit(&context);

   CSL_intcGlobalNmiEnable();
   intStat = CSL_intcGlobalEnable(&state);

   vectId = CSL_INTC_VECTID_4;
   hIntc63 = CSL_intcOpen (&intcObj63, CSL_INTC_EVENTID_63, &vectId, NULL);

   EventRecord.handler = &event63Handler;
   EventRecord.arg = hIntc63;

   CSL_intcPlugEventHandler(hIntc63,&EventRecord);
   CSL_intcHwControl(hIntc63,CSL_INTC_CMD_EVTENABLE,NULL);
 
   CSL_IntcClose(hIntc63);
}

void event63Handler(CSL_IntcHandle hIntc){
  . . .
}

CSL_IntcContext це структура, яка використовується для збереження поточного INTC контексту (ситуації) і включає в себе чотири елементи: запис обробника події, маску виділення подій, кількість входжень подій і зміщення. Запис обробника подій складається з обробника подій, тобто функції ISR, яка буде викликатися при настанні певної події, і відповідний аргумент, який буде переданий в цю функцію ISR. Число входжень подій відповідає числу подій, які програміст планує відображати. Маска виділення подій складається з 4-х масивів 32-бітних значень, де кожен біт являє собою один з 128 подій. Карта зміщення являє собою масив з 128 елементів, в якому зберігається кожне з 128 подій, які були нанесені на карту для переривання процесора, і чи є дійсним зв’язаний обробник події.

На наступному етапі в прикладі включаються глобальні і NMI переривання за допомогою CSL_intcGlobalEnable () і CSL_intcGlobalNmiEnable () API.

Відображення подій переривань досягається за допомогою CSL_intcOpen (...) API. API резервує переривання-подію для використання і повертає дійсний дескриптор події, якщо подія ще не виділена. У цьому прикладі ми відображаємо ідентифікатор події 63 для вектору переривань процесора 4.

Для визначення функції ISR, яка повинна бути запущена, коли дана подія відбувається, ми спочатку оновлюємо запис обробника подій контексту INTC. У цьому прикладі ми вказуємо обробник події "test_isr_handler", яка є функцією що виконується коли відбувається подія 63. CSL_intcPlugEventHandler (...) API потім використовується для зв'язування обробник події до події, так що, коли відбувається подія відповідна подія-обробник викликається. потім використовується CSL_intcHwControl (...) API для включення події, в даному випадку події 63.

CSL_intcClose (...) API викликається для звільнення події. Після того, як вона буде викликана, дескриптор INTC більше не може використовуватися для доступу до подій; подальший доступ до ресурсів подій можливий тільки після "відкриття" об'єкту події знову.
Для виконання роботи нам знадобиться ще один пристрій - таймер.

Таймери

Таймери можуть бути використані для подій, які відбуваються через деякий проміжок часу, підрахунку подій, генерації імпульсів, переривання процесора і посилання подій синхронізації в EDMA.

TMS320C6678 має шістнадцять 64-розрядних таймерів. Таймери Timer0 - Timer7 належать кожному з восьми CorePacs як сторожові таймери, а також можуть бути використані як таймери загального призначення. Кожен з восьми таймерів також може бути налаштований лише як таймер загального призначення, запрограмованим як 64-розрядний таймер або як два окремих 32-розрядних таймера.

При роботі в 64-бітному режимі таймер рахує або VBUS такти або вхідні (TINPLx) імпульси (на наростаючому фронті) і генерує вихідний імпульс/сигнал (TOUTLx) плюс внутрішню подію (TINTLx) на запрограмований період.

При роботі в режимі 32-біт таймер розділяється на два незалежних 32-розрядних таймера. Кожен таймер складається з двох 32-бітових лічильників: лічильник вверх (додавальний) і лічильник вниз (віднімальний). Виводи таймера, TINPLx і TOUTLx з’єднані з лічильником вниз. Виводи таймера TINPHx і TOUTHx підключені до лічильника вверх.

Коли зовнішній вхідний контакт TINP, обраний як джерело синхронізації таймера, таймер може рахувати вхідні імпульси і переривати процесор, коли досягається задана величина.

При роботі в режимі сторожового таймера, підрахунок відбувається до 0 і генерується подія. Скидання ініціюється шляхом програмування сторожового таймера через регістр Reset Type Status Register (RSTYPE) (стор. 147), а тип скидання можна встановити шляхом програмування регістра Reset Configuration Register (RSTCFG)' (стор. 148). Більш детальна інформація наведена в Timer64P для KeyStone пристроїв (стор. 72).

Внутрішня тактова частота для C6678 таймерів тактується частотою SYSCLK7 - це тактова частота процесора, що ділиться на 6 (CPU clock / 6). Таким чином, тактова частота таймера становить SYSCLK7=1 ГГц/6 = 166,67 МГц. якщо тактова частота CorePac (SYSCLK1)  дорівнює 1 ГГц після PLL.

Кожен таймер має три регістри, показані в таблиці 4.2. Бібліотека CSL [ ] має C-функції і макроси для конфігурації і взаємодії з таймерами.

Таблиця 4.2: Регістри таймера (Timer Registers)

Для того, щоб отримувати періодичні переривання, налаштуйте таймер для роботи в безперервному режимі (ENAMODE = 10b або 11b). Кожен раз, коли таймер закінчує підрахунок, він згенерує переривання таймера для CPU і подію таймера для контролера EDMA. Швидкість, з якою це відбувається (швидкість переривання таймера), залежить від того, чи має таймер подільник.

Якщо таймер не має подільника (є тільки один лічильник). Коли лічильник таймера досягає значення періоду таймера, таймер генерує переривання і подію EDMA. Оскільки таймер знаходиться в безперервному режимі, то через один такт після того, як лічильник таймера досягає періоду таймера, лічильник таймера скидається на 0 і починається відлік знову. Швидкість переривання таймера:

Якщо таймер має подільник ( є два лічильника). Один такт відбувається після того, як лічильник подільника досягає запрограмованого періоду, і лічильник таймера збільшується на 1, а подільник скидається, щоб почати відлік знову.

Після того, як лічильник таймера досягає запрограмованого періоду, таймер генерує переривання і подію EDMA. Через один такт (за умови, безперервного режиму) лічильник таймера скидається на 0 і починає відлік знову. Частота переривань таймера в даному випадку:

Виконання лабораторної роботи

Після знайомства з перериваннями та таймерами виконаємо наступне завдання - змінимо програму, яка працює зі світлодіодами таким чином, щоб затухання/загорання світлодіодів відбувалося по перериванню таймера. Період виникнення переривання таймером встановлюється згідно виконаних розрахунків. Для створення програми ми скористаємося готовою бібліотекою CSL[].

1.    Зробіть копію проекту з попередньої роботи.
2.    Встановіть необхідні шляхи до бібліотеки CSL для роботи з перериваннями та таймерами.

3.    Додайте перед main наступні бібліотеки, прототипи та глобальні змінні:


#include "ti\platform\platform.h"
#include "ti\platform\resource_mgr.h"

#include <ti/csl/csl_tmr.h>
#include <ti/csl/csl_tmrAux.h>
#include <ti/csl/src/intc/csl_intc.h>
#include <ti/csl/src/intc/csl_intcAux.h>



/************************** Global Variables *************************/

/* INTC Objects */
CSL_IntcObj                  tmrIntcObj;
CSL_IntcContext              context;
CSL_IntcEventHandlerRecord   EventHandler[30];

platform_info p_info;

/* Counter for Timer ISR */
volatile Int32 timerISRCounter = 0;

void TimerInterruptHandler (void *arg);
Int32 intc_init (void);
Int32 test_high_continuous_timer (Uint8 IntcInstance);

4.    Змініть main на наступний

void main(void) {
    platform_init_flags init_flags;
    platform_init_config init_config;

    char message[] = "\r\nHello World.....\r\n";
    uint32_t length = strlen((char *)message);
    uint32_t i;

    /* Initialize platform with default values */

    memset(&init_flags, 0x01, sizeof(platform_init_flags));
    memset(&init_config, 0, sizeof(platform_init_config));
    if (platform_init(&init_flags, &init_config) != Platform_EOK) {
        return;
    }

    platform_uart_init();
    platform_uart_set_baudrate(115200);

    platform_get_info(&p_info);

   //  Write to the UART
    for (i = 0; i < length; i++) {
        if (platform_uart_write(message[i]) != Platform_EOK) {
            return;
        }
    }

    printf ("****************** Timer Testing  ****************\n");

      /* Initialize the INTC Module. */
      if (intc_init() < 0){
          printf ("Error: Initialization of the INTC module failed\n");
          return;
      }

      /* Initialize timer CSL module */
      CSL_tmrInit(NULL);

      /* Start the testing for the  Timer. */
     if (test_high_continuous_timer(CSL_TMR_0) < 0)
     {
         printf("Error: Testing hi Timer (Unchained)  FAILED\n");
         return;
     }
     printf("Debug: Testing hi Timer (Unchained) Passed\n");

    /* Play forever */
    while(1) {}
}


5.    Додайте після main функцію ініціалізації переривання

Int32 intc_init (void)
{
    // Global Interrupt enable state
    CSL_IntcGlobalEnableState   state;

    /* INTC module initialization */
    context.eventhandlerRecord = EventHandler;
    context.numEvtEntries      = 10;
    if (CSL_intcInit(&context) != CSL_SOK)
        return -1;

    /* Enable NMIs */
    if (CSL_intcGlobalNmiEnable() != CSL_SOK)
        return -1;

    /* Enable global interrupts */
    if (CSL_intcGlobalEnable(&state) != CSL_SOK)
        return -1;

    /* INTC has been initialized successfully. */
    return 0;
}


6.    Додайте функцію обробки переривання

void TimerInterruptHandler (void *arg)
{

    static uint32_t led_no = 0;
    /* Increment the number of interrupts detected. */
    timerISRCounter++;
    if (timerISRCounter%2 == 0){
        platform_led(led_no, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
    }
    else
    {
        platform_led(led_no, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
        led_no = (++led_no) % p_info.led[PLATFORM_USER_LED_CLASS].count;
    }

    /* Clear the event ID. */
    CSL_intcEventClear((CSL_IntcEventId)arg);
}


7.    Додайте  функцію налаштування таймера та переривання за таймером

Int32 test_high_continuous_timer (Uint8 IntcInstance)
{
    CSL_TmrHandle               hTmr; // дескриптор таймера
    CSL_TmrObj                  TmrObj; // об'єкт таймера
    CSL_Status                  status; // статус
    CSL_TmrHwSetup              hwSetup = CSL_TMR_HWSETUP_DEFAULTS; // налаштування таймера (період...)
    CSL_IntcEventHandlerRecord  EventRecord;// запис дескриптора події
    CSL_IntcParam               vectId; // айді вектора переривання
    CSL_IntcHandle              tmrIntcHandle; // дескриптор переривання для таймера
    Uint32                      LoadValue = 83333500; // значення періоду
    CSL_TmrEnamode              TimeCountMode = CSL_TMR_ENAMODE_CONT; // неперервний режим таймера
    Uint32                      count; // лічильник

    /* Clear local data structures */
    memset(&TmrObj, 0, sizeof(CSL_TmrObj)); // обнулення обєкту таймера
    printf("Debug: Testing High Timer (Unchained) in Continuous Mode....\n");

    /**************************************************************
     ********************** INTC related code *********************
     **************************************************************/

    /* Open INTC */
    vectId = CSL_INTC_VECTID_13; // встановлюємо 13 вектор переривання

    // відкриваємо переривання для події CSL_GEM_TINTHN
    tmrIntcHandle = CSL_intcOpen(&tmrIntcObj, CSL_GEM_TINTHN, &vectId, NULL);
    if (tmrIntcHandle == NULL)
        return -1;

    /* Bind ISR to Interrupt */
    // записуємо функцію, яка буде оброблювати переривання по таймеру
    EventRecord.handler = (CSL_IntcEventHandler)&TimerInterruptHandler;
    // передаєм додатковий аргумент
    EventRecord.arg     = (void *)CSL_GEM_TINTLN;
    // зв*язуємо функцію оброблення з перериванням
    CSL_intcPlugEventHandler(tmrIntcHandle, &EventRecord);

    // Event Enable  дозволяємо подію
    CSL_intcHwControl(tmrIntcHandle, CSL_INTC_CMD_EVTENABLE, NULL);

    //********************** Timer related code ********************

    // Open the timer.  Відкриваємо таймер IntcInstance= CSL_TMR_0 для 0 ядра
    hTmr =  CSL_tmrOpen(&TmrObj, IntcInstance, NULL, &status);
    if (hTmr == NULL)
        return -1;

    // Open the timer with the defaults. встановлюємо налаштування по замовчуванню- все по нулях
    CSL_tmrHwSetup(hTmr, &hwSetup);

    // Stop the Timer - зупиняєм таймер
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL);

    // Set the timer mode to unchained dual mode -
    // встановлюєм режим таймера unchained dual mode
    hwSetup.tmrTimerMode = CSL_TMR_TIMMODE_DUAL_UNCHAINED;
    CSL_tmrHwSetup(hTmr, &hwSetup);

    /* Reset the timer ISR Counter. */
    timerISRCounter = 0;

    // Load the period register - записуємо період таймера
    status = CSL_tmrHwControl(hTmr, CSL_TMR_CMD_LOAD_PRDHI, (void *)&LoadValue);

    // Start the timer in CONTINUOUS Mode. Запускаєм таймер в непереввному режимі
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_START_TIMHI, (void *)&TimeCountMode);

    /* Wait for the timer interrupts to fire...*/
    while (timerISRCounter <= 500);

    /* Since the HIGH Counter is operating in Continuous Mode; the value here should
     * be non-zero. Though there is a small probability that the value here could be 0. */
    CSL_tmrGetTimHiCount(hTmr, &count);
    if (count == 0)
    {
        /* Taking into account the small probability; lets confirm out again.
         * This time for sure the value should be non-zero. */
        CSL_tmrGetTimHiCount(hTmr, &count);
        if (count == 0)
            return -1;
    }

    /**************************************************************/

    /* Disable the events. */
    CSL_intcHwControl(tmrIntcHandle, CSL_INTC_CMD_EVTDISABLE, NULL);

    /* Stop the Timer */
    CSL_tmrHwControl(hTmr, CSL_TMR_CMD_RESET_TIMHI, NULL);

    /* Close the Tmr and Interrupt handles. */
    CSL_tmrClose(hTmr);
    CSL_intcClose(tmrIntcHandle);

    /* Test has completed successfully. */
    return 0;
}

8.    Побудуйте програму, загрузіть її в процесор. Виконання на 0 ядрі.

Завдання

1.    Проаналізуйте код програми.  
2.    Змініть період таймера на 100 мс,  500мс,  1с.
3.    Змініть ID вектора переривання на інший.
4.    Реалізуйте перемикання світлодіодів за випадковим законом.
5.    Підключіть Бібліотеку для роботи з портами GPIO, згенеруйте меандр та спостерігайте його на осцилографі. Перевірте, чи співпадають отримані осцилограми з розрахунками.

Домашнє завдання

1. Заповнення масиву розміром 200 елементів по таймеру. Налаштуйте таймер на роботу по 5 вектору переривання. Заповнення повинно відбуватися з частотою 100 Гц. Масив заповнювати відліками сигналу, що представляє собою суміш синусоїд з різними частотами, наприклад , 500 Гц, 2500 Гц, 5000 Гц. Після заповнення вивести зображення сигналу інструментами Code Composer Studio.

Новини

  • Модуль SMARC запускає Android або Linux на Snapdragon 820
    Модуль SMARC запускає Android або Linux на Snapdragon 820

    SMART 2.0 "Snapdragon 820 SOM" iWave має 3 Гб LPDDR4, 32 Гб eMMC, Wi-Fi та Bluetooth, а також вхідні/вихідні виводи, включаючи GbE, HDMI 2.0, MIPI-CSI, USB 3.0 та PCIe. Комп'ютер розміром 82x50 мм працює на ОС Android Snailbone або вище, з наступною підтримкою Linux. Snapdragon 820 об'єднує чотири 14-нм Cortex з технологією FinFET - два на частоті 2,15 ГГц, а два з 1,6 ГГц, які намагаються імітувати високоякісні Cortex-A72. Крім того, SoC оснащений 624 МГц Adreno 530 GPU, Hexagon 680 DSP і 14-розрядним ISP для Spectra. Snapdragon 820 SOM підтримує кодування H.265 4K@60 та кодування 4K@30.

    in Новини

Записатися на курс