Start z STM32 VL Discovery – 14 — DAC

Start z STM32 VL Discovery – 14 — DAC
Razem głosów: 4 co stanowi: 90% całości.

Free Image Hosting at www.ImageShack.us

Kolejnym ciekawym układem wbudowanym w ARM jest DAC (Digital – Analog Converter), który może się

nam przydać np. do budowy generatora przebiegów. Zatem niniejszy opis potraktujmy jako wstęp.

Trochę teorii :

Zmianę wartości analogowych na cyfrowe już omówiliśmy, a teraz zajmiemy się szybkim dwukanałowym

przetwornikiem działającym  w kierunku przeciwnym, którym jest cyfrowo-analogowy DAC. 


Patrząc do DS naszego  STM32F100 który jest obecny w naszej Dicovery, w części opisującej piny

i ich alternatywne funkcje łatwo znaleźć, że DAC1 ma wyjście na pinie PA4, a drugi kanał DAC2 na PA5.

Ta opis  jest dla początkujących, więc będzie tylko pokazywał podstawy funkcjonalności DAC

w najprostszy sposób – czyli generowanie dwóch przebiegów  piłokształtnych, który będziemy w stanie

sprawdzić przy pomocy multimetru (nie każdy ma oscyloskop). Aby pomiar był jeszcze  łatwiejszy,

na początku okresu migniemy LED4 . Wychodzi na to, że  jest to typowy przypadek szkolenia  –

w praktyce.  Dlatego w dalszej części pokażę jak rozwiązać działanie konwertera używając przerwania

timera, który pozwala nam realizować wspólny program i wiele wyjść DAC będzie się zmieniać tylko

 podczas jego wystąpienia. Czasami w innych projektach, zademonstrowane jest wykorzystanie transferu

DMA, uwalniając operacje z transferu danych przez rdzeń procesora , DMA gwarantuje najszybszy możliwy

transfer bez użycia MCU – a wtedy możemy osiągnąć wysokie wartości generowanych częstotliwości w

setkach KHz. 

DAC jest 12-bitowy, więc wartość minimalna i maksymalna 0x0 0xFFFE odpowiada Vcc, czyli 3,3.

Opis szczegółowy  DAC  jest w Nocie. 

DAC może się generować sygnały – White, Noise oraz Saw.

Hmmm … dlaczego mielibyśmy zatem nie spróbować ??  Podobno trening czyni mistrza więc

spróbujmy sami użyć automatycznego generowania sygnału i go sobie zobaczyć.

 

Program 

Inicjowanie DAC jest podobne do inicjowania pinów GPIO,  więc nie będzie problemu ze zrozumieniem. 

Generowania sygnałów za pośrednictwem funkcji alternatywnych jaką jest DAC (na które rzucimy się w

innej części, kiedy wepchniemy tę funkcję w obsługę przerwania timera). Przy wstawianiu wartości

obliczonych ze stałą DAC_Align_12b_R, co oznacza, że ​​dane umieścimy w 12-bitowej przestrzeni  

i wyrównany do prawej. Zasadniczo program jest bardzo prosty i zrozumienie go nie powinno

stanowić problemu dla nikogo. Choć zamieszczę za pewne kompletny projekt :)

Kto używa multimetru może zobaczyć poprawne wartości na wyjściu PA4 i PA5,  Można też ustawić czas

opóźnienia na wartość  0x25555 lub 0x2FFFF gdyż typowe multimetry sa stosunkowo wolne. Przebiegi 

takie najlepiej obserwować na ekranie oscyloskopu.

Zatem czas na nasz program:

Prawda, że to bardzo proste …  Popróbujcie zatem sami generować sobie różne przebiegi  :)

No, jak widzicie udało się nam wygenerować analogowy sygnał na wyjściu przy pomocy przetwornika

DAC , działa to , ale powiedzmy że nasze poczynania sa nieco niezdarne w tym wypadku, a program jest 

mało optymalny i nie bardzo w sumie sprawny. Niemniej chodziło nam o szybkie przetestowanie

i sprawdzenie zasady działania.

Teraz postawimy sprawę jasno i zbudujemy porządniejszy program.

Jak już wspominałem oprzemy wszystko o przerwania ,  korzystanie z przerwań omówiłem już  przy okazji

Systick . Dlatego nie będę się tu wiele rozpisywał , a czytelnicy raz-dwa będa wiedzieć o co chodzi.

W skrócie powiem  iż używaliśmy TIM2 i biblioteki SunLCD . Teraz też założymy że użyjemy TIM3.

Oczywiście możemy sobie użyć i TIM2 i innego wolnego ….. ale nie o to chodzi  , bardziej o

wykorzystywanie zasobów.

Inicjacja PRZERWAŃ:

Zasadniczo jest taka sama jak w przypadku opisanym w SysTick , niemniej dokonamy zmiany polegające

na tym ze zamiast używać przerwania zewnętrznego EXTI użyjemy przerwania generowanego przez

TIM3. Na tym przykładzie nauczymy się też modyfikacji kodu , tak by wykorzystać zasoby naszych

Cortexów M3  i innych.

