wingless Postat August 8, 2006 Partajează Postat August 8, 2006 Salut lucrez la un proiect si ma invart in cerc ... poate ma puteti ajuta Practic un encoder de pozitie genereaza niste impulsuri(verificat cu voltmetru) care mie imi genereaza o intrerupere. Cand primesc un impuls inseamna ca vehiculul s-a deplasat cu 0.5cm In rutina de intrerupere incrementez 3 registri rezervati numiti dist0,dist1,dist2 (R6,7,8). Am facut o rutina de test care trebuie sa deplaseze vehiculul cu x centimetri. Transmiterea numarului de jumatati de cm se face printr-un registru numit arg0 Ex: ldi arg0, 70 ;35cm rcall depl_fata_xjcm Am incercat pana acum 3 implementari. Momentan, pentru orice argument (10 centimetri 20 35 etc) vehiculul se misca la fel de mult Ideea de baza ar fi(in implementarea asta): 1. retin valorile curente ale dist2:dist1:dist0 2 intru in bucla si astept ca diferenta dintre valoarea curenta a dist2..1 si valorile retinute la 1) sa fie mai mare decat valoarea argumentului transmis (arg0) Alta idee(care nu a mers) era sa adun de la inceput arg0 peste valoarea curenta a dist2..0 si apoi sa astept sa devina dist2..0 egal sau mai mare Aveti vreo idee de ce nu ia in considerare argumentul si roteste rotile mereu acelasi numar de centimetri? Codul: ;%***%;procedura pt test care deplaseaza robotul maxim 255/2 cm;->arg0 cate jumatati de cm;deplasarea se face in fata cu arg0 jumatati de cmdepl_fata_xjcm:push tmp3Lpush tmp3Hpush tmp4Lpush tmp4H;iau distanta parcursa pana in prezent (doar primii 2 bytes)mov tmp3L, dist0mov tmp3H, dist1;pornesc motorul 0, viteza 25setMot 0, dirFATA, 25depl_fjcm:;iau distanta curentamov tmp4L, dist0mov tmp4H, dist1;scad distanta vechesub tmp4L,tmp3Lsbc tmp4H,tmp3H;arg0 poate fi maxim 255tst tmp4Hbrne depl_fjcm_gata ;am parcurs o distanta prea mare(>255=MAX(aux0))cp tmp4L, arg0brge depl_fjcm_gata;destul;;;;;;rjmp depl_fjcmdepl_fjcm_gata:;franezldi arg0, dirSPATErcall franaMot0pop tmp4Hpop tmp4Lpop tmp3Hpop tmp3Lret codul intreruperii care incrementeaza dir2:dir1:dir0 ;***impuls de la encoder (=blocare lumina = 0 logic,front negativ)EXT_INT1:in ri,SREG ; salvez registrul flagsinc dist0brne int1_gata ;verifica flagul ZERO == overflow inc dist1brne int1_gata inc dist2int1_gata: out SREG,ri ; restore reg flagsreti Link spre comentariu
lucicop Postat August 9, 2006 Partajează Postat August 9, 2006 Cam ce distanta parcurge de fiecare data ? Ai posibilitatea sa testezi cu un simulator/debugger ca sa vezi valorile registrilor ? Daca nu, incearca sa o iei pe bucati si sa schimbi cate ceva, pana se modifica distanta. Banuiesc ca problema provine din rutina de tratare a distantelor in tmp4H/L.Nu ma prea pricep la ASM, dar vad in Instruction Set ca functia CP compara doi registri Rx, unde x e de la 0 la 31. Link spre comentariu
wingless Postat August 9, 2006 Autor Partajează Postat August 9, 2006 salut. Cam 10 centimeri...Am simulat in AVR studio si mi s-a parut ok. Nu are cp legatura, toate variabilele din subrutina sunt registri . Oricum am schimbat acum 'cp' cu 'sub' ca sa imi ramana in tmp4L distanta care mai trebuie parcursaIncerc azi sa conectez un ecran de mobil la microcontroller Poate pana maine poimaine fac si softul pt el si o sa pot sa afisez pe el ce vreau ex valorile registrilor poate asa o sa imi dau seama pe viu cam ce nu merge Multam de sfaturiDaca nu si nu trec pe C Link spre comentariu
Vizitator DragosP Postat August 9, 2006 Partajează Postat August 9, 2006 Dacă nu modifici algoritmul, poţi să treci şi pe ADA, tot aia e :yawinkle: Ce nu-nţeleg eu este unde foloseşti tu arg0. La intrarea în subrutină văd că încarci în tmp3 valoarea dist pe care o incrementezi în rutina ISR. Despre arg0 doar în comentarii pare să fie vorba.În altă ordine de idei, probabil că faci dist=0 înainte de a apela rutina de deplasare, nu? Link spre comentariu
wingless Postat August 9, 2006 Autor Partajează Postat August 9, 2006 "Dacă nu modifici algoritmul, poţi să treci şi pe ADA, tot aia e " Nimic mai adevarat:) Dar mi-ar fi poate mai usor de gasit greseli intrucat aici ma incurca si sintaxa. Eu vreau sa raman pe asm totusi arg0 este un registru pe care il modific in rutina principala si prin care transmit parametrul rutinei deplasare bucla_pp:ldi arg0, 10rcall depl_fata_xjcmmdelay_s 2ldi arg0, 20rcall depl_fata_xjcmmdelay_s 2ldi arg0, 40rcall depl_fata_xjcmmdelay_s 2ldi arg0, 70rcall depl_fata_xjcmmdelay_s 3rjmp bucla_pp Nu, dist0, dist1, dist2 se incrementeaza doar in rutina de intrerupere nu le modific pe nicaieri. Restul programului poate folosi dist0,dist1,dist2 doar pt a citi deci ca o referinta. dist0,1,2 le init cu 0 la inceputul programului si pe toata durata executiei programului(deci pana la reset) dist se incrementeaza. Pe 3 bytes daca incrementez la fiecare jumatate de cm am overflow la aprox 80km evident nu se atinge asta. Deci in bucla principala chem rutina depl_fata_xjcm dupa ce am incarcat valoarea de jumatati de centimetru pe care vreau sa o parcurga in arg0. mdelay_s este un macro pt delay in secunde Faptul ca robotuul se deplaseaza aceeasi distanta indfiferent de ce valoare are arg0 imi arata mie ca primeste impulsuri(pentru ca altfel nu s-ar mai opri: ex daca opresc cu mana motorul cand ii dau drumul el se mai roteste cat e nevoie si dupa aia se opreste) Problema cred ca se afla in bucla de asteptare dar mi se pare atat de logica si de simpla problema si algoritmul incat pur si simplu nu vad nimic ciudat... Deocamdata vreau sa vad ce se intampla exact cu valorile de aceea lucrez la un ecranLCD ca sa il atasez microcontrollerului sa vad toti registrii pe viu poate asa imi dau seama ce am uitat sau ce am gresit Link spre comentariu
Vizitator DragosP Postat August 9, 2006 Partajează Postat August 9, 2006 Lasă-mă dom'le-n pace cu arg0 şi cum îl încarci tu în programul principal! Arată-mi în subrutina depl_fata_xjcm unde te foloseşti de el! Tu te legi tot timpul de tmp3 şi tmp4, dar de arg0 nu te legi, nu-l citeşti, nu nimic! :axe: Link spre comentariu
wingless Postat August 9, 2006 Autor Partajează Postat August 9, 2006 depl_fjcm:;iau distanta curentamov tmp4L, dist0mov tmp4H, dist1;scad distanta vechesub tmp4L,tmp3Lsbc tmp4H,tmp3H;arg0 poate fi maxim 255tst tmp4Hbrne depl_fjcm_gata ;am parcurs o distanta prea mare(>255=MAX(aux0))cp tmp4L, arg0brge depl_fjcm_gata;destul;;;;;;rjmp depl_fjcm cp tmp4L, arg0 in tmp4L am distanta parcursa pana in prezent de la inceperea subrutinei si compar asta cu cat ar trebui sa parcurg=arg0 Link spre comentariu
Vizitator DragosP Postat August 9, 2006 Partajează Postat August 9, 2006 cp tmp4L, arg0in tmp4L am distanta parcursa pana in prezent de la inceperea subrutinei si compar asta cu cat ar trebui sa parcurg=arg0Mda, scuze, sunt tâmpit. :rolleyes: Căldura...Codul pare corect; rămâne vreun efect lateral, probleme cu ISR, cu semnalul de la traductor... Link spre comentariu
wingless Postat August 9, 2006 Autor Partajează Postat August 9, 2006 deci din momentul cand pornesc motorul si pana il opresc se executa bucla aceea...motorul se invarte o perioada(lungime) fixa deci ISRul incrementeaza dist0,1,2 ca altfel nu s-ar mai opri. Eu am luat "la mana". Am legat un voltm,etru si foarte incet am rotit roata. La o rotatie compelta am obtinut cele 46 de ipulsuri numarate cu ochii pe voltmetru. Ceva trebuie sa fie ca de mers nu merge dar nu imi dau seama ce naiba... Link spre comentariu
nicu_stef Postat August 9, 2006 Partajează Postat August 9, 2006 intreruperea o declansezi pe front?daca ai un timer liber, poti incerca sa-l folosesti ca numarator, intri cu impulsurile in el, si el declanseaza o int, poti sa-l presetezi cu nr de cm etcsuccese Link spre comentariu
wingless Postat August 9, 2006 Autor Partajează Postat August 9, 2006 salut intreruperea o declansez pe front negativ. E complicatie cu timerul, eu vreau sa numere mereu impulurile nu sa genereze intrerupere la x impulsuri. Astfel programul "se uita" din cand in cand la registrii in care se numara impulsurile si poate vedea ce se intampla cu sistemul: se misca sta pe loc etc Deci registrii dist0,1,2 vor servi mai multor subrutine, ca informatie privitoare la starea robotului. Ce am facut acolo este o subrutina de test ... Link spre comentariu
wingless Postat August 16, 2006 Autor Partajează Postat August 16, 2006 Salu8t, am rezolvat pana la urma era o problema de atentie. Foloseam un macro care modifica arg0 ... multam de sfaturiproblema:;pornesc motorul 0, viteza 25setMot 0, dirFATA, 25 Link spre comentariu
Postări Recomandate
Creează un cont sau autentifică-te pentru a adăuga comentariu
Trebuie să fi un membru pentru a putea lăsa un comentariu.
Creează un cont
Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!
Înregistrează un nou contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum