Mikrokontrolery ARM cz22


K U R S
Mikrokontrolery z rdzeniem ARM,
część 22
Przetwarzanie C/A, biblioteka standardowa
Przetworniki C/A są układami
List. 14. Program do odgrywania ciągu próbek z pliku WAV
#include  lpc213x.h
peryferyjnymi stosunkowo
#include  armint.h
#include  wav.h
rzadko spotykanymi w typowych
#define P025_DAC_SEL (2<<18)
mikrokontrolerach. Producent
#define TIMER0_VIC (1<<4)
#define TIMER0_VIC_BIT 4
mikrokontrolerów LPC, począwszy
#define VIC_IRQSLOT_EN (1<<5)
od wersji LPC21x2, wyposażyli
static int AdcPos = 0;
je w jeden kanał konwersji
//Przerwanie od Timera
void IrqTimerHandler(void) __attribute__ ((interrupt( IRQ )));
C/A o rozdzielczości 10 bitów
void IrqTimerHandler(void)
z buforowanym wyjściem
{
//Zapis danych do DAC
napięciowym.
DACR = ((unsigned int)wav_file[AdcPos++])<<8;
if(AdcPos>= wav_length) T0TCR = 0;
//Kasuj zrodlo przerwania
T0IR = T0IR_MR0;
//Informacja dla VIC  koniec procedury przerwania
VICVectAddr = 0;
}
/* Funkcja glowna main */
int main(void)
{
PINSEL1 |= P025_DAC_SEL;
//Preskaler wylaczony
T0PR = 0;
Przetwornik wbudowany w pre- //Gdy warunek spelniony zeruj Timer i zglaszaj przerwanie
T0MCR |= T0MCR_Interrupt_on_MR0 | T0MCR_Reset_on_MR0;
zentowane mikrokontrolery charak-
//Przerwanie z częstotliwością 11khz
T0MR0 = 2720;
teryzuje się czasem przetwarzania
//Zeruj licznik i preskaler
rzędu 1 ms. Wyjściem przetworni-
T0TCR = T0TCR_Counter_Reset;
//Zalacz licznik T0
ka jest sygnał AOUT (P0.25), któ-
T0TCR = T0TCR_Counter_Enable;
ry może przyjąć wartości napięć
//Wektor 0
VICVectAddr0 = (unsigned int)IrqTimerHandler;
z zakresu 0& Vref. Przetwornik ten
VICVectCntl0 = TIMER0_VIC_BIT | VIC_IRQSLOT_EN;
może być wykorzystany do różno- //Zalaczenie przerwania
VICIntEnable = TIMER0_VIC;
rakich celów na przykład do gene-
//Zalacz IRQ
rowania sygnału audio, a sterowanie enable_irq();
return 0;
nim jest naprawdę bardzo proste,
}
ponieważ sam przetwornik posiada
tylko jeden rejestr. Zamiana warto-
ści cyfrowej na analogową sprowa- BIAS  Bit ten pozwala na wpisania wartości reprezentującej
dza się do wpisania odpowiednich ustalenie prędkości pracy przetwor- napięcie do rejestru DACR. Jedyną
wartości do tego rejestru. Rejestrem nika C/A, a co się z tym wiąże czynnością, o której musimy pamię-
tym jest DACR (0xE006C000), któ- umożliwia określenie prądu pobie- tać to, ustawienie linii P0.25 por-
rego wykaz bitów przedstawiono na ranego przez przetwornik. W przy- tu za pomocą rejestru PINSEL1,
rys. 72. padku, gdy bit ten jest wyzerowa- tak, aby pełniła ona rolę wyjścia
Funkcje jego poszczególnych bi- ny prąd pobierany przez przetwor- przetwornika C/A. Na zakończenie
tów są następujące: nik wynosi około 700 mA, a czas kursu napiszemy program (dostęp-
VALUE  Zapisanie odpowiedniej przetwarzania przetwornika wynosi ny na CD EP9/2007B pod nazwą
wartości na tych bitach powoduje 1 ms. W przypadku, gdy bit ten ep9c.zip), który wykorzystując prze-
pojawienie się napięcia na wyjściu jest ustawiony, wówczas przetwor- twornik C/A, będzie odtwarzał plik
AOUT, będącego odzwierciedleniem nik charakteryzuje się zmniejszo- dzwiękowy zawarty w wewnętrznej
wartości tych bitów. Wartość na- nym poborem prądu do 350 mA, pamięci Flash, na głośniczku wbu-
pięcia pojawiającego się na wyjściu ale równocześnie ulega zwiększe- dowanym w zestaw ZL6ARM. Plik
AOUT możemy wyznaczyć według niu do 2,5 ms czas przetwarzania dzwiękowy został zapisany bezpo-
wzoru: U =(VALUE/1023)*Vref przetwornika. średnio w pliku wav.c, w postaci
out
Używanie tego próbek dzwiękowych i został przy-
 & BIAS VALUE & &
