kursC czesc007

background image

39

Programowanie

Elektronika dla Wszystkich

Dziœ zajmiemy siê czymœ, od czego zaczyna

siê wiêkszoœæ ksi¹¿ek o C dla „du¿ych kom-

puterów”. Dlaczego dopiero teraz? Wspomi-

na³em ju¿ o tym i napiszê raz jeszcze: mikro-

kontrolery rz¹dz¹ siê innymi prawami ni¿

stacje robocze. Tam gdzie w stacji roboczej

wystêpuje BIOS oraz System Operacyjny,

sprawiaj¹ce razem, ¿e wypisanie informacji

na ekranie jest najprostsz¹ mo¿liw¹ rzecz¹,

tam w mikrokontrolerze... nie ma nic. Musie-

liœmy po kolei nauczyæ siê podstawowych

operacji na rejestrach, dopiero póŸniej wspi-

naæ siê coraz wy¿ej. Szczêœliwie rejestry

mamy ju¿ za sob¹. Dziœ na celu mamy dotar-

cie do funkcji printf oraz jej bliskich znajo-

mych. Dowiemy siê, jak realizowane s¹ ope-

racje strumieniowe – tak naturalne w du¿ych

maszynach. Nie bez znaczenia jest fakt

powstania nowej p³ytki. Funkcja printf, bar-

dzo uniwersalna i o wielkich mo¿liwoœciach,

zajmuje stosunkowo du¿o pamiêci programu.

„Hello world”

Stwórzmy folder na nowy program. Skopiuj

do niego plik makefile. Mo¿esz wzi¹æ go z

poprzednich programów albo te¿ bezpoœred-

nio z folderu C:\WinAVR\sample. W Program-

mers Notepadzie tworzymy nowy projekt.

Mo¿esz nazwaæ go na przyk³ad helloworld.

Do projektu dodajemy plik makefile i zaczy-

namy jego edycjê. Niezbêdne zmiany zazna-

czone s¹ na rysunku 37.

Teraz zgodnie z wprowadzonymi zmiana-

mi tworzymy g³ówny plik programu o nazwie

main.c. Dodajemy go do projektu w oknie

Programmers Notepada. W pliku tym wpisu-

jemy kod z listingu 52. Skompilowanie pro-

gramu przyniesie dwie niespodzianki:

1. Program zajmuje zaskakuj¹co du¿o miejsca

w pamiêci (u mnie ponad 1kB!).

2. Program w zasadzie nic nie robi, a raczej:

nie daje ¿adnych zewnêtrznych oznak dzia³ania.

Pierwszy problem zaskoczy³ mnie kiedyœ,

prawdopodobnie tak samo jak móg³ zasko-

czyæ teraz wiêkszoœæ Czytelników. Jego roz-

wi¹zanie wymaga nieco „gimnastyki”. Ze

wzglêdu na objêtoœæ materia³u poczekamy

z tym do czêœci 8. Teraz przyjrzyjmy siê prob-

lemowi z nicnierobieniem naszego programu.

Pytanie podstawowe brzmi: gdzie proce-

sor ma wys³aæ podany mu napis „Hello

world!”? W typowym programie

komputerowym bêdzie to zwyk-

le konsola... Nasza p³ytka posia-

da wyœwietlacz LCD, jednak

kompilator nic o tym nie wie.

Posiada tak¿e port szeregowy.

Wiele kompilatorów w³aœnie

port szeregowy uzna³oby za

domyœlne wyjœcie dla naszego

napisu. W AVR-GCC zosta³o to

rozwi¹zane inaczej. Domyœlnym

miejscem, gdzie dane bêd¹ wysy-

³ane, bêdzie pierwsze otwarte

urz¹dzenie. Zanim przejdziesz

dalej, zajrzyj do ramki „ABC... C

– Jak dzia³aj¹ strumienie”.

W ramach kursu nie mieliœ-

my jeszcze okazji zaj¹æ siê por-

tem szeregowym. Zróbmy to teraz. Zgodnie

