;***************************************************************** ;* PROGRAM OBSLUGI AUTOMATYCZNEJ WIERTARKI DO PLYTEK DRUKOWANYCH * ;***************************************************************** org 0 using 0 czujnikX equ 00001000b ;maska czujnika krancowego osi X czujnikY equ 00000100b ;maska czujnika krancowego osi Y czujnikZ equ 00010000b ;maska czujnika krancowego osi Z poczatek_stosu equ 60h ;******* FLAGI *********************************************************** rs_end_flag equ 00h ;flaga sygnalizujaca zakonczenie transmisji ;wszystkich bajtow rs_rozkaz equ 01h ;znacznik rozkazu rs_rozkaz_OK equ 02h ;rozkaz gotowy w buforze start: ljmp poczatek ;****************************************** ; tablica wektorow przerwan ;****************************************** org 003h ret org 00Bh ret org 013h ret org 023h ljmp int_RS232 ;******************************* ; Program glowny ;******************************* org 30h rs_buf_in db 0h,0h,0h,0h ;bufor znakow przychodzacych rs_buf_out db 0h,0h,0h,0h ;bufor znakow wychodzacych rs_buf_in_point db 0h rs_buf_out_point db 0h rs_out_count db 0h org 3Dh stan_X db 0h poczatek: mov SP,#poczatek_stosu ;ustawienie wskaznika stosu mov stan_X,#00000100b ;ustawienie poczatkowego polozenia X mov P1,#0h mov ACC,#0FFh ;chwila na ustabilizowanie sie systemu acall wait_1 ; setb ex0 ;zezwolenie na INT 0 (os Y) ; setb ex1 ;zezwolenie na INT 1 (os X) ; setb ea ;zezwolenie na przerwania acall reset_Z ;ustawienie glowicy w Z w polozeniu acall reset_X ;ustawienie glowicy w X w polozeniu 0 acall reset_Y ;ustawienie glowicy w Y w polozeniu 0 mov ACC,#0FFh acall wait_1 ;krotka pauza acall RS232_ini ;ustawienie parametrow RS-232 mov R0,#3h mov R1,#10h mov R2,#10h petla_glowna: acall przesun_X acall przesun_Y mov A,#08 acall wait_1 acall wierc jb rs_rozkaz_OK,odb_rozkaz ljmp petla_glowna odb_rozkaz: mov R0,31h mov R1,32h mov R2,33h clr rs_rozkaz_OK setb REN ljmp petla_glowna ;*********************************************************** ; przesuniecie w osi X o 1 skok ; R1 zmniejszane za kazdym wywolaniem funkcji ; jesli R1 = 0 powrot bez jakiejkolwiek akcji ; R0.0 = 0 kierunek do czujnika ; R0.0 = 1 kierunek od czujnika ;*********************************************************** przesun_X: mov A,R1 jnz test_X anl P1,#11000011b ret test_X: mov A,stan_X anl A,#3Ch ; maska bitow silnika X ;*********************** cjne A,#00000100b,px_C mov A,R0 anl A,#1h anl P1,#11000011b jz koc_4 ;kierunek od czujnika orl P1,#00001100b ajmp dec_R1 koc_4: orl P1,#00100100b ajmp dec_R1 ;*********************** px_C: cjne A,#00001100b,px_8 mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_C ;kierunek od czujnika orl P1,#00001000b ajmp dec_R1 koc_C: orl P1,#00000100b ajmp dec_R1 ;*********************** px_8: cjne A,#00001000b,px_18 mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_8 ;kierunek od czujnika orl P1,#00011000b ajmp dec_R1 koc_8: orl P1,#00001100b ajmp dec_R1 ;*********************** px_18: cjne A,#00011000b,px_10 mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_18 ;kierunek od czujnika orl P1,#00010000b ajmp dec_R1 koc_18: orl P1,#00001000b ajmp dec_R1 ;*********************** px_10: cjne A,#00010000b,px_30 mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_10 ;kierunek od czujnika orl P1,#00110000b ajmp dec_R1 koc_10: orl P1,#00011000b ajmp dec_R1 ;*********************** px_30: cjne A,#00110000b,px_20 mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_30 ;kierunek od czujnika orl P1,#00100000b ajmp dec_R1 koc_30: orl P1,#00010000b ajmp dec_R1 ;*********************** px_20: cjne A,#00100000b,px_34 mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_20 ;kierunek od czujnika orl P1,#00100100b ajmp dec_R1 koc_20: orl P1,#00110000b ajmp dec_R1 ;*********************** px_34: cjne A,#00100100b,powrot_przesun_X mov A,AR0 anl A,#1h anl P1,#11000011b jz koc_34 ;kierunek od czujnika orl P1,#00000100b ajmp dec_R1 koc_34: orl P1,#00100000b ajmp dec_R1 ;*********************** dec_R1: dec AR1 mov A,P1 mov stan_X,A powrot_przesun_X: ret ;******************************* ; ;******************************* przesun_Y: mov A,R2 jnz test_Y ret test_Y: mov A,R0 anl A,#02h jz pdcz acall w_lewo_Y ajmp ret_przesun_Y pdcz: acall w_prawo_Y ret_przesun_Y: dec AR2 ret ;********************************** ; obrot silnika Y o 25 skokow w prawo ;********************************** w_lewo_Y: push AR4 mov AR4,#19h mov A,#2h anl P1,#0BFh obr_l_Y: xrl P1,#80h acall wait_1 djnz AR4,obr_l_Y pop AR4 ret ;********************************* ; obrot silnika Y o 25 skokow w prawo ;********************************* w_prawo_Y: push AR4 mov AR4,#19h mov A,#2h orl P1,#40h obr_p_Y: xrl P1,#80h acall wait_1 djnz AR4,obr_p_Y pop AR4 ret ;*********************** ; w_dol ;*********************** w_dol: orl P1,#2h xrl P1,#1h mov A,#08h acall wait_1 ret ;*********************** ; w_gore ;*********************** w_gore: anl P1,#0FDh xrl P1,#1h mov A,#12h acall wait_1 ret szybko_w_gore: anl P1,#0FDh xrl P1,#1h mov A,#08h acall wait_1 ret ;************************************** ; Obrot silnika X o 1 skok do czujnika ;************************************** wprawo_X: push AR0 push AR1 mov AR1,#1h ; 1 skok mov AR0,#0h ; obrot do czujnika acall przesun_X pop AR1 pop AR0 ret ;************************************** ; Obrot silnika X o 1 skok od czujnika ;************************************** wlewo_X: push AR0 push AR1 mov AR1,#1h ; 1 skok mov AR0,#1h ; obrot od czujnika acall przesun_X pop AR1 pop AR0 ret ;********************************************************** ; Ustawienie glowicy w osi X w polozeniu 0 ; Argumenty: Brak ; Powrot: ACC = 0 jesli OK ACC != 0 jesli cos bylo nie tak ;********************************************************** reset_X: clr ea ; zablokowanie przerwan push AR0 ; rejestr na stos push AR1 ; rejestr na stos mov AR1,#03h ; beda 3 proby ustawienia wozka orl p3,#czujnikX ; ustawienie portu 3 "do odczytu" mov ACC,p3 ; oczytanie portu 3 anl ACC,#czujnikX ; maska czujnika osi X jnz czX_na ; skok jesli czujnik NIE aktywny czX_aktywny: dec AR1 ; zmniejszenie rejestru ilosci prob mov ACC,AR1 jz reset_X_error ; test "czy byly juz 3 proby" mov AR0,#30h ; max 30h skokow w lewo leftX_loop: acall wlewo_X ; przesuniecie wozka X mov A,#08h acall wait_1 djnz R0,leftX_loop ; petelka czX_na: mov AR2,#5h czX_na_loop0: mov AR0,#0FFh ; 500h skokow (przejscie calej drogi X) czX_na_loop1: acall wprawo_X ; przesuniecie wozka X mov A,#08h acall wait_1 ; mov A,p3 ; odczytanie portu anl A,#czujnikX ; maska czujnika osi X jz reset_X_ret ; czujnik uaktywnil sie -> skok djnz R0,czX_na_loop1 djnz R2,czX_na_loop0 ajmp czX_aktywny ; powtorzenie proby nop reset_X_error: mov ACC,#1h ajmp reset_X_end reset_X_ret: mov ACC,#0h reset_X_end: pop AR1 ; rejestr ze stosu pop AR0 ; rejestr ze stosu setb ea ; odblokowanie przerwan ret ;********************************************************** ; Ustawienie glowicy w osi Y w polozeniu 0 ; Argumenty: Brak ; Powrot: ACC = 0 jesli OK ACC != 0 jesli cos bylo nie tak ;********************************************************** reset_Y: clr ea ; zablokowanie przerwan push AR0 ; rejestr na stos push AR1 ; rejestr na stos mov AR1,#03h ; beda 3 proby ustawienia wozka orl p3,#czujnikY ; ustawienie portu 3 "do odczytu" mov ACC,p3 ; oczytanie portu 3 anl ACC,#czujnikY ; maska czujnika osi X jnz czY_na ; skok jesli czujnik NIE aktywny czY_aktywny: dec AR1 ; zmniejszenie rejestru ilosci prob mov ACC,AR1 jz reset_Y_error ; test "czy byly juz 3 proby" mov AR0,#30h ; max 30h skokow w lewo leftY_loop: acall w_lewo_Y ; przesuniecie wozka Y djnz R0,leftY_loop ; petelka czY_na: mov AR2,#3h czY_na_loop0: mov AR0,#0FFh ; 300h skokow (przejscie calej drogi Y) czY_na_loop1: acall w_prawo_Y ; przesuniecie wozka Y mov A,p3 ; odczytanie portu anl A,#czujnikY ; maska czujnika osi Y jz reset_Y_ret ; czujnik uaktywnil sie -> skok djnz R0,czY_na_loop1 djnz R2,czY_na_loop0 ajmp czY_aktywny ; powtorzenie proby nop reset_Y_error: mov ACC,#1h ajmp reset_Y_end reset_Y_ret: mov ACC,#0h reset_Y_end: pop AR1 ; rejestr ze stosu pop AR0 ; rejestr ze stosu setb ea ; odblokowanie przerwan ret ;********************************************************** ; Ustawienie glowicy w osi Z w polozeniu spoczynkowym ; Argumenty: Brak ; Powrot: ACC = 0 jesli OK ACC != 0 jesli cos bylo nie tak ;********************************************************** reset_Z: clr ea ; zablokowanie przerwan push AR0 ; rejestr na stos push AR1 ; rejestr na stos mov AR1,#03h ; beda 3 proby ustawienia wozka orl p3,#czujnikZ ; ustawienie portu 3 "do odczytu" mov ACC,p3 ; oczytanie portu 3 anl ACC,#czujnikZ ; maska czujnika osi Z jnz czZ_na ; skok jesli czujnik NIE aktywny ajmp zstr_up ; byc moze ze wozek jest w zlym miejscu ; trzeba go przesunac by to sprawdzic czZ_na: mov AR0,#0A0h ; max A0h skokow czZ_na_loop1: acall w_dol ; przesuniecie wozka Z w dol mov ACC,p3 ; odczytanie portu anl ACC,#czujnikZ ; maska czujnika osi Z jz reset_Z_ret ; czujnik uaktywnil sie -> skok djnz R0,czZ_na_loop1 ; jesli program dotarl tutaj to znaczy ; ze wozek byl ponizej czujnika ; w zwiazku z typ podnosimy najpierw ; wozek do gory aby go ustawic z odpowiedniej ; strony czujnika zstr_up: dec AR1 mov ACC,AR1 jz reset_Z_error mov AR0,#15h ; max 10h skokow do gory zstr_loop: acall szybko_w_gore ; przesuniecie wozka Z w gore djnz R0,zstr_loop ; petelka ajmp czZ_na ; zakladam ze wozek znalazl sie w odpowiednim ; miejscu (i nie zrobil jeszcze dziury w plytce) reset_Z_error: mov ACC,#1h ajmp reset_Z_end reset_Z_ret: mov ACC,#0h reset_Z_end: pop AR1 ; rejestr ze stosu pop AR0 ; rejestr ze stosu setb ea ; odblokowanie przerwan ret ;*********************** ; wierc ;*********************** wierc: clr ea push AR2 mov A,AR0 setb ea anl A,#4h ; test czy bit wiercenia jest ustawiony jz wierc_ret ; jesli nie to powrot mov R2,#80h ; 80h skokow w gore loop_w_gore: acall w_gore djnz R2,loop_w_gore loop_w_dol: acall w_dol mov A,p3 anl A,#00010000b jnz loop_w_dol wierc_ret: anl AR0,#0FBh pop AR2 ret ;***************************** ; opoznienie ; Argumenty: A - ilosc petli ; Powrot: ;***************************** wait_1: push AR1 push AR2 mov AR2,A wait_1_loop2: mov AR1,#0FFh wait_1_loop1: nop nop nop nop djnz AR1,wait_1_loop1 djnz AR2,wait_1_loop2 pop AR2 pop AR1 ret vector_INT1: clr ex1 mov AR4,#1h reti ;*************************************************************** ;* Procedura inicjacji parametrow transmisji portu szeregowego * ;*************************************************************** RS232_ini: mov SCON,#01010000b ;ustawienie trybu 1 i inicjacja odbiornika anl PCON,#7Fh ;pcon.7=0 dla 600 - 9600 bodow, ;pcon.7=1 dla 19200 bodow anl TMOD,#0Fh orl TMOD,#20h ;licznik T1 pracuje w trybie 2 (8 bitowy z ;automatycznym reladowaniem) mov TH1,#0FDh ;wartosci poczatkowe dla poszczegolnych ;predkosci transmisji: mov TL1,#0FDh ;D0h-600, E8h-1200, F4h-2400, FAh-4800, ;FDh-9600, FDh-19200 clr TF1 clr rs_rozkaz ;znacznik rozkazu clr rs_rozkaz_OK mov rs_buf_in_point,#0 mov rs_buf_out_point,#0 setb TR1 setb REN setb ES ;zezwolenie na przerwania transmisji ;szeregowej portu RS setb EA ;globalne zezwolenie na przerwania ret ;***************************************** ; Procedura przerwania portu szeregowego * ;***************************************** int_RS232: push PSW ;zachowanie zawartosci rejestrow uzywanych przez ;procedure przerwania push ACC push AR0 jb scon.1,rs_send ;skok jesli przerwanie wywolane zostalo przez ;zakonczenie transmisji poprzedniego bajtu ;***** FUNKCJA ODBIORU BAJTU ****** clr scon.0 ;zerowanie flagi odbioru kolejnego bajtu mov R0,sbuf ;odbebrany bajt do rejestru mov A,#30h ;obliczenie adresu add A,rs_buf_in_point xch A,R0 ;zamiana miejscami A i R0 mov @R0,ACC ;odebrany bajt do bufora jb rs_rozkaz,odb_rozk ;test czy rozkaz? cjne A,#0EAh,end_of_rx ;czy znak = EA ? jesli nie to skok setb rs_rozkaz ;ustawienie znacznika rozkazu inc rs_buf_in_point ;zwiekszenie wskaznika bufora ajmp end_of_rx odb_rozk: inc rs_buf_in_point ;zwiekszenie wskaznika bufora mov A,rs_buf_in_point cjne A,#4h,end_of_rx ;czy odebrane 4 bajty rozkazu? clr rs_rozkaz setb rs_rozkaz_OK ;ustawienie znacznika konca rozkazu clr REN ;zablokowanie odbiornika mov rs_buf_in_point,#0h ;wyzerowanie wskaznika bufora end_of_rx: ajmp rs_int_end ;***** FUNKCJA NADAWANIA BAJTU ****** rs_send: clr scon.1 ;zerowanie flagi sygnalizujacej zakonczenie ;transmisji bajtu mov A,rs_out_count ;sprawdzenie czy wyslano juz wszystkie bajty jnz rs_t2 ;jesli nie to skok setb rs_end_flag ;ustawienie flagi sygnalizujacej zakonczenie ;transmisji wszystkich znakow ajmp rs_int_end ;koniec obslugi przerwania rs_t2: mov R0,rs_buf_out_point mov A,@R0 ;pobranie kolejnego bajtu z bufora do wyslania ;portem szeregowym inc rs_buf_out_point ;ustawienie wskaznika na kolejny bajt bufora dec rs_out_count ;zmniejszenie o 1 licznika wyslanych bajtow mov sbuf,A ;bajt do rejestru wyjściowego portu szeregowego rs_int_end: pop AR0 ;odtworzenie pierwotnych wartosci rejestrow ;uzywanych przez procedure przerwania pop ACC pop PSW reti end