trzech elementów zawiera błędy? W zasadzie bardzo trudno jest odpowiedzieć na tak postawione pytanie. Intuicyjnie wiadomo, że trudniej jest rozwiązać układ równań z trzema niewiadomymi niż równanie z jedną niewiadomą. Dlatego warto zmienić podejście i pisać kod po kawałku. Na początek obsługa SPI. Powinna ona zapewniać możliwość poprawnej komunikacji z układem pamięci. Problem jak zwykle stanowi znalezienie testu, który pozwoli określić, czy kod obsługujący SPI jest poprawny. W przypadku pamięci Flash (AT45DBxxx) dokumentacja producenta podpowiada, jakiego testu użyć. Na rysunku 2 pokazana jest odpowiedź znaleziona w dokumentacji. Jest to rejestr statusowy, który ma cztery bity zawsze stałe. Co więcej, nietrudno zgadnąć, że najstarszy bit tego rejestru będzie miał wartość 1, gdyż pamięć nie będzie zajęta, bo nie została jeszcze zmuszona do żadnej operacji. To jest właśnie element, który sprawia, że „równanie” ma tylko jedną niewiadomą, którą stanowi port SPI. Jeżeli uda się ten port oprogramować w taki sposób, aby po odczycie rejestru statusowego te pięć bitów się zgadzało z założeniami, to można przyjąć, żc obsługa SPI działa poprawnie. Szanse na szybsze ukończenie pracy nad modułem pamięci są większe, gdyż teraz w razie problemów z zapisem należy szukać błędów tylko w procedurach odpowiedzialnych za odczyt lub zapis rejestrów, a nie samym sposobie komunikacji. Oprogramowując jakiś czas temu ten układ pamięci, postąpiłem właśnie w ten sposób i pozwoliło to zaoszczędzić sporo czasu.
Innym źródłem trudnych do wykrycia błędów mogą być niewłaściwie ustawione porty I/O. Przykładowo tworząc projekt ze wspomnianą powyżej pamięcią, trzeba (oprócz linii portu SPI) przygotować linię CS do uaktywniania lej pamięci.
Problem pojawi się w momencie, gdy z jakiegoś powodu należy zmienić port obsługujący
wejście CS. Może to być _
spowodowane zmianami w układzie, użyciem biblioteki w innym projekcie bądź błędami logicznymi (np. użyty port jest typu open-collector). W takiej sytuacji trzeba zmienić wszystkie odwołania do starego portu na odwołania do nowego portu. Robiąc to ręcznie, nietrudno przeoczyć jedną lub dwie stare instrukcje w którymś miejscu programu. Powoduje to oczywiście nieprawidłową pracę pamięci i wymusza sprawdzanie po kolei wszystkich aspektów pracy układu, prowadzenie testów, etc.
W takiej sytuacji znacznie lepiej zamienić stary port na nowy w sposób automatyczny, za pomocą narzędzia replace all. Jeszcze lepszym wyjściem jest tworzenie „sterowników” urządzeń, czyli maki' (instrukcja define) lub prostych funkcji do obsługi danego wyprowadzenia.
Pewien zdradziecki błąd pokazano na listingu 1. Czy potrafisz wskazać, co w tym kodzie jest nie tak, nic patrząc na dalszą część tekstu? Okazuje się, że winny jest pewien drobiazg, mianowicie w linii 15 zamiast zmiennej key2 jest zmienna keyl. Pomyłki tego typu są skutkiem kopiowania bloku kodu i wklejania go. Wystarczy chwilowe rozproszenie uwagi (np. zadzwoni telefon), aby zapomnieć o zmianie fragmentów w skopiowanym kodzie. Są to również uciążliwe błędy sprawiające problemy z ich wyszukaniem. Dlatego kopiując fragment kodu, należy zachować daleko posuniętą ostrożność i w sposób systematyczny dokonywać w nim zmian.
char key (){
char result = 0 ;
//przycisk 1
if(!(PINB&DEVICE_KEY_1)){ delay_ms(20) ;
Tf(!(PINB&DEVICE_KEY_1)&&(keyl==false)){ keyl = true ; result |= DEVICE KEY 1;
} “ “
}else{keyl = false ;}
//przycisk 2
if(! (PINB &DEVICE_KEY_2)){ delay_ms(20) ;
Tf (! (PINB&DEVICE__KEY_2) && (key2=false) ) { keyl = true ; result |= DEVICE KEY 2;
}
}else{key2 = false ;}
//przycisk 3
if(!(PINB&DEVICE_KEY_3)){ delay_ms(2( ) ;
Tf (! (PINB &DEVICE_KEY_3) && (key3=false)) { key3 = true ; result |= DEVICE KEY 3;
} “ “
}else{key3 = false ;}
return result; //zwroc rezultat |_istirsg1
Diagnozując błędy w oprogramowaniu, warto zapewnić sobie jakieś źródło informacji zwrotnej. Wspomniano już, że nadaje się do tego wyświetlacz LCD, gdyż umożliwia zapisanie zarówno tekstu, jak i wartości liczbowych. Problem stanowi jedynie fakt, że nie znajduje się on w każdym urządzeniu. Podłączenie wyświetlacza do układu, który go nie zawiera, nastręcza pewnych problemów. Konieczne jest wtedy doprowadzenie 6 linii
Status Register Format
Bit 7 |
Bit 6 |
Bit 5 |
Bit 4 |
Bit 3 |
Bit 2 |
Bit 1 |
BitO |
RDY/3USY |
COMP |
0 |
0 |
1 |
1 |
X |
X |
Rys. 2
Rys. 3
F1 0.3A
f=l-
Z1 USB
L1 820uH
16
15
8
19
24
27
28
17
VCCIO |
TXD | |
vcc |
RXD | |
RTS# | ||
USBDM |
CTS# | |
USBDP |
DTR# | |
DSR# | ||
NC |
DCD# | |
RESET# |
RJ# | |
NC |
CBUSO | |
OŚCI |
CBUS1 | |
OSCO |
CBUS2 | |
CBUS3 | ||
3V30UT Q Z O |
Q |
CBUS4 O £ |
O z |
Z |
Z u] |
< O |
o |
O H |
12
C2
100n
in |
oo |
CD | ||
GND ^ |
i-< |
)-( |
CM i-I |
CM i-< |
VCCO—
Schottky
D1
JP1
USB PORT
1 TxD / |
\Ix |
dE |
1 9 | |
5 RxD / |
VDTR - |
Z o | ||
3 RTS / |
\RTS £ |
O A | ||
11 CTS/ |
VRxD E |
4* c | ||
2 DTR/ |
\ |
CTS |
O a | |
9 10 6 |
o I 7 8 |
23
22
13
14
;c3
4.7u
I/O do tego elementu (D7, D6. D4, D4, ENA, RS), co nie zawsze jest możliwe.
Inną alternatywą jest użycie portu szeregowego. Nawet gdy nic jest on obecny w projektowanym układzie, wystarczy wyprowadzenie tylko jednej linii, co sprawia, że nie jest to szczególnie skomplikowane i prawie zawsze daje się przylutować na pająka jeden przewód do płytki drukowanej. Port szeregowy jest na tyle prostym układem, żc nawet nie jest potrzebne korzystanie z dedykowanego, sprzętowego układu USART. Transmisję z mikrokontrolera do komputera można zawrzeć w dosłownie kilku linijkach kodu. Co prawda port RS232 jest obecnie rzadkością, ale nie jest problemem, aby użyć prostego konwertera opartego na układzie FT232. Przykładowy schemat zastał pokazany na rysunku 3 (wzór PCB można znaleźć pod adresem http://dportal.pl/ftp 05/200803dyry-gent.zip). Warto wykonać taki układ we własnym zakresie i używać go przy wyszukiwaniu błędów. Można również kupić gotowe moduły w sklepie AVT (np. ZLIUSB czy ZL2USB). Zaletą portu USART
_ jest większa prędkość pracy
niż w przypadku wyświetlacza LCD i możliwość gromadzenia danych na ekranie komputera. W skład środowiska WinARM wchodzi bardzo przyjazny program {Terminal. exe), który umożliwia podłączenie się do portu szeregowego i bardzo elastyczne konfigurowanie prędkości. Można do tego celu wykorzystać również standardowy Hyper Terminal systemu Windows. Przy tak przygotowanym module i terminal możliwe jest wyświetlanie zarówno ciągów tekstowych jak i liczb. Warto zauważyć, że dane odbierane w oknie
:C4 100n
E2 Styczeń 2010 Elektronika dla Wszystkich