z tym, czego nauczyliœmy siê do tej pory,

funkcje zwi¹zane z transmisj¹ danych umieœ-

cimy w oddzielnym module. Utwórz pliki rs.c

oraz rs.h. Pamiêtaj, aby do pliku makefile

dodaæ nowy plik kodu Ÿród³owego. Przypo-

minam o tym na rysunku 38. Kod, jaki nale-

¿y wpisaæ w plik rs.c, znajduje siê na listingu

53. Nie ma w nim nic niezwyk³ego – w prak-

tyce przyk³ady takie mo¿na znaleŸæ w doku-

mentacji technicznej procesorów AVR.

Listing 54 pokazuje kod, który powinien

znaleŸæ siê w pliku nag³ówkowym. Deklaru-

jemy tutaj funkcje, które zdefiniowane zosta-

³y w pliku Ÿród³owym. Od tej chwili bêdzie-

my mogli swobodnie u¿ywaæ ich wszêdzie

tam gdzie do³¹czymy plik rs.h.

Dodatkowo w naszym nag³ówku definu-

jemy dwa makra pomocne przy obliczaniu

danej wpisywanej do rejestru UBRR, która

wyznacza prêdktoœæ transmisji. Makro

pomocnicze RS_MAKE_UBRR jest przenie-

sieniem na C opisanego w dokumentacji spo-

sobu obliczania potrzebnej wartoœci. Sta³a

F_CPU deklarowana jest z poziomu pliku

makefile.

Zwracam Twoj¹ uwagê na fakt, jak

wa¿ne jest otoczenie nawiasami obliczeñ

makra RS_MAKE_UBRR. Wstaw w wy-

obraŸni zawarty w nim tekst – tak jak robi

to preprocesor – w miejscu wyst¹pienia

jego wywo³ania. Zauwa¿, co sta³oby siê,

gdyby nawiasów nie by³o. Szczególnie

widoczne jest to w miejscu, gdzie obliczo-

n¹ wartoœæ przesuwamy.

PP

PP

rr

rr

oo

oo

gg

gg

rr

rr

aa

aa

m

m

m

m

oo

oo

w

w

w

w

aa

aa

nn

nn

ii

ii

ee

ee

pp

pp

rr

rr

oo

oo

cc

cc

ee

ee

ss

ss

oo

oo

rr

rr

óó

óó

w

w

w

w

w

w

w

w

jj

jj

êê

êê

zz

zz

yy

yy

kk

kk

uu

uu

CC

CC

czêœæ 7

Rys. 37 Zmiany w pliku makefile

Listing 52 – wypisanie prostego tekstu

#include <avr\io.h>

#include <stdio.h>

iinntt

main((

vvooiidd

))

{{

puts((

„Hello world!”

));;

}}

Listing 53 – plik rs.c

#include <avr\io.h>

#include „rs.h”

iinntt

rs_put((

cchhaarr

znak))

{{

// Oczekiwanie a¿ bufor nadajnika jest pusty

wwhhiillee

((!!((

1

<<<<UDRE0 && UCSR0A)))) {}

UDR0 == znak;;

rreettuurrnn

0

;;

}}

iinntt

rs_get((

vvooiidd

))

{{

cchhaarr

znak;;

// Oczekiwanie na pojawienie siê danej

wwhhiillee

((!!((

1

<<<<RXC0 && UCSR0A)))) {}

znak == UDR0;;

rreettuurrnn

znak;;

}}

background image

Utwórz teraz ostatni potrzebny nam,

nowy plik. Zapisz go pod nazw¹ harddef.h.

Tak jak robiliœmy to poprzednio, zmieœcimy

w nim wszystkie definicje dotycz¹ce czêœci

sprzêtowej. Za tak¹ mo¿emy uznaæ prêdkoœæ

transmisji. Mo¿e wydaje Ci siê to bezcelowe

– tworzenie nowego pliku dla jednej tylko

danej. Jednak trzeba wzi¹æ pod uwagê, ¿e pro-

