Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:adc-to-matlab

Vzorkování analogového signálu do MATLABu

Jan Novotný, UREL, FEKT, VUT v Brně, xnovot97@stud.feec.vutbr.cz


Úvod

Úkolem tohoto projektu je navrhnout dvoukanálový vzorkovač analogového signálu do MATLABu s použitím vývojové desky STM32F429 Discovery kit, na které je osazen mikrokontrolér STM32F429ZIT s jádrem ARM Cortex-M4. Pro analogově-digitální převod bude využit vnitřní A/D převodník mikrokontroléru, z převodníku jsou data posílána do paměti pomocí periferie DMA a přenos do PC je řešen pomocí USB, které se chová jako virtuální sériový port. Převod a odeslání dat je spouštěno tlačítkem. V počítači jsou data načtena do programu MATLAB a vykreslena.


Použité periferie mikrokontroléru

Pro realizaci vzorkovače jsou důležité zejména tyto tři periferie:

  • Vnitřní A/D převodník
  • Kontrolér DMA (Direct Memory Access)
  • Periferie USB_OTG

A/D převodník

Mikrokontrolér STM32F429ZIT nabízí tři vnitřní 12-bitové analogově-digitální převodníky, z nichž zde jsou využity dva, a to ADC1 a ADC2, každý pro vzorkování jednoho vstupního analogového kanálu. Přenos digitalizovaných dat do paměti je řešen přes DMA pro dosažení co největší rychlosti. Převodníky jsou nastaveny do tzv. Multimode Interleaved módu (prokládaný režim). Ten spočívá v tom, že výstupem každého převodníku jsou 16-bitová slova, ta jsou pak složena do 32-bitového slova, které je posláno přes DMA do paměti. 16-bitová slova jsou do 32-bitového slova organizována tak, že v horních 16 bitů obsahuje data z převodníku ADC2 (kanál č. 2), spodních 16 bitů obsahuje data z převodníku ADC1 (kanál č. 1). Tuto situaci znázorňuje následující obrázek: Seřazení výstupních registrů A/D převodníků v prokládaném režimu

Kontrolér DMA

Jedná se o periferii mikrokontroléru, která slouží pro přímý přenos dat (odtud DMA-Direct Access Memory) z některé vnější periferie (například UART, A/D převodník, kontrolér pro čtení/zápis do vnější paměti FMC apod.) do paměti nebo zpět, a to celé bez asistence jádra. Jádro tedy může během DMA přenosu vykonávat jinou činnost, navíc přenos je rychlejší a ničím nepřerušovaný.

Periferie USB_OTG

Je poslední podstatnou periferií pro vytvořený vzorkovač. Je nastavena do režimu device (zařízení) s rychlostí full-speed, protože s interní fyzickou vrstvou není rychlost high-speed podporována, a po připojení k PC se chová jako virtuální sériový port (Virtual COM port) a umožňuje velice snadný sběr dat.


Blokové schéma zapojení

Blokové schéma propojení Discovery kitu (resp. mikrokontroléru) se zdrojem signálu a počítačem je na následujícím obrázku: Blokové schéma Jak už bylo řečeno, pro realizaci projektu byla použita vývojová deska Discovery kit, jejíž podoba a blokové schéma je na obrázku níže. Discovery kitBlokové schéma Discovery kitu


Vytvořené programy

Pro kompletní obsluhu vzorkovače bylo třeba vytvořit dva programy. Jednak to byl program v jazyce C pro použitý mikrokontrolér a za druhé to byl skript v MATLABu pro čtení a vykreslení dat z virtuálního sériového portu.

Program pro mikrokontrolér

Program je psán v jazyce C ve vývojovém prostředí Em::Blocks 2.30, ale protože nastavování všech periferií, systémů atd. mikrokontrolérů s jádrem ARM je již poměrně komplikované, je velice výhodné použít program STM32CubeMX, který umožňuje jednoduše zvolit a nastavit požadované periferie pouhým výběrem v grafickém rozhraní a následně umožňuje vygenerovat kostru kódu pro zvolené vývojové prostředí na základě knihovny HAL (HAL library), která obsahuje většinu potřebných funkcí.

