mystery Opublikowano 3 Grudnia 2004 Zgłoś Opublikowano 3 Grudnia 2004 witam, jest to moj pierwszy post, czyli jestem tu nowym noobkiem :P dopiero zaczynam zapoznawać się z tym forum, więc nie jestem pewien czy w odpowiednim miekscu umieściłem ten temat, jeśli w złym to niech admin przeniesie tam gdzie trzeba, byle nie do kosza :) mam mały problem i w związku z tym szukam małej pomocy. nie chcę żeby ktoś za mnie pisał program a jedynie mi doradził co nieco jeśli oczywiście jest to możliwe. do rzeczy muszę napisać program pod mikrokontroler 8051, język programy pisze się w assemblerze, ale trzeba znać odpowiednią listę rozkazów, zresztą ten kto miał styczność z tym sprzeten kiedykolwiek wie o co come on :) treść programu: po uruchomieniu program ma zmierzyć czas reakcji jaki upłynią od zapalenia diody do wciśnięcia przycisku podłączonego z zewnątrz (wejście INT0 lub INT1) i czas wyśletlić na ekranie LCD lub siedmiosegmentowym. trzeba wykorzystać oczywiście przerwania i układ czasowo licznikowy. mój problem tkwi w tym jak poprawnie zaprogramować przerwanie oraz sam licznik. jak widać program nie jest aż tak trudny, ale jestem poczatkujący więc jeszcze nie kumam wszystkiego. korzystałem z opcji szukania, ale nic nie znalazłem konkretnego :P jeśli ktoś jest w stanie mi pomóc to byłbym bardzo wdzięczny :) pozdro :) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 6 Grudnia 2004 Zgłoś Opublikowano 6 Grudnia 2004 To ja może spróbuje pomóc, chociaż sam niedawno zaczołem programowanie w Assemblerze. Żeby obsłużyć przerwanie trzeba pierw zezwolić na przerwanie programując odpowiedni rejestr. Tym rejestrem jest IE. Opis najczęściej używanych rejestrów mam nadzieje masz pod ręką bo bez tego ani rusz. Żeby zezwolić na przerwanie INT1 do IE trza wysłać #84H czyli MOV IE,#84H żeby INT0 zezwolić trza wysłać MOV IE,#81H. Jeśli wystąpi dane przerwanie to procek szuka obsługi przerwania pod odpowiednim adrsem (tabelka przerwań i ich adresów także powinna być pod reką). INT0 ma adres 0003H, a INT1 0013H. Czyli żeby obsłużyć przerwanie trza umieścić instrukcje pod danym adresem. Musisz jeszcze wiedzieć od jakiego adresu możesz zacząć pisać instrukcej. Najczęsciej jest to 2000H i teraz przykładzik: CSEG AT 2000H;adresowanie od 2000HSJMP USTAW ;skok bezwarunkowy do etykiety ustaw gdzie programuje procka, liczniki itdORG 2003H ;obsluga przerwania INT0SJMP PRZERW ;skok bezwarunkowy do etykiety przerw, moga ty byc instrukcje ale za duzo ich nie moze byc bo mozna wejsc na adres nastepnego przerwaniaUSTAW:MOV TMOD, #01H ;programowanie licznikówMOV IE,#81H ;zezwolenie na przerwanie INT0 o licznikach zaraz napisze Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 6 Grudnia 2004 Zgłoś Opublikowano 6 Grudnia 2004 URL=http://www.ime.uz.zgora.pl/dydaktyka/materialy/oprogramowanie_aparatury_up/regb_mcs51.pdf]To[/url] powinineneś mieć pod ręką. Zapomniałem napisać że trzeba jeszcze "wyjść" z obsługi przerwania instrukcją RETI. A teraz o licznikach. W tej broszurce co podałem linka wyżej masz schemat blokowy działania liczników w odpowiednich trybach. Pierw musisz wiedzieć jaką czestotliwością jest taktowany procek. ZAkladam że jest to 12MHz bo tak jest zreguły jeśli chcemy coś zliczać. Licznik programujemy wysyłając do rejestru TMOD odpowiednia liczbe (opis rejestru w broszurce). Jeśli licznik uzywamy do zliczania to najczęściej częstotliwość dzilimy na 12 żeby otrzymać 1MHz. (dzielimy przez 12 ustawiając C/T na 0 przy programowaniu). 1MHz czyli licznik jest zwiększany co 1us (mikrosekundę) 1s=1000000us. Do zliczania licznik ustawia się najczęściej na tryb 1 ponieważ ma największą pojemność (4 bajty czyli 65535us czyli 0,065s czyli dużo za mało dla danego przykładu ale o tym póżniej). MOV TMOD,#01H ;tryb 1 i dzielenie przez 12, licznik 0 to co licznik zliczył jest w rejestrach TL0 i TH0 (lub TH1 i TL1 w zalerzności który licznik używamy). Żeby powiększyć zakres licznika trza wprowadzić dodatkowy rejestr do zliczania. Możemy zezwolić na przerwanie jesli licznik sie przepelni i zwiekszać dodatkowy resjestr (któryś z R0-R7), wtedy mamy juz 6 bajtów czyli możemy zliczyć do ok 16.sekund. Muszę już kończyć jakby cosbylo niejasnego a napewno było to pisz jak znajde czas to odpisze. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 8 Grudnia 2004 Zgłoś Opublikowano 8 Grudnia 2004 dzięki cici, ale ja wiem jak zorganizowane są przerwania w tym układzie, wiem tez jak ustawic liczniki w dany tryb pracy. częstotliwosc się zgadza (a dokladnie jest to 11,059Mhz) mój problem tkwi w tym aby odpowiednio zaprogramować licznik, aby liczył czas z dokladnością do setnej sekundy. na potrzeby programu 16 sekund na pewno wystarczy, bo w końcu ma mierzyc czas reakcji. program nie muszę zaczynać az od bitu 2000H. dsm-51 ma inaczej zorganizowaną pamięć. przerwania zaczynają się od adresu 03H - dla INT0, a dla INT1 - 13H, sam program zaś należy zacząć pisać od adresu 100H. myślę jednak że z samym przerwaniem nie będzie większego kłopotu. muszę zastanowić się tylko nad tym jak wyświetlic zawartosć licznikow na wyświetlaczu. gdy juz bedę mial odpowiednio ustawione liczniki to z tym sobie jakos poradzę. jeszcze troche pracy przede mną :) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 8 Grudnia 2004 Zgłoś Opublikowano 8 Grudnia 2004 Licznik najlepiej ustawic na tryb 1, czyli MOV TMOD, #01H Z tymi 11MHz będziesz miał mały problem, ale to szczegół. Lepszą częstotliwością byłoby 12MHz bo licznik by zliczał dokładnie co 1us, a tak zlicza co 1,085us, ale to sie da obejsc. Napisz jeszcze z jaką dokładnością musisz wyświetlić czas reakcji, bo moża to zrobić troche w inny sposób. Można zliczać na przykład co 0,1s. Wartość początkową liczników ustawiasz na wartość żeby przepełnienie licznika nastąpiło co 0,1s i wtedy jak się licznik przepelni inkermentujesz któryś z rejestrów. A jak wyświetlić wartości liczników na wyswietlaczu, to trza wiedzieć w jaki sposób jest podłączony wyświetlacz do mikroprocka. wyświetlacze LED są podłączone albo przez multiplekser, albo są podłączone do lini adresowej i wtedy wartość do wyświetleniana na danym segmencie wysyła się pod odpowiedni adres. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 8 Grudnia 2004 Zgłoś Opublikowano 8 Grudnia 2004 niestety nie mam wpływu na wybór układu. musze zadowolić się tym zegarem :). co do dokładności to myślę, że do jedej setnej sekundy ( 0.01s) będzie dobrze. jeśli chodzi o wyświetlenie wyniku to z tym nie będzie większego problemu. poza tym mam do wyboru wyświetlacz LED albo siedmiosegmentowy. wyświetlenie na LED będzie łatwiejsze, ale tym już sam się zajmę :) pozostaje mi teraz napisać algorytm i potem program. ale nie jestem jeszcze do konca wszystkiego pewny :) dzięki za pomoc cici, jak będziesz jeszcze chciał to napisz coś więcej :D Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 8 Grudnia 2004 Zgłoś Opublikowano 8 Grudnia 2004 Robiłem całkiem niedawno podbne zadanko, tylko że ja miałem zrobić zegarek odświerzany co sekundę. Ustawienie licznika więc będzie podobne. Jak wcześniej napisałeś dokładność ma być 0,01s więc co taki czas powinno być wywołane przerwanie przepełnienia licznika. Trzeba więc ustawić wartości początkowe licznika. Licznik musi być ustawiony w tryb 1, ponieważ w tym trybie licznik ma największą pojemność. Musimy odmierzyć 0,01s czyli 10000us kwarc jest 11,085MHz do licznika dochodzi częstotliwość podzielona przez 12, czyli licznik jest inkrementowany co 1,0825us. Żeby odmierzyc 0,01s licznik musi się zwiększyć 9238 razy w trybie szesnastkowym to będzie 2416h czyli tą liczbę trzeba odjąć od FFFFh i dostaniemy wartość początkową licznika DBE9 czyli TH0 powinno mieć wartość DBh a TL0 E9h przerwanie od licznika T0 będzie wywoływane co 0,01s. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 15 Grudnia 2004 Zgłoś Opublikowano 15 Grudnia 2004 czyli muszę jeszcze zorganizować drugie przerwanie. z twojej wypowiedzi wynika, że co 0.01s będzie wywoływane przerwanie z licznika, gdy się on przepełni, czyli muszę to zapisać w jakimś rejestrze, np R7. co każde przerwanie zwiększałby się o jeden, tylko że rejstr ma ograniczoną pojemność, tj. tylko 8 bitów, czyli największa liczba jaką mogę w nim zapisać to 255, czyli odpada. ale jest jeszcze 16-bitowy rejestr DPTR, w którym mogę zapisać juz 65355 - czyli jak dla moich potrzeb wystarczająco. lecz nie jestem pewien czy mogę użyć tego rejestru, ale chyba tak. wynika z tego, że w rejestrze miałbym czas w ms poczynając od 10ms, bo tak ustawiony jest zegar. zastanawiam się tylko czy nauczyciel mi na to pozwoli, bo jeśli ktoś nie wciśnie w ciągu np po minucie, ale można programowo założyć że czas tej reakcji nie powinien przekraczać np. 5 sekund, wtedy wszystko będzie wporządku. przed wyświetleniem należy jeszcze przed trzecim znakiem postawić kropkę, ale tym zajmę się później. najważniejsze w programie jest odpowiednie ustawienie zegara, bo przerwania juz są łatwiejsze. i tak przerwanie od przycisku będzie tylko zatrzymywało licznik i wyświetli stan rejestru na LCD. procedura na wyświetlanie na LCD jest gotowa w pamici EPROM układu, więc wystarczy go tylko przywołać w odpowiednim miejscu(mam nadzieję że będę mogł tego użyć, bo jak nie to wyświetle na 7-seg :P), tylko że podprogram ten wyświetla zawartość akumulatora na LCD :/. muszę pomyśleć jak to rozwiązać, ewentualnie zapytam opiekuna pracy. btw, we wtorek juz mam pierwsząkontrolę prac dyplomowych :/. lipa bo miałem nadzieje ze po świętach dopiero to będzie, ale cóz, wystarczy że będę miał algorytm i trochę programu na kartce :D jeszcze pytanie. dsm-51 ma zegar 11.059MHz, a nie 11.085MHz, więc czy ustawienia, które podałeś będą się zgadzały? moim zdaniem różnica jest znikoma, ale pytam dla pewności :) i jeszcze jedno, po przepełnieniu licznik będzie mierzył spowrotem od zadanej wartości, czy muszę ją jeszcze raz przypisać, np w przerwaniu? pozdrawiam mystery[/code] Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 18 Grudnia 2004 Zgłoś Opublikowano 18 Grudnia 2004 Problem z przepelnieniem rejestru (np. R7) mozesz rozwiazac podczas obslugiwania przerwania. Sprawdzasz czy R7 ma wartosc 255, jeśli tak to to zwiększasz rejestr R6 a R7 zerujesz. I wtedy mamy 16 bitów. Mozna jeszcze sprawdzac rejestr R6 czy się nie przepelnia i zwiększac R5 itd. DPTRa raczej się nie używa do przechowywania danych. Zmiana zegara dużo nie zmieni, ale zapewne w sprawozdaniu będziesz musiał wyliczyć dlaczego takie a nie inne są wartości początkowe rejestrów licznika. Po przepełnieniu licznika musisz na nowo wprowadzić wartości początkowe liczników. Czyli w obsłudze przerwaniu musi się to znaleźć. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 18 Grudnia 2004 Zgłoś Opublikowano 18 Grudnia 2004 dzięki cici, duzo mi pomogles, ide zaraz pisac program :) jeszcze tylko powiedz, w ktorym przerwaniu ustawić te liczniki, od licznika, czy od int0? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 18 Grudnia 2004 Zgłoś Opublikowano 18 Grudnia 2004 Wartości początkowe liczników ustawiasz po wystąpieniu przerwania od licznika T0. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 24 Lutego 2005 Zgłoś Opublikowano 24 Lutego 2005 witam ponownie, sporo czasu upłynęło do mojej ostatniej wizyty. ale mam już program, tzn napisałem juz program. Dlaczego tak długo? bo wcześniej mi się nie chciało :P w sumie to w godzine go napisałem. oto program: LJMP START ORG 03H SJMP PRZERW1 ORG 0BH MOV TH0,#0DBH MOV TL0,#0FFH INC R7 CJNE R7,#100,P1 INC R6 P1: RETI ORG 100H START: MOV IE,#10000011B ;ustawienie przerwań MOV TMOD,#01H ;tryb pracy licznika MOV TH0,#0DBH MOV TL0,#0FFH MOV R7,#0 MOV R6,#0 CLR P1.7 ;zapalenie diody SETB TR0 ;włączenie licznika SJMP $ PRZERW1: SETB P1.7 CLR TR0 MOV A,R6 ACALL POD MOV A,#'.' LCALL WRITE_HEX ;write_hex wyświetla na LCD znak, ktorego kod zapisany jest w A MOV A,R7 ACALL POD RETI POD: ;jest to podprogram, który przedstawia wymik dzielenia MOV B,#100 ;na LCD w postaci dziesiętnej DIV AB LCALL WRITE_HEX MOV A,B MOV B,#10 DIV AB ADD A,B LCALL WRITE_HEX RET oto i cały program, ale jeszcze nie wiem czy działa, bo nie miałem do tej pory możliwości aby sprawdzić go. jeżeli widzisz jakieś blędy cici, to krzycz. jeżeli masz jakieś wątpliwości co do użytych rozkazów bądź podprogramów to pytaj. pozdrawiam mystery Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
CiCi Opublikowano 1 Marca 2005 Zgłoś Opublikowano 1 Marca 2005 Witam Przeglądnołem twój programik i wydaje się być poprawnie zrobiony poza jednym wyjątkiem INC R7 CJNE R7,#100,P1 INC R6 P1: RETI ORG 100H Jeśli chciałeś tu zrobić to o czym myśle to powinno być jeszcze zerowanie rejestru R7, jeśli rejestr ten osiągnie wartość 100 CJNE R7,#100,P1 INC R6 MOV R7,#0 ;tego brakuje P1: Jak rozumiem inicjalizacji LCD i funkcji wyświetlającej znaki na wyświetlaczu nie musisz pisać?? Czy po prostu przyjdzie na to czas?? pozdro Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 2 Marca 2005 Zgłoś Opublikowano 2 Marca 2005 dzięki cici, to był poważny błąd :) co do LCD, to system dsm-51 ma wbudowane pewne gotowe procedury, np. na obsługę wyświetlacza, są też podprogramy opóźnień, itp. lepiej jest sobie ułatwiać pracę wykorzystując gotowe już programy. profesor też mi tak powiedział, że to ma być jak najprostszy program, więc wszystko gra B) nie jestem jeszcze na etapie, aby konfigurować wyświetlanie na LCD, na wyświetlaczu siedmiosegmentowym już umiem, na LCd przyjdzie jeszcze czas :) pozdrawiam mystery Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 15 Marca 2005 Zgłoś Opublikowano 15 Marca 2005 witam wszystko byłoby ok, gdyby nie to, że w tym akurat systemie nie wyprowadzonych bezpośrednio wejść INT0 i INT1. fakt ten komplikuje nieco sytuację, ale jak sie okazało wystarczy dodac do programu kilkanaście linijek i wszystko będzie ok. w układzie znajduje sie sterownik przerwań, którego wyjścia podłączone są do wejść mikrokontrolera INT0 i INT1. INT0 połączony jest z portem COM2, wieć odpada jego użycie, natomiast mogę użyć wejścia INT1. NAleży wykorzystać wejście IX na szynie systemowej i odpowiednio zaprogramować steronik przerwań. Nie jest to trudne. Dziś już uporałem się z pracą programu działa on znakomicie. należy dodać tylko kilka linijek do obsługi przerwania i do programu głównego do prgramu głównego nalezy dodać: MOV R1,#CSIC ;PROGRAMOWANIE MOV A,#3 ;STEROWNIKA PRZERWAŃ MOVX @R1,A MOV IE,#10000110B LCALL LCD_CLR ;WYCZYSZCZENIE EKRANU LCDdo przerwania od INT1 nalezy dodać: MOVX A,@R1 ;SPRAWDZENIE I WYZEROWANIE ANL A,#03H ;PRZERWANIA W STEROWNIKU MOVX @R1,A CJNE A,#3,END LCALL LCD_CLR (...) RETIEND: ;WYZEROWANIE INNYCH PRZERWAŃ PUSH ACC MOV R1,#CSAD MOVX A,@R1 POP ACC MOV R1,#CSIC MOVX @R1,A RETIsprawdzilem i dziala juz niedlugo kontrola prac dyplomowych :) jezeli ktos chcialby całyprogram to niech napisze to wysle mu na meila :) pozdrawiam mystery Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mystery Opublikowano 4 Maja 2005 Zgłoś Opublikowano 4 Maja 2005 no i po obronie... teraz jestem juz technikiem elektronikiem. a dyplom na 6 :D pozdrawiam mystery Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...