gram mo¿e siê rozrastaæ. Najlepiej od pocz¹t-

ku utrzymywaæ w nim porz¹dek. Zawartoœæ

wspomnianego pliku pokazuje listing 55.

Jeœli zaczynasz siê gubiæ w tym, co robi-

my, nie poddawaj siê teraz! Przed nami ostat-

nia prosta, która nada sens wszystkim naszym

dzia³aniom. Listing 56 pokazuje zmienion¹

funkcjê main. Teraz program po skompilowa-

niu i w³adowaniu danych do procesora

zacznie dzia³aæ zgodnie z naszym zamierze-

niem. Konieczne bêdzie pod³¹czenie p³ytki do

wolnego portu RS232 w naszym komputerze.

Do komunikacji wykorzystaæ mo¿na dowolny

program terminala. Mo¿e byæ to nawet termi-

nal wbudowany w œrodowisko BASCOM.

Transmisjê nale¿y skonfigurowaæ na:

Liczba bitów na sekundê: 4800

Bity danych: 8

ParzystoϾ: Brak

Bity stopu: 1

Rysunek 39 pokazuje efekt dzia³ania pro-

gramu. Po ka¿dym zerowaniu

procesor wyœle kolejny napis.

Zgodnie z dokumentacj¹, funk-

cja puts dodaje na koniec znak

nowej linii. Nie wprowadza jed-

nak znaku powrotu karetki, co

daje widoczny na rysunku

39 efekt. Nie ka¿dy termi-

nal zinterpretuje przesy³a-

ne dane w taki w³aœnie spo-

sób, jednak aby zupe³nie

pozbyæ siê problemu, mo-

¿emy napis zamieniæ na:

„Hello world!\r”

W ten sposób rêcznie dodamy przed

znakiem nowej linii znak powrotu karet-

ki i wszystkie nowe napisy u³o¿¹ siê

jeden pod drugim.

Jaki to ma sens

Dobrze wiêc... utworzyliœmy, zajmuj¹cy po-

nad 1KB pamiêci, program wypisuj¹cy za po-

moc¹ portu RS ³adne przywitanie. Pocz¹tek

nie wypad³ nam zachwycaj¹co. Zmniejszanie

zajêtoœci pamiêci zwi¹zane bêdzie z tematem,

który chcê omówiæ dopiero w

kolejnej czêœci. Teraz zajmijmy

siê poznaniem funkcji, która tak

naprawdê sprawia, ¿e biblioteka

stdio jest potê¿nym narzêdziem

Przeczytaj ramkê ABC... C –

printf, razem z do³¹czonymi do

niej tabelkami. Nie wygl¹da to

mo¿e w tej chwili najproœciej,

dlatego te¿ proponujê natych-

miast przejœæ do przyk³adu poka-

zanego na listingu 57. Jedyne,

co musisz zmieniæ, to zawartoœæ

funkcji main. Ze wzglêdu na

oszczêdnoœæ miejsca inicjacja

portu szeregowego, która nie

uleg³a zmianie, zosta³a wykrop-

kowana.

Dzia³anie przyk³adowego

programu pokazuje rysunek 40.

Pobaw siê tym kodem. SprawdŸ,

"

Programowanie

Elektronika dla Wszystkich

ABC... C

Jak dzia³aj¹ strumienie?

Pamiêtasz, jak do tej pory obs³ugiwaliœmy napisy na

wyœwietlaczu LCD? Pisaliœmy oddzielne funkcje do

wypisania ³añcucha znaków, do wypisania liczby

w formacie dziesiêtnym czy szesnastkowym.

Idea funkcji operuj¹cych na zasadzie strumieni

zdejmuje z nas obowi¹zek tworzenia wszystkich prze-

kszta³ceñ. Wymaga od nas jedynie stworzenia funkcji

wypisuj¹cej oraz odczytuj¹cej jeden znak. Genialnoœæ

pomys³u pokazuje rysunek w ramce:

Funkcje get i put

Dwie powy¿sze funkcje nie s¹ dok³adnie okreœlone