Jádro programu tvoří funkce main(), ve které je nejprve inicializována knihovna HAL, hodiny a všechny potřebné periferie. Následně se v nekonečné smyčce testuje, zda došlo k externímu přerušení od stisku tlačítka. Pokud ano, spustí se A/D převod a čeká se, až je nastaven příznak indikující konec převodu. Pokud je nastavený, odešlou se získaná data přes USB, ale nejprve jsou poslány čtyři bajty udávající délku vysílaných dat v bajtech, což lze s výhodou využít při příjmu dat v programu MATLAB. Následně se vynulují příznaky dokončení převodu a stisku tlačítka. A/D převodníky je pak třeba vypnout, což je nutné pro vynulování všech příznaků v registrech převodníků, které by mohly bránit opětovnému spuštění převodu. Program se pak vrací opět na čekání na stisk tlačítka a celý cyklus se opakuje. Jednotlivé příznaky indikující stisk tlačítka dokončení A/D převodu atd. se nastavují v rámci tzv. callback funkcí. Protože knihovna HAL je postavena tak, že každé přerušení volá svou vlastní callback funkci, kterou si uživatel může editovat dle svých potřeb. Pro vyslání dat přes USB je vytvořena funkce VCP_write(), která musí data vysílat po úsecích maximální délky 64 bajtů, což je dáno maximální velikostí paketu endpointu USB. Vývojový diagram programu pro mikrokontrolér a zdrojové kódy klíčových funkcí main() a VCP_write() jsou uvedeny níže. Blokové schéma programu pro MCU

int main(void)
{
  /* Reset všech periferií, inicializace Flash rozhraní a Systicku. */
  HAL_Init();
 
  /* Konfigurace hodinového systému */
  SystemClock_Config();
 
  /* Inicializace nakonfigurovaných periferií */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_USB_DEVICE_Init();
 
 memset(hodnota, 0xAA, sizeof(hodnota));
 
  /* Nekonečná smyčka */
  while (1)
  {
      while(flag != 1);
      if (HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t*)hodnota, LENGTH_32) != HAL_OK)
      {
          Error_Handler();
      }
 
      if (HAL_ADC_Start(&hadc2) != HAL_OK)
      {
          Error_Handler();
      }
 
       HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);
      while (EndConv != 1);
 
      if ((EndConv == 1) && (flag == 1))
      {
          int delka = 4*LENGTH_32;
          VCP_write(&delka, 4);
 
          VCP_write(hodnota, 4*LENGTH_32);
 
          flag = 0;
          EndConv = 0;
          HAL_ADCEx_MultiModeStop_DMA(&hadc1);
          HAL_ADC_Stop(&hadc2);
       }
  }
}
// Funkce pro odesláni dat přes USB virtuální COM port
int VCP_write(const void *pBuffer, int delka)
{
    if (delka > APP_TX_DATA_SIZE)
    {
        int offset;
        for (offset = 0; offset < delka; )
        {
            int todo = MIN(APP_TX_DATA_SIZE,
                           delka - offset);
            int done = VCP_write(((char *)pBuffer) + offset, todo);
            offset += done;
        }
        return delka;
    }
 
    USBD_CDC_HandleTypeDef *pCDC =
            (USBD_CDC_HandleTypeDef *)hUsbDeviceHS.pClassData;
    while(pCDC->TxState) { } //Čekání na dokončení předchozího přenosu
 
    USBD_CDC_SetTxBuffer(&hUsbDeviceHS, (uint8_t *)pBuffer, delka);
    if (USBD_CDC_TransmitPacket(&hUsbDeviceHS) != USBD_OK)
        return 0;
 
    while(pCDC->TxState) { } //Čekej, dokud přenos neskončí
    return delka;
}

Program pro MATLAB

Pro přečtení dat přijatých přes USB do PC a jejich zobrazení byla v MATLABu vytvořena funkce Serial_2channel(). Zdrojový kód funkce je uveden níže:

function [] = Serial_2channel()
 
clear all; close all; clc;
s = serial('COM5');
set(s, 'InputBufferSize', 150000);
set(s, 'Timeout', 10);
set(s, 'DataBits', 8);
fopen(s);
 
len_bytes = fread(s,1,'uint32');
 
data_16b = fread(s,len_bytes/2,'uint16');
 
fclose(s);
delete(s);
clear s;
 
matrix_16b = reshape(data_16b,2,(length(data_16b)/2));
 
signalI = matrix_16b(1,:);
signalQ = matrix_16b(2,:);
 
signalQ = signalQ*3/(2^12);
tQ = 0:(1/2.4e6):((length(signalQ)-1)/2.4e6);
 
signalI = signalI*3/(2^12);
tI = 0:(1/2.4e6):((length(signalI)-1)/2.4e6);
 
figure(1);
subplot(2,1,1);
plot(tI, signalI);
title('Napětí na soufázovém vstupu'); 
xlabel('Čas[s]','FontSize', 14);
ylabel('Napětí[V]','FontSize', 14);
 