przetwornika A/C gotowany na podstawie zwykłego
jest naprawdę bar- pliku w formacie wav z wykorzysta-
31 & 16 15 14 13 12 11 10 9 8 7 6 & 0
dzo proste i spro- niem narzędzi sox oraz awk, które
Rys. 72. Rejestr DACR wadza się tylko do zawarte są w pakiecie Cygwin. Plik
Elektronika Praktyczna 9/2007
101
K U R S
Tab. 8. Skrócony opis funkcji w bibliotece stdio
o jakimś prostym algorytmie umoż-
Nazwa funkcji Opis liwiającym skompresowanie próbek
dzwiękowych, co pozwoli na za-
_ssize_t _read_r(struct _reent *r,int file, void funkcja odczytująca dane z pliku lub konsoli lub
*ptr,size_t len) terminala
oszczędzeniu dodatkowego miejsca
_ssize_t _write_r (struct _reent *r,int file,const funkcja zapisująca dane do pliku lub konsoli lub w pamięci. Można również pliki
void *ptr,size_t len) terminala
dzwiękowe przechowywać w jakiejś
int _close_r(struct _reent *r,int file) funkcja zamykająca plik
dużej zewnętrznej pamięci takiej
_off_t _lseek_r(struct _reent *r,int file,_off_t
jak karta MMC, czy pamięć DATA
funkcja określająca przesunięcie w pliku
ptr,int dir)
Flash.
int _fstat_r(struct _reent *r,int file,struct stat
funkcja zwracająca status pliku
*st)
Biblioteka standardowa (stdio)
funkcja zwracająca czy otwarty plik jest termi-
W prezentowanych przykładach
int isatty(int file)
nalem
posługiwaliśmy się bezpośrednio
funkcjami biblioteki standardowej
dzwiękowy opiera się na zmien- merHandler(). W procedurze obsłu- , a dokładniej funkcją
nej tablicowej wav_file[] zawiera- gi przerwania próbki przesuwane printf w celu wyświetlania komu-
jącej próbki sygnału w formacie są na odpowiednią pozycję oraz nikatów tekstowych bezpośrednio
8 bitowym oraz wav_length okre- przesyłane do rejestru przetwornika na terminalu szeregowym. W przy-
ślającej rozmiar próbek. Zmienne C/A. Dzieje się tak do momentu padku standardowych kompute-
te zostały zadeklarowane ze sło- dopóki wszystkie próbki nie zosta- rów PC zadanie tej funkcji jest
wem kluczowym const, przez co ną przesłane, natomiast po zakoń- oczywiste i polega na wyświetle-
kompilator automatycznie traktując czeniu przesyłania ostatniej próbki niu ciągu znaków bezpośrednio na
je jako dane stałe umieszcza je zatrzymywany jest układ czasowo monitorze komputera. W tym celu
w obszarze pamięci Flash. Odtwa- licznikowy i cały proces odtwarza- funkcja printf wywołuje odpowied-
rzanie pliku dzwiękowego sprowa- nia pliku dzwiękowego kończy się. nie funkcję systemu operacyjnego
dza się do wysyłania poszczegól- Ponowne rozpoczęcie odtwarzania wyświetlające poszczególne znaki.
nych próbek sygnału analogowego pliku dzwiękowego rozpocznie się W przypadku mikrokontrolerów nie
do przetwornika C/A z częstotliwoś- po wciśnięciu przycisku zerującego mamy zdefiniowanego monitora
cią 11 kHz. Fragment programu do mikrokontroler. Przedstawiony tu- ekranowego, jednak do tego celu
odgrywania ciągu próbek za pomo- taj przykład miał pokazać jedynie można wykorzystać port szerego-
cą przetwornika C/A przedstawiono możliwość odtwarzania prostych wy mikrokontrolera. Pisząc progra-
na list. 14. plików dzwiękowych za pomocą my dla małych mikrokontrolerów
Odtwarzanie pliku dzwiękowego przetwornika C/A, wykorzystano pracujemy bez obecności systemu
rozpoczyna się od razu po wyze- tutaj bezpośrednie przechowywa- operacyjnego zapewniającego jedno-
rowaniu mikrokontrolera, a po jego nie parametrów próbek w pamięci lity interfejs programowy, a każdy
zakończeniu jest zatrzymywane, Flash. W rzeczywistym programie mikrokontroler posiada z reguły
dlatego aby ponownie odsłuchać odtwarzającym warto pomyśleć, inny układ portu szeregowego, nie
zawartość pliku należy nacisnąć
przycisk zerowania mikrokontro- List. 15. Funkcja umozliwiająca zapis danych do terminala
_ssize_t _write_r (struct _reent *r,int file,const void *ptr,size_t len)
lera. Po wyzerowaniu rozpoczyna
{
się wykonywanie funkcji głównej
int i;
const unsigned char *p;
(main), w której na początku usta-
p = (const unsigned char*) ptr;
wiana jest linia P0.25 tak, aby
for (i = 0; i < len; i++)
pełniła rolę wyjścia przetwornika
{
C/A. Przesyłanie  pustych pró- if (*p ==  \n ) Uart0PutChar( \r );
Uart0PutChar(*p++);
bek do przetwornika odbywa się
}
w przerwaniu od układu czasowo return len;
}
licznikowego T0, z wykorzystaniem
układu porównującego MR0, dlate-
go następną czynnością jest skon-
List. 16. Funkcja umożliwiająca odczyt znaków z terminala i przekazywanie
figurowanie układu porównującego
ich do wyższych funkcji biblioteki stdio
w taki sposób, aby zgłaszał prze- _ssize_t _read_r(struct _reent *r,int file, void *ptr,size_t len)
{
rwanie z częstotliwością 11 kHz.
char c;
int i;
Następnie konfigurowany jest kon-
unsigned char *p;
troler przerwań VIC, tak, aby
p = (unsigned char*)ptr;
for (i = 0; i < len; i++)
przerwanie od T0 powodowało
{
generowanie przerwania wektoryzo- c = Uart0GetChar();
if (c == 0x0D)
wanego, a na koniec włączana jest
{
globalna flaga zezwoleń na prze- *p= \0 ;
break;
rwanie. Całą pracę polegającą na
}
*p++ = c;
przesyłaniu poszczególnych próbek
Uart0PutChar(c);
sygnału z odpowiednią częstotliwoś-
}
return len  i;
cią do przetwornika C/A wykonuje
}
funkcja obsługi przerwania IrqTi-
Elektronika Praktyczna 9/2007
102
K U R S
funkcji biblioteki standardowej, na
List. 17. Funkcja _close_r służąca do zamykania plików
przykład na karcie pamięci MMC,
int _close_r(struct _reent *r,int file)
{
wówczas wspomniane wcześniej
return 0;
funkcję należy znacząco rozbu-
}
dować, o dodatkowe mechanizmy.
Konieczność zadeklarowania dodat-
kowych niskopoziomowych funkcji
List. 18. Funkcja _lseek_r umożliwiająca zmian ę pozycji w pliku
zapewnia bibliotece uniwersalność
_off_t _lseek_r(struct _reent *r,int file,_off_t ptr,int dir)
{
i niezależność od platformy syste-
return (_off_t)0; /* Always indicate we are at file beginning. */
mowej i sprzętowej.
}
Zakończenie
Podczas kursu zapoznaliśmy
List. 19. Funkcja _fstat_r służąca do zwracania informacji o otwartym pliku
się z możliwościami analogowymi
int _fstat_r(struct _reent *r,int file,struct stat *st)
{
mikrokontrolerów LPC213x/214x,
/* Always set as character device. */
które w sposób znaczący nie wy-
st >st_mode = S_IFCHR;
return 0;
różniają się niczym szczególnym
}
na tle innych podobnych układów
i należą do  klasyki w tej klasie.
i przekazywania do wyższych funk- Jednak rozdzielczość i dokładność
List. 20. Funkcja wykrywająca ter-
cji biblioteki. przetworników A/C wbudowanych
minal
Działanie tej funkcji sprowadza w mikrokontroler jest wystarczająca
int isatty(int file)
{
się do pobierania poszczególnych dla większości popularnych apli-
return 1;
znaków z terminala do momentu kacji, i tylko w przypadku bardziej
}
napotkania znaku końca linii, a na- zaawansowanych aplikacji pomiaro-
stępnie zwraca ona liczbę odczyta- wych użytkownik będzie zmuszony
da się więc bezpośrednio przygo- nych bajtów. To są właśnie dwie do zastosowania innych mikrokon-
tować uniwersalnej biblioteki stdio, główne funkcje, które odpowia- trolerów (na przykład ADCU7000
która pasowałaby do każdego mi- dają za współpracę z terminalem. również z rdzeniem ARM), lub
krokontrolera. Aby umożliwić dzia- Oprócz tego musimy zdefiniować użycia zewnętrznych przetworni-
łanie tej biblioteki musimy wraz kilka funkcji pomocniczych, które ków. Wbudowany w mikrokontroler
z programem przygotować pewien nie będą nic robić oprócz zwra- przetwornik C/A, umożliwia prze-
zestaw funkcji umożliwiających cania odpowiednich parametrów. twarzanie wielkości cyfrowych na
wysyłanie i odbieranie znaków, któ- Funkcja _close_r (list. 17) służy do analogowe, co możemy wykorzy-
re są zależne od typu mikrokontro- zamykania plików, a ponieważ my stać na przykład do odtwarzania
lera. Dla zapewnienia minimalnej pracujemy tylko z terminalem i nie plików dzwiękowych.
funkcjonalności musimy zapewnić można go zamknąć, dlatego funkcja To jest już ostatni odcinek tego
interfejs do następujących funkcji zwraca wartość 0. Kolejną funkcją kursu. Mam nadzieję, że przed-
niskopoziomowych: jest funkcja _lseek_r umożliwiająca stawione zagadnienia, informacje
Funkcje te służą do wykony- zmianę pozycji w pliku, ponieważ i przykłady pozwoliły Czytelnikom
wania operacji na plikach, gdzie terminal nie posiada żadnej pozy- zapoznać się z możliwościami mi-
uchwyty do plików o wartości 0, cji, więc funkcja ta zwraca zawsze krokontrolerów LPC21xx. Cykl ten
1, 2 są w systemach operacyjnych wartość zerową bez wykonywania miał także pokazać, że mikrokon-
szczególnymi plikami, czyli stan- żadnych czynności. trolery z rdzeniem ARM nie są
dardowym wejściem i wyjściem. Funkcja _fstat_r (list. 19) służy takie straszne, a posługiwanie się
Ponieważ w naszym przypadku nie do zwracania informacji o otwar- nimi wcale nie musi być dużo
pracujemy pod kontrolą systemu tym pliku, w naszym przypadku trudniejsze od programowania
operacyjnego i nie wykorzystujemy zawsze zwracamy informację, że 8 bitowych mikrokontrolerów na
plików, funkcje te są bardzo proste jest to urządzenie znakowe, nato- przykład AVR ów.
i sprowadzają się jedynie do wysy- miast funkcja isatty (list. 20) po- Niestety ograniczone łamy ni-
łania i odbierania znaków z portu winna zwracać wartość prawda niejszego kursu nie pozwoliły na
szeregowego. Do zapisywania da- w przypadku, gdy urządzenie jest przedstawienie wszystkich zagad-
nych do terminala wykorzystywana terminalem, w naszym przypad- nień, ale na podstawie przedsta-
jest funkcja _write_r, którą przed- ku również powinna zwracać ona wionych materiałów użytkownik
stawiono na list. 15. wartość prawdziwą. we własnym zakresie będzie mógł
Działanie tej funkcji sprowadza To już są wszystkie funkcje rozwinąć zagadnienia stosownie do
się do wysłania wszystkich zna- niezbędne do tego, aby biblioteka swoich wymagań. W razie jakiś py-
ków przekazanych do funkcji jako standardowa umożliwiała wyświet- tań wątpliwości oraz uwag na te-
argument prosto do terminala za lanie i odbieranie znaków do ter- mat niniejszego kursu, czekam na
pomocą funkcji Uart0PutChar(). Ko- minala za pomocą standardowych kontakt.
lejną funkcją umożliwiającą współ- mechanizmów znanych z kompute- Lucjan Bryndza, EP
pracę z terminalem jest funkcja rów PC. W przypadku, gdybyśmy lucjan.bryndza@ep.com.pl
_read_r (list. 16), która służy do chcieli obsługiwać zapisywanie
odczytywania znaków z terminala i odczytywanie plików za pomocą
Elektronika Praktyczna 9/2007
103


Wyszukiwarka