przez standard ANSI C. W AVR-GCC musz¹ one

mieæ formê jak poni¿ej:

iinntt

put((

cchhaarr

znak))

iinntt

get((

vvooiidd

))

Funkcja put powinna zwracaæ 0, jeœli wysy³anie

znaku przebieg³o pomyœlnie, w innym przypadku

zwracamy wartoœæ ujemn¹, co spowoduje przerwanie

dzia³ania operuj¹cej na niej funkcji – nawet jeœli

wszystkie jej dane nie zosta³y wys³ane. Podobnie sytu-

acja ma siê z funkcj¹ get. Tutaj jednak funkcja nor-

malnie zwraca odebran¹ dan¹, gdy wyst¹pi b³¹d, nale-

¿y zwróciæ wartoœæ ujemn¹.

Inicjowanie urz¹dzenia

Zak³adaj¹c, ¿e posiadamy ju¿ gotowe funkcje put oraz

get, musimy jeszcze poinformowaæ funkcje z bibliote-

ki stdio o tym, ¿e chcemy w³aœnie z nich korzystaæ.

Wykonujemy to za pomoc¹ funkcji fdevopen. Jej

sk³adniê przedstawiam poni¿ej:

fdevopen((put,, get,,

0

));;

Ostatni parametr jest niewykorzystany i powinien

mieæ zawsze wartoœæ 0. Po wywo³aniu jak wy¿ej,

podane funkcje zostan¹ przyporz¹dkowane, odpo-

wiednio, domyœlnemu wyjœciu oraz wejœciu. Od tej

chwili wywo³anie przyk³adowej funkcji puts z listingu

52 da oczekiwany efekt przes³ania kolejnych znaków

‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘ ‘ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’ ‘!’, kolejno do

funkcji put. Co z kolei w niej bêdzie siê dzia³o z prze-

s³anymi znakami, to ju¿ kwestia naszych potrzeb

i inwencji.

Listing 54 – plik rs.h

#ifndef RS_H_INCLUDED

#define RS_H_INCLUDED

#define RS_MAKE_UBRR(baud) (F_CPU/(baud*16l)-1)

#define RS_SET_BAUD(baud) \

{UBRR0H = (uint8_t)(RS_MAKE_UBRR(baud)>>8); \

UBRR0L = (uint8_t)RS_MAKE_UBRR(baud); }

iinntt

rs_put((

cchhaarr

znak));;

iinntt

rs_get((

vvooiidd

));;

#endif

// RS_H_INCLUDED

Listing 55 – plik harddef.h

#ifndef HARDDEF_H_INCLUDED

#define HARDDEF_H_INCLUDED

#define DEF_BAUD 4800

#endif

// HARDDEF_H_INCLUDED

Listing 55 – plik harddef.h

#ifndef HARDDEF_H_INCLUDED

#define HARDDEF_H_INCLUDED

#define DEF_BAUD 4800

#endif

// HARDDEF_H_INCLUDED

Listing 56 – zmiany w pliku main umo¿liwiaj¹ce dzia³anie programu

#include <avr\io.h>

#include <stdio.h>

#include „rs.h”

#include „harddef.h”

iinntt

main((

vvooiidd

))

{{

////////////////////////////////////////////

// Inicjacja portu szeregowego

RS_SET_BAUD((DEF_BAUD));;

UCSR0C ==

1

<<<<URSEL0 ||

1

<<<<UCSZ01 ||

1

<<<<UCSZ00;;

UCSR0B ==

1

<<<<RXEN0 ||

1

<<<<TXEN0;;

UCSR0A ==

0

;;

// Koniec inicjacji

////////////////////////////////////////////

// Inicjacja funkcji domyœlnych strumieni io

fdevopen((rs_put,, rs_get,,

0

));;

puts((

„Hello world!“

));;

}}

Rys. 38 Dodanie pliku rs.c

Rys. 39 Efekt dzia³ania programu

background image

jakie efekty da

podanie okreœlo-

nej szerokoœci lub

