Zakład Techniki Cyfrowej
Laboratorium z przedmiotu „Architektura komputerów i systemy operacyjne”
Ćwiczenie nr 5 Komunikacja z wykorzystaniem portu szeregowego UART
autor instrukcji: dr inż. Lech Zagoździński
Celem ćwiczenia jest zapoznanie studentów z zasadami programowania i wykorzystania interfejsów
szeregowych na przykładzie interfejsu UART.
Wymagania dla studentów
Niezbędna jest umiejętność programowania z wykorzystaniem języka C w zakresie składni,
operatorów pętli, konstrukcji warunkowych oraz znajomości operacji na wskaźnikach, tablicach, i
operacji wywołania funkcji.
Konieczne jest rozumienie pojęcia „przerwanie” oraz sposobu jego obsługi w mikrokontrolerach z
rdzeniem ARM Cortex M3.
Przed wykonaniem ćwiczenia studenci powinni zapoznać się z niniejszą instrukcją, plikami
aplikacji przykładowej z katalogu LAB_UART oraz umieć wyjaśnić zagadnienia podane jako
„tematy do przemyślenia” (podane kursywą).
Ponadto studenci powinni posiadać umiejętności nabyte we wcześniejszych ćwiczeniach
laboratoryjnych z przedmiotu „Architektura komputerów i systemy operacyjne”, w szczególności
znać sposoby obsługi środowiska IDE Keil Vision oraz budowy aplikacji w języku C.
Kolokwium wstępne
W czasie kolokwium będą zadane trzy pytania z zakresu objętego wymaganiami dla studentów.
Każde z pytań będzie ocenione w skali od 0 – 1pkt z gradacją co 0,25pkt.
W czasie kolokwium można korzystać z wydrukowanych fragmentów dokumentacji procesora [z
plików STM32F103VBT6.pdf – rozdział 4 Memory mapping oraz stm32f10xxx.pdf – rozdział 25
Universal synchronous asynchronous receiver transmitter (USART)] oraz z wydruków aplikacji
przykładowej.
Zakres pytań:
Pytanie nr 1- podstawowe konstrukcje języka C
Pytanie nr 2- budowa i konfiguracja interfejsu USART
Pytanie nr 3- budowa i zasada działania aplikacji przykładowej
Ocena wyników
Ocenie będą podlegały następujące składniki ćwiczenia:
•
staranność wykonania kodu
•
samodzielność pracy i znajomość wytworzonego oprogramowania
•
uzyskane funkcjonalności
każde z zadań jest oceniane osobno, punktacja podana jest w rozdziale 2.4 .
1
Asynchroniczna transmisja szeregowa
Transmisja asynchroniczna oznacza szeregowy przesył danych znak po znaku, które są kodowane
jako ciąg bitów oddzielanych specjalnymi znacznikami początku i końca znaku. Transmisja nie jest
synchronizowana żadnymi znakami specjalnymi, czy ciągami synchronizującymi. Jej początek
określają zmiany wartości początkowej z poziomu wysokiego na niski. Początek transmisji każdego
ze znaków jest określany z chwilą rozpoczęcia jego nadawania. Interpretacja znaku w odbiorniku
następuje po nadaniu kilku bitów danych, dlatego niewielkie różnice częstotliwości taktowania, po
obu stronach linii (nadajnik/odbiornik), nie mają istotnego znaczenia. Dla detekcji błędów
transmisji opcjonalnie używa się 1-bitowego znacznika parzystej liczby takich samych wartości
bitów jednego znaku. Dane są transmitowane znak-po-znaku na jednym przewodzie transmisyjnym.
W układach transmisji danych każdy bit (lub znak) musi być rozpoznany w czasie określonym
przez takt zegara synchronizującego. Ciąg bitów określających znak jest transmitowany w
znormalizowanej formie zwanej ramką czasową, którą przedstawiono na rys 1.
Rysunek 1: Struktura ramki asynchronicznej transmisji
szeregowej
Zmiana sygnału, na przewodzie transmisyjnym, z poziomu wysokiego na niski rozpoczyna
przedział czasu określający bit startu (START). Po bicie startu następuje od 5 do 8 bitów danych
poczynając od najmłodszego - D0, do najstarszego - D7. Ilość bitów zależy od konfiguracji
współpracujących urządzeń. Po bitach danych zostaje zapisany bit parzystości (P) określający
liczbę jedynek w ciągu danych (parzysta lub nieparzysta). Jego zastosowanie jest najprostszym
sposobem sprawdzenia pojedynczego błędu transmisji. Przed kolejnym bajtem danych (znakiem),
rozpoczynanym bitem startu są umieszczane: 1, 1.5 lub 2 interwały czasowe dla bitów końca znaku,
które nazwano bitami stopu (STOP).
Temat do przemyślenia:
Przeanalizuj zależności czasowe transmisji asynchronicznej dla różnych szybkości np. 9600, 19200,
itd. [bod]. Jaka jest rzeczywista przepływność binarna łącza, rozumiana jako ilość bitów
informacyjnych jaką maksymalnie udaje się przetransmitować w jednostce czasu.
2
Wykonanie ćwiczenia
Ćwiczenie wykorzystuje interfejs USART układu STM32F10103, który będzie skonfigurowany w
tryb pracy asynchronicznej (UART). Wymiana danych pomiędzy interfejsem a aplikacja będzie
następowała z wykorzystaniem systemu przerwań. Duży nacisk położono na strukturę kodu, w
której wyraźnie rozdzielono funkcjonalności drivera i aplikacji.
2.1
Konfiguracja stanowiska
Płytka laboratoryjna ZL27ARM wykorzystuje złącze CON3 w standardzie RS232C do transmisji
szeregowej.
Temat do przemyślenia
Przeanalizuj schemat ideowy płyty ZL27ARM. Wskaż numer portu USART, do którego jest
dołączone złącze CON3. Wyszuka informacje na temat standardu RS232C oraz układu U4. Jaka jest
jego funkcja?
Podłączenie płyty ZL27ARM do komputera wymaga wykorzystania kabla typu DCE-DTE, oraz
konwertera USB-RS232C. Należy zestawić stanowisko zgodnie z rysunkiem 1. Przed włączeniem
zasilania płyty należy uzyskać zgodę prowadzącego.
D0
D1
D2
D7
P
STOP
START
Następnie należy realizować ćwiczenie zgodnie z punktem 2.4 . Po zrealizowaniu każdego
podpunktu należy zgłosić ten fakt prowadzącemu. Kolejność realizacji podpunktów jest narzucona
przez instrukcję i nie należy jej zmieniać. Do końca ćwiczenia należy zachować kopię kodów
programu wykonanych do danego podpunktu.
Ćwiczenie jest realizowane w oparciu o aplikację przykładową. Wszystkie działania
studentów polegają na modyfikacjach i uzupełnianiu tej aplikacji. Do końca ćwiczenia należy
zachować kopię kodów programu wykonanych do danego podpunktu.
Należy skopiować katalog LAB_UART_ZRODLA do własnego katalogu i otworzyć w środowisku
Keil Microvision projekt LAB_UART. Okno projektu powinno odpowiadać rysunkowi
Rysunek 3: Struktura projektu
2.2
Struktura aplikacji
Wykonanie ćwiczenia opiera się na algorytmie pokazanym na rysunku 4. Jest to prosta aplikacja,
która po rozpoczęciu działania wykonuje niezbędne inicjalizacje a następnie przechodzi do
nieskończonej pętli programu, w której oczekuje na zdarzenia, a po ich wystąpieniu obsługuje je.
Algorytm aplikacji przykładowej pokazano na rysunku 4.
Rysunek 2: Konfiguracja stanowiska laboratoryjnego
ZL27ARM
Konwerter
USB RS232
PC
CON3
USB
JTAG
USB
ST-LINK
Rysunek 4: Struktura aplikacji przykładowej
Ilustruje to fragment kodu.
<main.c>=
#include "stm32f10x.h"
#include "uart_drv.h"
#include "io.h"
void main(void){
<deklaracje zmiennych lokalnych funkcji main>
<niezbędne inicjalizacje>
while(1){
if(<sprawdzenie znaczników>){
<obsługa danych>
}
}
}
Temat do przemyślenia
Na podstawie kodu źródłowego aplikacji laboratoryjnej należy wskazać jakie urządzenia
peryferyjne mikrokontrolera są inicjalizowane w bloku
<niezbędne inicjalizacje>
. Należy
zapoznać się z tymi urządzeniami.
Jak pokazano program
main
nie zajmuje się obsługą buforów danych, funkcja ta jest realizowana
przez driver. Zadaniem drivera jest obsługa systemu przerwań oraz buforów danych. Funkcje
wchodzące w jego skład bezpośrednio odczytują i zapisują dane do rejestrów danych interfejsu
Bufor danych
Bufor danych
main
Niezbędne
inicjalizacje
Sprawdze-
nie
znacznika
0
Obsługa
danych
1
Obsługa
przerwań
Driver
transmisji danych (UART). Operacje te będą opisane w dalszej części instrukcji.
Znaczniki informują aplikację, czy w buforach danych znajduje się informacja, która wymaga
obsłużenia. W aplikacji przykładowej znaczniki te są ukryte w pliku <buffer.o>. Dostęp do
nich jest zrealizowany niejawnie, za pośrednictwem funkcji interfejsu
<sprawdzenie znaczników>=
getRxUartData(<adres bufora>)
.
Temat do przemyślenia
Funkcja
getRxUartData
zwraca wartość, która odpowiada ilości danych przepisanych do bufora,
którego adres jest parametrem wywołania. Wskazać deklarację tego bufora w aplikacji
przykładowej oraz podać własny przykład implementacji funkcji
getRxUartData
.
Obsługa danych w aplikacji przykładowej polega na wysłaniu danych do drivera celem odesłania
ich do komputera PC.
<obsługa danych>=
putTxUartData(buffer, num);
putTxUartData("\n\r", 2);
Funkcja
putTxUartData
jest interfejsem drivera, który pobiera adres bufora oraz ilość danych,
które się w nim znajdują.
Temat do przemyślenia
W jakim celu umieszczono instrukcję
putTxUartData("\n\r", 2)
. Co oznaczają znaki \n i \r.
2.2.1 Driver - obsługa buforów danych
Obsługa buforów danych interfejsu UART jest zrealizowana przy pomocy funkcji:
int putTxUartData(char * buffer, int num);
int putRxUartData(char * buffer, int num);
int getTxUartChar(char * buffer);
int getRxUartData(char * buffer);
Aplikacja przykładowa nie udostępnia szczegółów implementacji funkcji obsługi buforów danych.
Implementacja procedur obsługi buforów danych jest tematem zadania 2.4.3 . Udostępniony jest
interfejs funkcji w postaci nagłówka „
buffer.h
”. Kod binarny biblioteki jest dołączany do projektu
w postaci pliku „
buffer.o
”.
Ważne jest, aby Studenci przed realizacją ćwiczenia zrozumieli zasady wykorzystania buforów w
aplikacji przykładowej. Jeżeli Ty masz kłopoty, zapytaj kolegów lub wykładowcy.
2.2.1.1 Funkcja putTxUartData
Funkcja interfejsu
putTxUartData
umieszcza w buforze nadawczym interfejsu UART
num
bajtów
danych zawartych w buforze
buffer
oraz inicjuje nadawanie. Funkcja zwraca wartość mówiącą o
ilości danych, które udało się umieścić w buforze. Jeżeli bufor jest pełny funkcja zwraca wartość
zero. Oznacza to, że funkcja nie nadpisuje danych w buforze nadawczym. Wszystkie uprzednio
wpisane dane zostaną wysłane.
Temat do przemyślenia
Zaproponuj własną implementację bufora. Czy Twoja implementacja posiada zabezpieczenie przed
nadpisaniem jeszcze nie wysłanych danych? Jeżeli nie, to w jaki sposób można zrealizować tą
funkcjonalność?
2.2.1.2 Funkcja putRxUartData
Funkcja interfejsu
putRxUartData
umieszcza w buforze odbiorczym interfejsu UART num bajtów
danych zawartych w buforze
buffer
. W aplikacji przykładowej funkcja jest wywoływana w
procedurze obsługi przerwania . Zapisuje ona zawsze jeden bajt danych do bufora. Zwraca ilość
bajtów danych, które udało się umieścić w buforze.
Temat do przemyślenia
Procedura aplikacji przykładowej <
handler przerwania
nie sprawdza wartości zwracanej
przez funkcję
putRxUartData
. Co się stanie z danymi odebranymi przez interfejs UART, gdy bufor
odbiorczy interfejsu UART jest pełny.
2.2.1.3 Funkcja getTxUartChar
Funkcja interfejsu
getTxUartChar
jest wykorzystywana przez <
handler przerwania
>. Wpisuje
ona bajt danych z bufora nadajnika portu UART do bufora wskazanego w wywołaniu. Zwraca:
•
1 gdy nastąpił wpis danych,
•
0 gdy bufor jest pusty.
2.2.1.4 Funkcja getRxUartData
Funkcja interfejsu
getRxUartData
powinna być wykorzystywana przez aplikację do sprawdzenia i
pobrania danych z bufora. Funkcja zwraca wartość niezerową (ściśle ilość bajtów danych
pobranych z bufora odbiorczego), gdy w buforze jest pełna linia danych zakończona znakiem
LF
. Jeżeli w buforze nie skompletowano całej linii danych, to w wyniku wywołania funkcji nie
następują żadne zmiany w strukturach danych bufora. Z tego powodu wywołanie funkcji jest
bezpieczne. Funkcję można wywołać w każdej chwili. Gdy jednak w buforze jest linia danych, to
zawsze następuje pobranie linii danych bufora odbiornika i przepisanie danych do bufora
wskazanego w parametrze wywołania funkcji.
Temat do przemyślenia
Zaproponuj własną implementację bufora zawierająca funkcję
int rxUartBufferEmpty(void)
,
która jedynie sprawdza, czy w buforze znajduje się linia danych. Czy przeglądanie całego bufora w
poszukiwaniu znaku końca linii LF jest wydajne? Jakie inne rozwiązanie można zastosować?
2.2.2 Driver - obsługa interfejsu UART w systemie przerwań
Obsługa interfejsu UART wymaga zakodowania następujących funkcji
•
<Inicjalizacja interfejsu UART>
•
<Handler przerwania interfejsu UART>
•
<Inicjacja nadawania>
2.2.2.1 Inicjalizacja interfejsu UART
Inicjalizacja interfejsu UART polega na ustawieniu wartości rejestrów konfiguracyjnych interfejsu
oraz uruchomieniu systemu przerwań.
1Określenie „handler” jest wyrażeniem żargonowym, ale na tyle szeroko stosowanym, że warto przyswoić jego
znaczenie.
2 LF, ang: Line Feed. Znak z zestawu ASCII. Porównaj [5], dodatek C
<Inicjalizacja interfejsu UART>=
<
Konfiguracja portu PA>
<Wlaczenie portu szeregowego>
<Zerowanie bitu M>
<Programowanie ilości bitów stop>
<Ustawienie szybkosci transmisji>
<wlaczenie odbiornika i nadajnika>
<wlaczenie przerwan portu usart w kontrolerze NVIC>
<Wlaczenie przerwania odbiornika>
Wszystkie operacje realizowane są bezpośrednio na rejestrach interfejsu, ważne jest zatem
zachowanie kolejności operacji. Aplikacja przykładowa konfiguruje interfejs dla następujących
parametrów: 57600 8 N 1.
Temat do przemyślenia
Zlokalizuj opis mapy pamięci procesora w dokumentacji mikroukładu STM32F103VBT6.pdf.
Odszukaj adres interfejsu UART (USART). Jaki jest rzeczywisty adres rejestru statusu USART_SR,
a jaki pozostałych rejestrów, np. rejestru kontrolnego USART_CR1.
W aplikacji przykładowej zadeklarowano strukturę danych
uartRegFile
, która jest dokładnym
obrazem rejestrów interfejsu.
<Deklaracja rejestrów pliku usart>
struct uartRegFile {
int USART_SR;
int USART_DR;
int USART_BRR;
int USART_CR1;
int USART_CR2;
int USART_CR3;
int USART_GTPR;
};
Następnie zdefiniowano wskaźnik do struktury i nadano mu wartość dokładnie odpowiadającą
adresowi interfejsu UART.
<Definicja wskaznika do pliku usart1>
static volatile struct uartRegFile * pUartRegFile =
(struct uartRegFile *)0x40013800;
Dzięki temu odwołanie do dowolnego rejestru interfejsu jest możliwe przy wykorzystaniu składni
odwołania do elementu struktury danych z wykorzystaniem wskaźnika do tej struktury, np.:
pUartRegFile->USART_BRR = 0x08b;
W odwołaniach do rejestrów szeroko wykorzystano wyrażenia zdefiniowane w pliku
stm32f10x.h,
który jest składnikiem aplikacji przykładowej.
Temat do przemyślenia
Porównaj definicje zawarte w pliku
stm32f10x.h
z nazewnictwem rejestrów interfejsu UART oraz
ze znaczeniem pól w tych rejestrach. Przemyśl jakie wartości powinny do rejestrów dla innych
parametrów transmisji. Będzie to tematem zadania 2.4.2 . Wykorzystaj w jak największym stopniu
definicje z pliku
stm32f10x.h
2.2.2.2 Handler przerwania interfejsu UART
Procedura obsługi przerwania nazywana jest „handlerem” przerwania. Funkcja jest wywoływana
zawsze ilekroć system przerwań (kontroler NVIC) zgłasza przerwanie interfejsu UART do rdzenia
mikroprocesora.
Temat do przemyślenia
Jaki jest mechanizm przyjęcia przerwania w procesorach ARM z rdzeniem Cortex M3. Odszukaj
tablicę wektorów przerwań w aplikacji przykładowej (w pliku STM32F10x.s). Jaki jest adres tej
tablicy po restarcie procesora a jaki w trakcie pracy aplikacji przykładowej. Czy tablica ta znajduje
się w pamięci stałej czy ulotnej? Co zawiera ta tablica?
Struktura handlera jest następująca:
<Handler przerwania interfejsu UART>=
<deklaracja zmiennych lokalnych>
<odczyt rejestru statusu>
if(USART_SR_RXNE = 1)
<pobranie danych z rejestru odbiorczego>
if(USART_SR_TC = 1){
<wylaczenie przerwania TCIE>
if(<pobranie danych z bufora nadajnika>){
<wysłanie danych do rejestru nadawczego DR>
<włączenie przerwania TXEIE>
}
else <wyzerowanie znacznika uartTransmitterInUse>
}
else if(USART_SR_RXNE = 1){
if(<pobranie danych z bufora nadajnika>){
<wysłanie danych do rejestru nadawczego DR>
}
else {
<wyłączenie przerwania TXEIE>
<włączenie przerwania TXCIE>
}
}
Odczyt rejestru statusu polega na pobraniu jego wartości do zmiennej lokalnej
tmp
, która jest dalej
analizowana.
<odczyt rejestru statusu>=
tmp=(pUartRegFile->USART_SR);
Odczyt rejestru statusu do zmiennej lokalnej gwarantuje, że zdarzenia zaistniałe po tym odczycie
nie wpłyną na przebieg procedury. Jeżeli te zdarzenia wystąpią w trakcie lub po zakończeniu
obsługi, to system na nowo zgłosi przerwanie.
Temat do przemyślenia
Jakie znaczniki rejestru USART_SR nie są obsługiwane przez handler. Jakie jest ich znaczenie.
Obsługa przerwania od odbiornika jest prosta. Zawiera jedynie pobranie danych z rejestru DR do
zmiennej tymczasowej data i wpisanie tej wartości do bufora odbiorczego interfejsu UART.
<pobranie danych z rejestru odbiorczego>=
data = (pUartRegFile -> USART_DR ) & USART_DR_DR;
putRxUartData(&data, 1);
Obsługa nadajnika jest bardziej skomplikowana. Wymaga sprawdzenia dwóch znaczników
USART_SR_TXE i USART_SR_TC.
Temat do przemyślenia
Jakie jest znaczenie bitów
USART_SR_TXE
i
USART_SR_TC
rejestru statusu? Kiedy są zgłaszane
odpowiednie przerwania? Wyjaśnij różnicę pomiędzy rejestrami
Transmit Data Register (TDR)
i Transmit Shift Register
nadajnika
.
Pobranie danych z bufora nadajnika jest ralizowane instrukcją
<pobranie danych z bufora nadajnika>=
getTxUartChar(&data);
co skutkuje zwróceniem odpowiedniej wartości i wpisaniem bajtu danych (o ile był w buforze) do
zmiennej lokalnej
data
.
Operacje wpisywania danych do rejestru DR nadajnika wykonuje wyłącznie handler Wynika stąd,
że inicjacja nadawania wymaga włączenia przerwania
TXEIE
nadajnika. Aby uprościć aplikację
zastosowano zmienną globalną
uartTransmitterInUse
, która służy wyłącznie do sprawdzania,
czy nadajnik jest używany, innymi słowy czy handler automatycznie wybiera dane z rejestru
nadawczego interfejsu UART. Po opróżnieniu bufora nadawczego handler zeruje tą zmienną.
<wyzerowanie znacznika uartTransmitterInUse>=
uartTransmitterInUse = 0;
Zmienna ta jest ustawiana przez procedurę inicjacji nadawania
void initUartTransfer(void)
:
<Inicjacja nadawania>=
if(!uartTransmitterInUse){
pUartRegFile->USART_CR1 |= USART_CR1_TXEIE;
uartTransmitterInUse=1;
}
Temat do przemyślenia
Jakie operacje należy wykonać aby nadać tekst „Hello world”. Przeanalizuj aplikację
przykładową. Aplikacja po starcie wysyła do interfejsu UART tekst:
***************
Start programu
***************
Jaki jest mechanizm przekazania tekstu do rejestru DR nadajnika interfejsu UART.
Zwróć uwagę, że powyższy tekst, łącznie ze znakami CR i LF znajduje się w pamięci danych w
obszarze zmiennych inicjalizowanych.
2.3
Funkcja wyjścia poziomu aplikacji sprintf()
W aplikacji przykładowej wykorzystano uproszczoną wersję funkcji standardowego
wejścia/wyjścia printf(). Kod źródłowy funkcji znajduje się w pliku
io.c
aplikacji przykładowej.
Interfejs funkcji jest następujący:
unsigned char sprintf (unsigned char *bufor,unsigned char *napis,...)
Funkcja umieszcza formatowany napis w buforze o adresie wskazanym przez parametr wywołania.
Bufor o odpowiedniej wielkości powinien być zadeklarowany przez użytkownika funkcji. Funkcja
zwraca ilość bajtów danych umieszczonych w buforze.
Temat do przemyślenia:
Porównaj interfejs funkcji sprintf () z interfejsem standardowej funkcji printf().
2.4
Realizacja ćwiczenia
Wykonanie ćwiczenia polega na modyfikacjach aplikacji przykładowej zgodnie z poniższymi
punktami. Kontrola działania aplikacji powinna zostać zrealizowana z użyciem debuggera oraz
oceniona z pomocą aplikacji terminala na komputerze PC.
2.4.1 Wykonanie aplikacji (zadanie za 2 pkt.)
Zadaniem studentów jest :
a/ Zrealizować funkcję echa, tzn. znaki odebrane z odbiornika portu UART powinny być
natychmiast retransmitowane do nadajnika tego portu i odesłane do komputera PC.
b/ stworzenie prostej aplikacji wykonującej na danych pobranych z bufora operację zadaną
przez prowadzącego ćwiczenie.
Należy dokonać następujące czynności:
1/ Wywołać funkcję inicjalizującą driver
int initUartDrv(void)
.
Funkcja jest bezparametrowa. Zwraca wartość 1, gdy działanie zakończyło się sukcesem, 0 w
przeciwnym wypadku. Funkcja inicjalizuje port dla parametrów 57600 8 N 1
2/ Dla pobrania danych z bufora należy wywołać funkcję
int getUartData(char * buffer)
,
podając jej wskaźnik do bufora zdefiniowanego w funkcji main. Funkcja wypełnia bufor danymi
znajdującymi się w buforze i zwraca ilość bajtów danych.
Uwaga: Funkcja magazynuje dane w buforze dopóki nie zostanie odebrany znak końca linii LF
(ang. Line Feed. Patrz tablica kodów ASCII). Dopiero wówczas udostępnia dane aplikacji. Dzięki
temu możliwe jest zrealizowanie obsługi komend wysyłanych z użyciem programu terminala
tekstowego np. „hyper terminal”, ale funkcja nie nadaje się dla realizacji „echa”.
3/ Dla wysłania danych do bufora należy wywołać funkcję
int putUartData(char * buffer,
int num)
. Parametrami wywołania są wskaźnik do bufora z danymi oraz ilość bajtów danych.
Funkcja zwraca ilość danych, które udało się umieścić w buforze.
2.4.2 Wykonanie drivera – procedura konfiguracji interfejsu UART
(zadanie za 2 pkt.)
•
Napisać własną wersję funkcję inicjalizacji bufora, przy czym parametrem wywołania
funkcji powinna być szybkość transmisji. Poprawne wartości szybkości transmisji należą do
zbioru {2400, 4800, 9600, 19200, 38400, 57600, 115200} [bod].
•
Sprawdzić działanie aplikacji dla różnych szybkości transmisji.
2.4.3 Wykonanie drivera – procedury obsługi struktur danych
(zadanie za 2 pkt.)
Celem zadania jest wykonanie fragmentów drivera, związanych z buforami przechowującymi dane.
Należy wykonać:
•
Zadeklarować bufory odbiorczy i nadawczy o długości MAX_DATA oraz funkcję
inicjalizacji zbudowaną w poprzednim zadaniu.
•
Napisać własną wersję procedury interfejsu bufora.
Procedury należy umieścić w pliku
buffer.c
, uprzednio odłączając od projektu plik
buffer.o
. Nie
należy modyfikować interfejsu bufora, znajdującego się w pliku
buffer.h
.
2.4.4 Modyfikacja funkcji warstwy aplikacji sprintf (zadanie za 1
pkt. do realizacji po wykonaniu zadań 3.3 – 3.5)
Celem zadania jest takie zmodyfikowanie funkcji sprintf, w tym jej interfejsu, aby wypisywała dane
bezpośrednio do bufora nadawczego portu UART. Funkcja powinna wywoływać interfejs bufora.
Pisanie bezpośrednio do struktur danych bufora jest niedozwolone.
3
Literatura dla studentów
Pozycje [1], [2], [3] spisu literatury można znaleźć na płycie laboratoryjnej CD. Będą one dostępne
podczas wykonania ćwiczenia na komputerach w laboratorium.
[1] ZL27ARM Zestaw uruchomieniowy dla mikrokontrolerów STM32F103, ver. 1.0 Kamami
2010, dostępny w pliku „dokumentacja_zl27arm.pdf”
[2] RM0008 Reference manual STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx
and STM32F107xx advanced ARM-based 32-bit MCUs, Doc ID 13902 Rev 9,
STMicroelectronics, dostępny w pliku „stm32f10xxx.pdf”
[3] STM32F103x8 STM32F103xB Medium-density performance line ARM-based 32-bit MCU
with 64 or 128 KB Flash, USB, CAN, 7 timers, 2 ADCs, 9 communication interfaces,
STMicroelectronics, dostępny w pliku „STM32F103VBT6.pdf”
[4] Brian W. Kernighan, Dennis M. Ritchie, Język ANSI C, WNT Warszawa 2004,
ISBN 83-204-2979-X
[5] Krzysztof Paprocki, Mikrokontrolery STM32, Wydawnictwo BTC, Legionowo 2009,
ISBN 978-83-60233-52-8