subplot(2,1,2);
plot(tQ, signalQ);
title('Napětí na kvadraturním vstupu'); 
xlabel('Čas[s]', 'FontSize', 14);
ylabel('Napětí[V]', 'FontSize', 14);

Funkce nejprve vyčistí pracovní plochu programu MATLAB, vytvoří spojení s příslušným sériovým portem (zde COM5), nastaví parametry přenosu, tj. velikost vstupního zásobníku pro přijatá data, čas, po kterém je spojení automaticky uzavřeno, a počet bitů každého přijatého znaku (čísla). Poté jsou z portu do 32-bitové proměnné přečteny čtyři bajty udávající délku přijatých dat v bajtech. Následně jsou samotná data ze sériového portu načtena do proměnné data_16b a spojení je ukončeno a zrušeno. Proměnná data_16b je pak zpracována tak, aby se od sebe oddělily oba kanály, a to změnou na dvouřádkovou matici, kde první řádek obsahuje liché pozice a druhý řádek sudé pozice původní proměnné. Pro úplnost je třeba zmínit, že navzorkovaná data jsou přes USB posílána po bajtech a to tak, že první dva bajty představují jeden kanál, druhé dva bajty druhý kanál atd. Tuto situaci naznačuje níže uvedený obrázek. Na závěr funkce už následuje pouze vytvoření časové osy a vykreslení obou kanálů, před kterým je ještě proveden přepočet velikostí vzorků na okamžitá napětí. Formát odesílání dat přes USB do počítače


Výsledky

Výsledné průběhy napětí obou kanálů vzorkovače zobrazené v MATLABu jsou na obrázku níže, přičemž pro otestování funkčnosti byly použity dva harmonické signály se stejnosměrnou složkou 1,65V (je třeba si uvědomit, že A/D převodník mikrokontroléru může pracovat s napětími v rozsahu 0V až 3,3V, proto je vhodné nastavit stejnosměrnou složku tak, aby rozkmit signálu mohl být stejný nad i pod tuto stejnosměrnou složku) a amplitudou 1V, takže jejich úrovně se pohybují v rozsahu cca 0,65V až 2,65V. Kmitočty sinusových průběhů jsou 1kHz a 500Hz. Popis průběhů jako napětí na soufázovém a kvadraturním vstupu je dán tím, že vzorkovač má být použit jako součást diplomové práce zabývající se zpracováním signálu UHF RFID čtečky. Soufázový vstup odpovídá kanálu č. 1 a kvadraturní vstup kanálu č. 2. Výsledné průběhy získané vzorkovačem a vykreslené v programu MATLAB Na následující fotografii je v hrubých rysech vidět propojení desky Discovery kit s počítačem a dvěma generátory signálu. Černý vodič přivádí signál na vstup kanálu č. 2 a červený vodič na vstup kanálu č.1. Připojení k počítači je realizováno dvěma USB kabely, jeden slouží pro připojení programovacího rozhraní a druhý pro přenos dat do počítače. Meřicí pracoviště

Na následujícím videu lze vidět navzorkování signálu. Nejprve se v MATLABu spustí funkce Serial_2channel() a pak se na Discovery kitu stiskne modré tlačítko, čímž se provede navzorkování a odeslání dat. Dokončení tohoto procesu je indikováno rozsvícením zelené LED diody a výsledné průběhy se pak objeví v grafu v MATLABu. Bohužel kvalita videa není dobrá, protože nebyl k dispozici přístroj poskytující dostatečnou kvalitu záznamu.


Závěr

Celkově je možno říci, že zadání se podařilo splnit. Vznikl dvoukanálový vzorkovač, který by teoreticky mohl být schopen vzorkovat signály až do kmitočtu 1MHz (A/D převodníky vzorkují s rychlostí 2,4 milionu vzorků za sekundu). Prakticky bude tato hodnota zřejmě nižší, ale vzhledem k určení vzorkovače by postačovala schopnost vzorkovat signály do kmitočtu 640kHz. Předností vzorkovače je využití periferie DMA, což zrychluje celý proces přenosu dat. Přenos navzorkovaných dat do počítače a jejich vykreslení také funguje velmi dobře, díky vestavěným funkcím MATLABu, které např. umožňují čtení dat ze sériového portu ve zvoleném formátu, není třeba data nějak výrazněji upravovat nebo přeskládávat, což přispívá k přehlednosti kódu.

2014/adc-to-matlab.txt · Poslední úprava: 2015/01/18 21:22 autor: Jan Novotný