precyzji. Wypró-

buj ró¿ne flagi.

Spróbuj skorzys-

taæ tak¿e z typów

‘s’ oraz ‘S’.

Poniewa¿ jest

to doϾ ciekawe,

proponujê Ci zapoznanie siê z rysunkiem 41,

który pokazuje ostatni kod uruchomiony za

pomoc¹ programu AVRStudio. Spróbuj same-

mu przeprowadziæ pokazan¹ na nim symulac-

jê. Widzimy tutaj, w jaki sposób poszczegól-

ne argumenty s¹ przesy³ane do funkcji.

Widzimy, ¿e jest to jak najbardziej zgodne

z opisem w ramce o naszej funkcji. Zauwa¿,

¿e w tym przypadku tak¿e parametr okreœlaj¹-

cy adres ³añcucha formatowania przesy³any

jest przez stos. Informacja o tym znajduje siê

w dokumentacji do³¹czonej do WinAVR... nie

ma dla nas tak du¿ego znaczenia przesy³anie,

nieznanej nam wczeœniej, otwartej listy argu-

mentów.

Pamiêæ programu

Jeœli w którymœ momencie zada³eœ sobie pyta-

nie, dlaczego ci¹gle umieszczam ³añcuchy w

pamiêci danych, zamiast jak ju¿ pokazywaliœmy

"#

Programowanie

Elektronika dla Wszystkich

ABC... C

printf

Dowolnoœæ argumentów... jak to dzia³a?

Sk³adnia funkcji printf wygl¹da nastêpuj¹co:

iinntt

printf((

ccoonnsstt cchhaarr

fmt,,......))

Widoczne trzy kropki to nie ¿adne wprowadzone

przeze mnie uproszczenie. To doœæ ciekawa oraz ca³-

kowicie formalna cecha jêzyka C. Trzy kropki poja-

wiaj¹ siê zawsze za ostatnim argumentem. Nie mo¿na

za nimi umieœciæ jeszcze kolejnego, ustalonego argu-

mentu. Format, z jakim mamy tutaj do czynienia ozna-

cza, ¿e zaraz za parametrem fmt mo¿emy umieœciæ

dowoln¹ iloœæ dowolnych parametrów.

Pierwszym parametr nazywany jest z angielska

„Format String”, co mo¿na t³umaczyæ jako ³añcuch

formatuj¹cy. W nim zawarte s¹ informacje, jakie para-

metry zosta³y wprowadzone i z jego pomoc¹ s¹ one

odzyskiwane. Sposób podawania odpowiednich infor-

macji pojawi siê za chwilê, teraz jednak skupmy siê na

reszcie argumentów.

Ka¿dy kolejny argument, wpisany w miejsce

trzech kropek, jest umieszczany na stosie. Jednak

wrzucane s¹ one „od ty³u”. W efekcie, w chwili

wywo³ania funkcji, pierwszy argument znajduje siê na

samym szczycie stosu i mo¿e byæ jako pierwszy

z niego zdjêty. Zmienne zdejmowane bêd¹ od naj-

m³odszego bajtu do najstarszego.

W ten sposób mo¿na do funkcji przekazaæ argu-

menty w objêtoœci ograniczonej jedynie pojemnoœci¹

pamiêci przeznaczonej na stos. Jest to niezwykle

wygodne w funkcji takiej jak printf, gdzie nie da siê

okreœliæ, jakie argumenty bêd¹ potrzebne, jednak

z mo¿liwoœci tej trzeba korzystaæ bardzo ostro¿nie...

Ryzyko i wady rozwi¹zania

Osoby obeznane trochê z programowaniem zdaj¹

sobie sprawê z tego, jak wa¿nym elementem jest stos.

Jakikolwiek b³¹d w przep³ywie informacji miêdzy sto-

sem a rejestrami mo¿e skutkowaæ zawieszeniem siê

ca³ego programu. Trzeba zdaæ sobie sprawê, ¿e o ile

w przypadku zwyczajnych funkcji, z ustalonymi para-