Zatem …..

 

Mam nadzieję że ładnie wszyscy zauważyli o co chodzi :)

 

Inicjalizacja timera

Będzie podobna do opisanej już wcześniej , którą znajdziecie w LCD.c pliku, użyjemy tylko innego numeru

zegara. Ustawianiu i używaniu liczników TIM2 TIM4 poświęcono sporo miejsca  w nocie.

Jest to 16-bitowy licznik, więc można podać mu wartości od 1 do 65535 (przy zliczaniu w dół).

Jako źródło zliczania impulsów, oczywiście należy wybrać źródło wewnętrznego taktowania  MCU, a

następnie możemy wybrać wartość preskalera, dokonując podziału impulsów zegarowych

(ponownie 16-bitowy, a więc także od 1 do 65535). W przypadku, gdy mamy wewnętrzny sygnał

zegarowy  z podstawową częstotliwością  taktowania MCU na STM32 VL Discovery, zestaw będzie mieć

częstotliwość 24 MHz, tj. na 1 sekundę na liczniku wychodzi  24000000 impulsów. Jest to trochę za dużo.

Jeśli ustawiony preskaler i podział wynosi  24000 impulsów ,sekunda może liczyć 1000 impulsów,

innymi słowy – każda milisekunda może liczyć jeden impuls.

 

Więc będziemy używać okresu trwającego 5 sekund (tj. 2,5 sekundy na wzrost sygnału i 2,5sek

na spadek ). Mamy 100 impulsów w jednym cyklu, więc 1 przyrost musiałby trwać 5s/100 = 50 ms!

Musimy zatem ustawić wartość początkową licznika na 50, odjąć  1 ms, a po 50ms skracać okres.

Oczywiście jeśli ustawimy 1 zamiast 50 wszystko będzie działać 50 razy szybciej, więc zamiast żądanej

częstotliwości 0,2 Hz  będziemy mieć piłę 25Hz .

 

Dlatego teraz ustawimy sobie nasz timerek żeby sobie liczył w dół , będzie to wymagało autoloadera —

oznacza to ze po doliczeniu do 0 wymagana wartość 50 będzie automatycznie wczytana do rejestrów.

Wartości Division CLOCK  przyglądniemy się dokładniej, jest ona potrzebna do zastosowania filtrów

cyfrowych:

 

Zatem cała inicjacja TIMERA 3  wygląda następująco :

Obsługa Przerwania :

Teraz gdy już mamy zrobiona koąnfigurację systemu przerwań i timera , musimy sobie napisać 

procedurę obsługi przerwania, tak by wszystko ze sobą ładnie pogodzić.

Tu problemu większego raczej nie będzie, wszystko co trzeba mamy już wstawione do jednej funkcji

nazwanej Generuj_DAC() ; wypisanej wyżej , a teraz tylko lekko ją poprawimy. 

Poprawa naszej funkcji będzie polegać w zasadzie na kosmetycznych zmianach dostosowujących 

ją do działania w przerwaniu , będziemy jedynie potrzebować sprawdzić czy wystąpiło przerwanie

i czy jest ustawiona flaga przerwania — to wszystko.

Ta niewielka korekta jest dla nas bardzo wygodna bo oszczędzamy czas  na napisanie całości od nowa.

Choć w naszym akurat przypadku można sobie takie podejście odpuścić, gdyż wartości sygnału

wyjściowego mamy w zakresie dopuszczalnym jak tez nie musimy przeliczać ich w skomplikowanym

przerwaniu, gdzie występuje wiele różnych zależności i funkcji. Niemniej myślę że nie warto też uczyć

się złych nawyków, dlatego właśnie zrobimy wszystko zgodnie z powszechnymi zasadami programowania.

Kiedy będziemy potrzebować wartości wyjściowej, trzeba najpierw zainicjować „zaliczkowo”

100-elementową tablicę wartości DAC1 i DAC2 i szybko ładować do niej wartości .


Jako ostatnią uwagę pamiętajmy do pliku stm32f10x_it.c wstawić FCE, nazwiemy go sobie dla

eksportowanej deklarację z pliku  stm32f10x_it.h. Tym sposobem będziemy mieć mniej kłopotu 

podczas niepotrzebnego wyszukiwania funkcji w main.c do których zwykle kompilator się doczepia

pisząc , że nie widzi w main.c funkcji do generowania wartości analogowych :)

Z tym oczywiście związane są nasze deklaracje przeniesienia zmiennych:

Licznik,

Wartosc_DAC1

Wartosc_DAC2. 

Zmienny okres zaś zadeklarujemy jako stałą. 

 

I to wszystko, teraz możecie sami pokombinować lub poczekać na gotowy przykład

i sobie modyfikować go i eksperymentować do woli.

Mam nadzieję, że DAC opisałem w miarę czytelnie …….

 

Podziel się na:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

Jedna myśl nt. „Start z STM32 VL Discovery – 14 — DAC

  1. Pingback: Kurs programowania STM32 VL Discovery | SunDuino – Nowy wymiar elektroniki

Możliwość komentowania jest wyłączona.