Bezpłatna biblioteka techniczna ENCYKLOPEDIA RADIOELEKTRONIKI I INŻYNIERII ELEKTRYCZNEJ Modułowe programowanie układów sterowania na MCS48. Encyklopedia elektroniki radiowej i elektrotechniki Encyklopedia radioelektroniki i elektrotechniki / Mikrokontrolery Wiadomo, że ten sam mikrokontroler może sterować zarówno skomplikowanymi urządzeniami technologicznymi, jak i domowym młynkiem do kawy czy zegarem elektronicznym. Dostosowanie do konkretnego obiektu odbywa się poprzez zmianę programu mikrokontrolera, prawie nie ma to wpływu na sprzęt. Proponowany artykuł jest poświęcony technikom programowania mikrokontrolerów serii MCS48, które są szeroko stosowane w układach sterowania do różnych celów. Jej główne postanowienia dotyczą również nowocześniejszych urządzeń. Rozwój i modernizacja programów sterujących jest znacznie ułatwiona, jeśli są one zbudowane zgodnie z zasadą modułową. W tym przypadku, po zdobyciu pewnego doświadczenia, a co najważniejsze własnej biblioteki debugowanych modułów, zaprogramowanie nowego systemu sterowania (CS) sprowadza się do wymiany niektórych modułów już istniejącego i debugowanego programu i ewentualnego uzupełnienia go o fragmenty, które wziąć pod uwagę specyfikę konkretnego systemu. Zasada ta jest osadzona w strukturze wielu języków wysokiego poziomu (PASCAL, C++), a programista jest dosłownie zmuszony do jej przestrzegania. Niestety ASSEMBLERY (w tym dla MSS48), dając programiście większą swobodę wyboru środków i metod rozwiązywania problemów, z reguły w ogóle nie monitorują przestrzegania dyscypliny programistycznej. Często prowadzi to do tworzenia programów tak zagmatwanych, że nawet ich autorzy nie mogą po pewnym czasie zorientować się, co zostało zrobione, nie mówiąc już o wykorzystaniu debugowanych fragmentów w innych programach. Świadome przestrzeganie wspólnych koncepcji modułowych znacznie ułatwia i przyspiesza programowanie mikrokontrolerów. Przykład typowego programu modułowego dla CS podano w tabeli. Jego składnia odpowiada składni tabelarycznej ASSEMBLY TASM dla mikroprocesora 8048. Jak widać, na początku tekstu programu dyrektywy EQU nadają stałe nazwy i przypisują wartości. Używanie nazwanych stałych jest zawsze lepsze niż określanie wartości liczbowych bezpośrednio w wykonywalnych instrukcjach procesora. Na przykład opóźnienie czasowe realizowane przez jeden z omówionych poniżej podprogramów jest określone przez trzy liczby. Są one określone przez stałe N1, N2 i N3. Jeśli potrzebujesz zmienić czas otwarcia migawki, wystarczy podać nowe wartości w operatorach EQU. W przeciwnym razie należałoby przeszukać cały program instrukcji z argumentami równymi tym liczbom, zdecydować, czy każdy z nich odnosi się do opóźnienia czasowego i wskazać nowe wartości w niezbędnych przypadkach. Oczywiście taka praca wymaga dużo czasu i często nie obywa się bez błędów. Jest to szczególnie skomplikowane przez fakt, że niektóre polecenia mogą nie używać całej liczby, ale na przykład jej wysoki lub niski bajt. ASSEMBER już na etapie tłumaczenia programu jest w stanie obliczyć pewne stałe na podstawie wartości innych. Możliwość tę ilustruje obliczenie bajtów wysokiego (N3N) i niskiego (N3L) liczby NXNUMX. Następnie program przydziela pamięć dla zmiennych. Robią to tymi samymi dyrektywami EQU, ale w przeciwieństwie do opisów stałych, określają nie wartości liczbowe zmiennych, ale adresy komórek pamięci, które zajmują. Jeśli ASSEMBLER na to pozwala, nie należy zaniedbywać możliwości korzystania z makr. Każda z nich jest niejako nową instrukcją wykonującą operację, której nie przewiduje bezpośrednio system instrukcji procesora. Opisując makroinstrukcję, programista nadaje jej nazwę (która oczywiście nie pokrywa się z nazwą żadnej z „prawdziwych” instrukcji) oraz określa wymagane działania w postaci Sekwencji instrukcji maszynowych. Za każdym razem, gdy napotka makroinstrukcję w programie, ASSEMBLER zastąpi ją określoną sekwencją. W tym przykładzie używane są dwa makra. Jeden z nich przenosi zawartość akumulatora do komórki pamięci danych określonej parametrem makro, a drugi z powrotem. Po włączeniu zasilania (lub podaniu sygnału resetu) mikrokontroler rozpoczyna wykonywanie programu od adresu zerowego. Ten adres jest zwykle używany do zapisywania bezwarunkowego polecenia skoku do rzeczywistego punktu startowego programu (w tym przypadku etykiety START). Jest to konieczne, ponieważ przerwania sprzętowe zawsze przekazują sterowanie na stałe adresy 3 i 7 (dla innych typów mikrokontrolerów adresy mogą być inne, ale nadal znajdują się na początku pamięci programu). Polecenia bezwarunkowego przejścia do procedur serwisowych odpowiednich przerwań znajdujących się pod tymi adresami mają być „obejmowane” przez program główny. Kolejnym krokiem jest ustawienie trybów pracy sterownika (np. wybór banków pamięci i rejestrów), inicjalizacja zmiennych oraz urządzeń zewnętrznych. Typowym błędem początkujących programistów jest założenie, że zaraz po uruchomieniu programu zmienne mają już jakieś określone wartości. To błędne przekonanie jest wzmocnione przez fakt, że niektóre języki wysokiego poziomu (takie jak BASIC) automatycznie ustawiają wszystkie zmienne na wartość początkową równą zero. W programach w asemblerze (i wielu innych językach) programista sam musi zadbać o to, aby przed pierwszym odczytaniem wartości zmiennej coś zostało już zapisane w przydzielonej jej komórce pamięci. Dobry styl programowania wymaga, aby na samym początku programu nadać zmiennym wartości początkowe. W tym przypadku odbywa się to za pomocą podprogramu 1INIT. Sekcja inicjalizacji urządzenia zewnętrznego zwykle wygląda jak alternatywne wywołanie podprogramów, z których każdy resetuje jeden z nich (przetwornik analogowo-cyfrowy, wskaźnik LED, klawiatura itp.) i można go łatwo wymienić podczas finalizowania i ulepszania systemu. Często te same procedury sprawdzają stan urządzeń. Następnie większość programów sterujących wchodzi w powtarzającą się w nieskończoność pętlę główną, której wykonanie jest wstrzymywane tylko w celu obsługi przerwań. Cykl składa się z podprogramów odpytywania klawiatury i innych czujników, sprawdzania flag ustawionych przez podprogramy obsługi przerwań (np. informacje otrzymane zgodnie z zadanym algorytmem sterowania, wyprowadzanie akcji sterujących do elementów wykonawczych, wyświetlanie informacji o stanie procesu technologicznego na wyświetlaczu ciekłokrystalicznym lub innych wskaźnikach. Wyjście z pętli głównej zapewniane jest zwykle tylko w sytuacjach awaryjnych, np. gdy w celu wyeliminowania skutków awarii konieczne jest powtórzenie inicjalizacji wszystkich zmiennych i urządzeń zewnętrznych, a także przy przetwarzaniu przerwań. Zatem program zbudowany na zasadzie modułowej jest zbiorem podprogramów. Jeśli np. w nowym systemie sterowania zastosowano inną klawiaturę, wystarczy wymienić podprogram BUTT. Aby taka wymiana była prosta i bezbolesna, należy wypracować pewne zasady i zawsze ich przestrzegać. Podprogramy, jeśli to możliwe, powinny zapisywać zawartość wszystkich rejestrów kontrolera, odbierać dane początkowe i wydawać wyniki w tych samych rejestrach i komórkach pamięci, stosować to samo kodowanie znaków itp. Trzeba walczyć z naturalną (zwłaszcza dla programistów, którzy pokonali pierwsze trudności i zaczynają czuć się jak profesjonaliści) chęcią upraszczania programu poprzez odejście od sztywnych reguł i zastosowanie niestandardowych technik. Pozornie na pierwszy rzut oka nieuzasadniona komplikacja w pełni się opłaci, ułatwiając debugowanie i przerabianie programu jako całości. Rozważmy niektóre cechy podprogramów. NCREM i DESREM wykonują wymaganą w wielu przypadkach operację zwiększania lub zmniejszania o zadaną wartość 16-bitowej liczby binarnej (jej wysoki i niski bajt znajdują się odpowiednio w rejestrach R6 i R5). Stałe określające wielkość przyrostu są opisane na początku programu. Ponieważ każdy mikrokontroler działa znacznie szybciej niż sprzęt technologiczny, bardzo ważna jest możliwość zorganizowania opóźnienia czasowego w programie. W tym przypadku używany jest wewnętrzny licznik/timer procesora. Ma ograniczoną pojemność i przelewa się w ciągu milisekund. Każde przepełnienie generuje żądanie przerwania. Procedura obsługi przerwań czasowych (TIME) zlicza je i po osiągnięciu określonej liczby ustawia flagę limitu czasu FLT na jeden. Wszystkim podprogramom, których działanie zależy od czasu, pozostaje przeanalizować stan tej flagi. Możliwe jest więc uzyskanie czasów otwarcia migawki wynoszących kilka sekund, a nawet minut. Aby rozpocząć odliczanie nowego interwału, konieczne jest wprowadzenie wartości początkowych w komórki robocze podprogramu CZAS i włączenie timera. Na przykład podprogram SET2M ustawia opóźnienie czasowe na 2 minuty. Obliczanie wartości początkowych ma kilka subtelności. Wiadomo, że w mikrokontrolerach serii MSS48 impulsy docierają na wejście wewnętrznego licznika/timera z częstotliwością 480 razy niższą od częstotliwości oscylatora kwarcowego. Na przykład przy częstotliwości rezonatora kwarcowego 7 MHz liczba zapisana na liczniku zmienia się co 480/7000000 = 0,00006857 s = 68,57 µs. Tak więc licznik przepełni się (i wygeneruje żądanie przerwania) w 68,57 -(256-N1) µs, gdzie N1 jest liczbą pierwotnie zapisaną w liczniku. Jeśli za każdym razem, gdy rozpoczniesz nowe odliczanie od tej liczby, to N0,1 = 2 0,1/[7000000 (1480-N256)] przepełnień wystąpi w ciągu 1 s (minimalne opóźnienie). Oczywiście to samo opóźnienie czasowe można uzyskać z różnymi N1 i N2, ale ponieważ te liczby nie mogą być ułamkowe, zostanie to zaimplementowane z pewnym błędem. Zadanie polega na wybraniu takiej pary wartości, dla której błąd jest minimalny. W rozważanym przypadku najlepszą opcją jest N1 = 13, N2 = 6. Zwłokę czasową 2 min uzyskuje się powtarzając opisaną procedurę N3 = 1200 razy. Często konieczne jest stosowanie różnych procedur przetwarzania tych samych przerwań sprzętowych w różnych trybach pracy programu. Jednym ze sposobów wykonania tego jest podprogram INTER. Analizuje kod typu przerwania wprowadzony przez program główny w komórce INTT iw zależności od jego wartości wywołuje jedną z procedur obsługi przerwania ISR1 lub ISR2. Zauważ, że oba kończą się na RET, a nie na RETR. Łatwo jest zwiększyć liczbę opcji przetwarzania, a nawet sprawić, aby dla określonej wartości kodu kilka różnych podprogramów było wywoływanych jeden po drugim. Nie jest konieczne zapisywanie wszystkich niezbędnych podprogramów w pliku tekstowym programu głównego. Moduły debugowane i wielokrotnie używane w różnych programach można umieścić w osobnych plikach i połączyć z programem głównym za pomocą dyrektyw INCLUDE. Każdy plik dołączany może zawierać jedną lub więcej procedur. Wadą tej metody jest to, że nazwy zmiennych, stałych i etykiet we wszystkich używanych modułach nie powinny się powtarzać. Pozbawiona tej wady metoda oddzielnej translacji modułów z późniejszym ich łączeniem na poziomie kodu wynikowego niestety nie jest wspierana przez TASM ASSEMBLY. Autor: D. Ryżow, Władimir Zobacz inne artykuły Sekcja Mikrokontrolery. Czytaj i pisz przydatne komentarze do tego artykułu. Najnowsze wiadomości o nauce i technologii, nowa elektronika: Nowy sposób kontrolowania i manipulowania sygnałami optycznymi
05.05.2024 Klawiatura Primium Seneca
05.05.2024 Otwarto najwyższe obserwatorium astronomiczne na świecie
04.05.2024
Inne ciekawe wiadomości: ▪ Nowy moduł RF oparty na CC1100 trafił na rynek Wiadomości o nauce i technologii, nowa elektronika
Ciekawe materiały z bezpłatnej biblioteki technicznej: ▪ sekcja witryny Regulacja tonu i głośności. Wybór artykułu ▪ artykuł Głos wołającego na puszczy. Popularne wyrażenie ▪ spawarka gazowa artykułów. Opis pracy ▪ artykuł Słuchawka. Encyklopedia elektroniki radiowej i elektrotechniki
Zostaw swój komentarz do tego artykułu: Wszystkie języki tej strony Strona główna | biblioteka | Artykuły | Mapa stony | Recenzje witryn www.diagram.com.ua |