metrami, to kompilator dba o prawid³ow¹ obs³ugê

stosu, nie jest on w stanie pilnowaæ jego dzia³ania, gdy

korzystamy z otwartej listy argumentów. Gdy decydu-

jemy siê na takie dzia³anie, to na nas spoczywa odpo-

wiedzialnoœæ za prawid³owe jego funkcjonowanie.

Kompilator nie bêdzie tak¿e w stanie sprawdziæ, czy

podawane argumenty s¹ w³aœciwego typu. Bardzo

wa¿ne jest wiêc, aby podane argumenty zgadza³y siê

z tym, co deklarujemy w ³añcuchu formatowania.

W innym przypadku funkcja printf mo¿e nie zdj¹æ

wszystkich informacji ze stosu. Mo¿e tak¿e zdj¹æ ich

zbyt wiele. B³¹d stosu mo¿e spowodowaæ, ¿e dalej, do

rejestrów wpisane zostan¹ przypadkowe dane.

W skrajnym przypadku œmieci zostan¹ wprowadzone

do licznika rozkazów... rozumiesz na pewno, co siê

wtedy stanie.

Oprócz koniecznej ostro¿noœci trzeba zwróciæ

uwagê na jeszcze jedn¹ sprawê. Jeœli wywo³ywana

funkcja posiada jedynie sta³e

argumenty, w miarê mo¿li-

woœci s¹ one umieszczane

bezpoœrednio w rejestrach.

Odpowiedni podprogram w

chwili uruchomienia zna

dok³adnie typy wszystkich

argumentów – ma je podane

niejako „na tacy”. Jeœli na-

tomiast wywo³ujemy funkcjê

z otwart¹ list¹ parametrów,

wszystkie one musz¹ zostaæ

umieszczone na stosie. Wy-

maga to dodatkowego czasu

oraz kodu przed wywo³aniem

podprogramu. Sam podpro-

gram tak¿e musi byæ bardziej

rozbudowany.

Ogólnie, jeœli to mo¿li-

we, funkcji tego typu raczej

siê unika. Czasami jednak

jest to albo jedyne... albo naj-

lepsze rozwi¹zanie – mimo

wszystkich wad.

Format

Wiemy ju¿ co i jak siê dzieje

w naszej funkcji. Teraz do-

wiemy siê, jak j¹ wykorzys-

taæ. Bardzo wa¿ny jest ³añ-

cuch formatuj¹cy. To w nim

zawarta jest informacja o przekazanych paramet-

rach oraz o sposobie, w jaki zostan¹ one

wyœwietlone. Znaki z ³añcucha formatuj¹cego s¹

wysy³ane bezpoœrednio na wyjœcie do chwili

natrafienia na znak ‘%’. Znaki wystêpuj¹ce za

nim s¹ interpretowane jako informacja o kolej-

nym argumencie.

Rysunek powy¿ej pokazuje format opisu

argumentu oraz sposobu jego wyœwietlenia.

Z naszego punktu widzenia, najwa¿niejsza jest

informacja o typie argumentu. Oznaczenia po-

szczególnych typów przedstawia tabela 6. Nie

sugeruj siê zbyt mocno podanymi tam typami

zmiennych. Najwa¿niejsze jest zachowanie ich

rozmiaru. Pod tym wzglêdem int oraz unsigned

int s¹ identyczne.

Przydatne flagi zamieœci³em w tabeli 7.

Nasz kompilator udostêpnia tylko jeden

modyfikator: ‘l’ oznaczaj¹cy, ¿e zamiast zmien-

nej typu int podajemy zmienn¹ typu long int.

Znaczenie precyzji oraz szerokoœci wyjaœnia

dodatkowa, niewielka ramka.

printf – pola precyzja oraz szerokoœæ

Znaczenie pola precyzji zmienia siê zale¿nie od typu.

Dla typów zmiennoprzecinkowych oznacza ono liczbê

miejsc po przecinku. Dla typów numerycznych –

minimaln¹ liczbê cyfr (dope³nienie zerami, niezale¿-

nie od flagi ‘ ‘). Dla ³añcuchów oznacza maksymaln¹

liczbê znaków, jaka ma zostaæ wypisana.

Jeœli d³ugoœæ napisu tworzonego przez dane prze-

kszta³cenie jest mniejsza ni¿ szerokoœæ, dodawane s¹

spacje, wzglêdnie zera (flaga ‘0’) po lewej lub prawej

(flaga ‘-’) stronie napisu. Parametr ten nigdy nie

powoduje przyciêcia wyniku.

Rys. 40 Dzia³anie

programu
z listingu 57

Tabela 6 – oznaczenia typów w ³añcuchu

formatowania

Tabela 7 – flagi w ³añcuchu formatowania

background image

sobie – w pamiêci programu... Bardzo siê

z tego pytania cieszê. Jeœli jeszcze tego nie

zrobi³eœ – popatrz na wynik symulacji. £añ-

cuch zajmuje cenn¹ pamiêæ RAM, jednoczeœ-

nie do jej inicjacji konieczna jest kopia

danych w pamiêci ROM.

Omawiane funkcje, tak jak wiêkszoœæ

z wystêpuj¹cych w AVR-GCC, posiadaj¹

specjalne wersje z przyrostkiem _P. Zmodyfi-

kuj poprzedni program zgodnie z listingiem

58. Konieczne bêdzie dodanie do programu

nag³ówka <avr\pgmspace.h>. Efekt zmiany

mo¿na zaobserwowaæ w symulacji na rysun-

ku 42. Od strony funkcjonalnej nie powinny

pojawiæ siê widoczne zmiany.

Na identycznej zasadzie mo¿esz zmodyfi-

kowaæ pierwszy z programów.

Podsumowanie

Dziœ poznaliœmy bardzo wa¿n¹ funkcjê z bib-

lioteki standardowej C. Wykorzystaliœmy j¹

w jeden z najprostszych sposobów. Praktyka

jest jednak taka, ¿e w AVR-GCC, standardo-

we funkcje wejœcia/wyjœcia, dzia³aj¹ce na

domyœlnych strumieniach nie zosta³y dobrze

zoptymalizowane. Musimy liczyæ siê z tym,

¿e jest to jednak narzêdzie darmowe i czasami

daje to odczuæ. Jest jednak szansa na poprawê

– mia³em okazjê testowaæ najnowsze bibliote-

ki i ich dzia³anie rzeczywiœcie zosta³o popra-

wione. Jednak dopóki nie powstanie nowa

wersja ca³ego pakietu, zmiana bibliotek

wymaga rêcznych modyfikacji. W najbli¿-

szym odcinku bêdziemy pracowaæ na stru-

mieniach innych ni¿ domyœlne – okazuje siê,

¿e funkcje te s¹ lepiej optymalizowane, jeœli

chodzi o rozmiar kodu. Dodatkowo daje to

mo¿liwoœæ wykorzystania tych samych pod-

programów do wysy³ania danych przez

RS232 czy na LCD, co sprawia, ¿e poznawa-

na biblioteka staje siê coraz ciekawsza.

Rados³aw Koppel

radoslaw.koppel@elportal.pl

"$

Programowanie

Elektronika dla Wszystkich

Rys. 41 – przesy³anie argumentów do funkcji printf

Rys. 42 Efekt umieszczenia ³añcucha formatowania w pamiêci programu

Listing 57 – wykorzystanie funkcji printf

iinntt

main((

vvooiidd

))

{{

iinntt

a ==

1234

;;

iinntt

b ==

0xff

;;

((......))

fdevopen((rs_put,, rs_get,,

0

));;

printf((

„a(%%d)=%d\r\n”

„a(%%x)=%x\r\n”

„a(%%X)=%X\r\n”

„b(%%#x)=%#x\r\n”

„b(%%o)=%o\r\n”

,,

a,, a,, a,, b,, b));;

}}

Listing 58 – wykorzystanie pamiêci programu

dla ³añcucha formatowania

printf_P((PSTR((

„a(%%d)=%d\r\n”

„a(%%x)=%x\r\n”

„a(%%X)=%X\r\n”

„b(%%#x)=%#x\r\n”

„b(%%o)=%o\r\n”

)),,

a,, a,, a,, b,, b));;

R

E

K

L

A

M

A

Zastosowanie: Œrodek penetruj¹cy i smaru-

j¹cy, przenikaj¹cy rdzê, wypieraj¹cy wodê,

myj¹cy z brudu i kurzu

Opis: CRC 5-56 - wielofunkcyjny preparat dla

potrzeb serwisowych. Œrodek penetruj¹cy i

smaruj¹cy, przenikaj¹cy rdzê, wypieraj¹cy

wodê, myj¹cy z brudu i kurzu. Sk³ada siê z

oleju parafinowego, organicznych inhibitorów

korozji co pozwala na utworzenie bariery chro-

ni¹cej przed dostêpem wody i tlenu.

W³asnoœci:

n

szybko penetruje, wnikaj¹c w najmniejsze

pory, szczeliny w rozwiniêtej powierzchni-

dobre w³asnoœci smarne- wypiera wilgoæ

z uk³adów elektrycznych i zap³onowych

n

luzuje zardzewia³e po³¹czenia

n

tworzy cienk¹ warstwê ochronn¹, przeciw-

dzia³aj¹ca korozji wywo³anej wp³ywami atmos-

ferycznymi

n

nie oddzia³uje z metalami i ich stopami

n

nie oddzia³uje z wiêkszoœci¹ plastików, gum,

powierzchni lakierowanych (w razie w¹tpli-

woœci - zalecany test technologiczny)

n

opakowania aerozolowe wyposa¿one s¹ w

zawór 360° dzia³ania oraz cienk¹ rurkê aplika-

cyjn¹.

n

Gaz pêdny - niepalny CO2 - co skutkuje

97% wykorzystaniem aktywnego preparatu

Sposób u¿ycia:

n

Na³o¿yæ preparat i pozwoliæ na jego penet-

racjê

n

Dla uruchomienia zawilgoconego silnika,

nanieœæ preparat na cewkê i przewody zap³onu

n

W przestrzeniach o trudnym dostêpie u¿yæ

rurki aplikacyjnej

n

W razie potrzeby CRC 5-56 mo¿na usun¹æ,

zmyæ wykorzystuj¹c CRC Brakleen lub CRC

Quickkleen
Dane techniczne (bez gazu pêdnego)

Kolor . . . . . . . . . . . . . . . przeŸroczysta ciecz

o lekko bursztynowym zabarwieniu

Ciê¿ar w³aœciwy (20°C) . . . . . . . . 0,82 g/cm

3

Punkt zamarzania . . . . . . . . . . . . . . < -50°C

Punkt zap³onu . . . . . . . . . . . . . . . . . . . 78°C

Gruboœæ warstwy (24 godz., 20°C) . . . . 1-2u

Wydajnoœæ z 1l (20°C ) . . . . . . . . . . . 100m

2

Odpornoœæ termiczna . . . . . . . . . . . . . 120°C

(150°C - nara¿enie chwilowe)

CRC 5−56 − wielofunkcyjny preparat dla potrzeb serwisowych

Zamówienia przyjmuje Dział Handlowy AVT, 01−939 Warszawa, ul. Burleska 9, tel. (22) 568 99 50, fax (22) 568 99 55, e−mail: handlowy@avt.pl

w w w. s k l e p . a v t . p l

200 ml

kod handlowy:

KON36

cena:

10 z³


Wyszukiwarka

Podobne podstrony:
kursC czesc006
kursC czesc001
kursC czesc003
kursC czesc006a przeprowadzka
kursC czesc000 programowanie
kursC czesc018
kursC czesc008
kursC czesc002
kursC czesc013
kursC czesc011
kursC czesc010
kursC czesc018

więcej podobnych podstron