XName Postat Aprilie 18, 2007 Autor Partajează Postat Aprilie 18, 2007 Am citit si postul cu rutinele de delay Dar tot nu merge programul La simulare primesc in MPLAB Sim urmatoarea eroare "Stack over flow error occurred" iar programul e simplu: #include p16F84a.inc LIST p=PIC16F84A ;modelul de microcontroler __CONFIG _XT_OSC & _WDT_OFF cblock 0x1C delay1 ;declar variabile delay2delay3 endc BANK0 macro bcf STATUS,RP0 endm BANK1 macro bsf STATUS,RP0 endm ;******************************************************* ORG 0x0000 ;Vectorul RESET goto Main ORG 0x0004 ;Vectorul INTRERUPERE goto Main;************** Programul principal ******************** Main BANK0 clrf PORTB BANK1 movlw B'00000000' movwf TRISB BANK0 clrf PORTA BANK1 movlw B'00000000' movwf TRISA Loop movlw b'00000001' movwf PORTB call Delay movlw b'00000010' movwf PORTB call Delay movlw b'00000100' movwf PORTB call Delay movlw b'00001000' movwf PORTB call Delay movlw b'00010000' movwf PORTB call Delay movlw b'00100000' movwf PORTB call Delay movlw b'01000000' movwf PORTB call Delay movlw b'10000000' movwf PORTB call Delay goto Loop ;****************** Functia Delay ********************* Delay movlw .6 movwf delay1 clrf delay2 clrf delay3 decfsz delay3,f goto $-1 decfsz delay2,f goto $-3 decfsz delay1,f goto $-5 return ;*************************************************** end Am modificat .24 cu .6 pt a reduce timpul la aproximativ o secunda La incarcarea in PIC acesta nu imi aprinde nici un led din cele legate pe portul B Mersi de ajutor Link spre comentariu
CristianC Postat Aprilie 18, 2007 Partajează Postat Aprilie 18, 2007 La intrarea in Loop te afli in bancul1 de registrii. PORTB este in bancul 0. Insereaza BANK0 inainte de Loop si o sa mearga Link spre comentariu
cirip Postat Aprilie 18, 2007 Partajează Postat Aprilie 18, 2007 As mai face o observatie. Nu afecteaza programul asta ptr ca nu lucrezi cu intreruperile, dar ca principiu, nu se iese niciodata din intrerupere cu goto, ci cu retfie. Daca iesi cu salt (goto) nu descarci stiva si e normal sa dea Stack Overflow. Dar in cazul tau, in care nu autorizezi intreruperile, nu este necasar sa faci acel org 4 si goto main.Cirip Link spre comentariu
XName Postat Aprilie 18, 2007 Autor Partajează Postat Aprilie 18, 2007 Si acum mai departe. Ca sa mai complic lumina dinamica, am decis sa folosesc 6 pini de pe portul B si 2 de pe portul A, ceilalti 2 ramasi de pe B se folosesc pt 2 butoane (RB7, RB6) care vor creste si vor scade viteza luminii dinamice Am facut tot programul si merge cu MPLAB Sim, dar am dat de o porblema pe care nu stiu cum as putea so fac directin asamblare fara directive de procesare, si anume o conditie de verificare eu vreau sa pun ca viteza sa fie intre valorile 200....256, ar fi ceva de genu: if(viteza==200) ... ;nu decrementa Multumesc Link spre comentariu
Abram Burel Postat Aprilie 19, 2007 Partajează Postat Aprilie 19, 2007 Presupunem ca viteza curenta o tii intr-o variabila numita chiar asa: viteza #define vitezajos 200 ;definire prag jos...viteza equ 25h; definire variabila viteza...movf vitezajos,w ;pune viteza in Wsubwf viteza,w; scade vitezajos (W) din viteza si pune rezultatul in Wbtfss status,c; daca rezultatul e negativ, sari o instructiunenop ; in mod normal daca nu e voie, atunci nu faci nimic pot sa pui un goto daca vrei totusi sa faci cevadecf viteza,f ;evident trebuie decrementata viteza daca e voie... Parca asa ceva...[/code] Link spre comentariu
TECH_FUN Postat Aprilie 19, 2007 Partajează Postat Aprilie 19, 2007 La seria 8051 este o instructiune CJNE-(compare and jump if not equal), ceea ce facea simpla ac. operatie. La 16Fxx nu exista , asa ca o comparatie se face cu SAU-EXCLUSIV, adica instructiunea XORLW k , k fiind constanta 200 de care ziceai. Rezultatul in W, in cazul in care cele 2 numere sunt egale va fi 0. Flag-ul Z este afectat de aceasta instructiune; testezi flag-ul. Altfel spus, daca operandul pe care-l testezi este = 200, flag-ul Z se face 1. nu-ti ramane decat sa-l testezi si sa iei decizia care trebuie. :yawinkle: Link spre comentariu
XName Postat Aprilie 20, 2007 Autor Partajează Postat Aprilie 20, 2007 Totusi daca vreau sa compar doua variabile a==b unde si a si b sunt intre 0...256 nu am o functie pt asa ceva.exista XORWF , iar pt asta trebuie sa incarc pe a in w, iar b este f, dar are o limitare: f nu poate sa fie decat 0..127Eu m-am gandit la o solutie nu stiu daca este si corecta, si cea mai practica: mai intai compar bitul MSB de la b, si astfel impart in doua categorii, daca este 0 execut cu XORWF dar daca este 1 , scad din b pe 128 si astfel raman tot cu o valoare cuprinsa intre 0...127 asupra careia pot aplica functia XORWFCe ziceti?!? Merge? Sau sunt solutii mult mai simple si eu nu le stiu? Link spre comentariu
cirip Postat Aprilie 20, 2007 Partajează Postat Aprilie 20, 2007 Totusi daca vreau sa compar doua variabile a==b unde si a si b sunt intre 0...256 nu am o functie pt asa ceva. Nu, nu ai o functie ptr asa ceva ptr ca asamblarea nu este limbaj de nivel inalt. Nu e prea prietenos. In asamblare nu ai functii, ci instructiuni si subrutine (daca ti le scrii sau la copiezi de undeva). dar are o limitare: f nu poate sa fie decat 0..127Cred ca este o neintelegere. f are 8 biti. Pe 8 biti se pot reprezenta numere intregi fara semn de la 0 la 255. Deci de unde limita 0...127? Eu m-am gandit la o solutie [...]Operatia cu care se face comparatia este scaderea. XOR este prea restrictiva; poate detecta numai egalitatea. Nu folosesti rezultatul scaderii, ci numai starea indicatorilor C si Z dupa scadere. Daca Z=1 atunci variabilele sunt egale. Daca Z=0, atunci C iti da relatia de ordine intre variabile. Te las pe tine sa experimentezi. Cirip Link spre comentariu
XName Postat Aprilie 20, 2007 Autor Partajează Postat Aprilie 20, 2007 Pai in datasheets asa scrie pt PIC16F84A sunt doua instructiuni XORLW si XORWF , prima se face cu o constanta 0XORWF Exclusive OR W with f Syntax: [label] XORWF f,d Operands: 0 <= f <= 127 d - [0,1] Operation: (W) .XOR. (f) --> (destination) Status Affected: Z Description: ..." Intradevar solutia zisa de tine e mult mai utila, poate prezenta si egalitatea si care este mai mic sau mai mare Trebuie sa-mi fac niste rutine in prinvinta ei Mersi Link spre comentariu
cirip Postat Aprilie 21, 2007 Partajează Postat Aprilie 21, 2007 Hehe... Studiaza putin modurile de adresare. Prima, xorlw, este adresare imediata, adica ii dai la nas data de 8 biti cu care sa faca xor.A doua este adresare indirecta, adica ii spui sa-si ia data de la adresa pe care i-o dai tu in instructiune. 0...127 este domeniul adreselor la care se pot gasi datele, adica locatiile file register-elor. Prin urmare, XORWF f, d inseamna "fa sau exclusiv intre continutul registrului de lucru W si data aflata la locatia cu adresa din f si depune rezultatul in w sau inapoi in (f)". Aici (f) inseamna adresare indirecta, adica data aflata la adresa indicata de valoarea lui f din codul instructiunii. Dar locatia e tot de 8 biti, deci poate reprezenta de la 0 la 255.Cirip Link spre comentariu
TECH_FUN Postat Aprilie 21, 2007 Partajează Postat Aprilie 21, 2007 Uite niste trucuri utile si usor de inteles: http://www.petesworld.demon.co.uk/homeb ... ictips.htm Astea ar trebui sa mai raspunda la niste intrebari de ale tale... :yawinkle: Link spre comentariu
XName Postat Aprilie 23, 2007 Autor Partajează Postat Aprilie 23, 2007 Cirip: Mersi, am inteles acuma. Deabia azi am reusit cat de cat sa-mi raspund in mare la intrebarea de ce au pus memoria pe bankuri si nu toata intrun singura zona. Am citit destul de multe documentatii inainte sa incep efectiv cu microcontrolere, dar nu am remarcat in niciuna sa prezinte de ce pe bankuri :)Tech_Fun: Mersi de link, cu adevart utile. Raspunsurile la multe dintr intrebarile mele Pe parcursul ultimelor zile, am aprofundat Simulatorual si MPLAB, este ft util pt a vedea ce se intampla in interirorul PICului.Din pacate nu am reusit sa lucrez cu TMR0 in simulator, in help scrie ca este suportat, dar nu se incrementeaza deloc. Singura solutie a fost sa-i dau stimuli externi pt GIE si flag-ul de TMR0, insa nu prea e buna solutia, nu pot face calcule de timpiSi mai am o intrebare legata de intreruperi: Am RB7, RB6 doi pini care pot produce intrerupere, in momentul in care acestia se schimba se produce intreruperea, programul executa rutina de intrerupere, in acest timp poate sa apara intrerupere si pe celalalt pin, rutina mea pt prima intrerupere sa zicem ca dureaza undeva la 200 de cicluri, timp in care poate sa dispara intreruperea de pe al doilea pin, stiu ca ramane flagul pt intreruperi activat, dar rutina de la prima interupere se va termina nu voi mai putea sti care din cei doi pini a dat a doua intrerupere ?! Link spre comentariu
cirip Postat Aprilie 23, 2007 Partajează Postat Aprilie 23, 2007 Din pacate nu am reusit sa lucrez cu TMR0 in simulatorMerge brici. Nu e configurat. Reseteaza-i T0CS din OPTION_REG. Timpii de executie ii masori cu Stopwatch.Am RB7, RB6 doi pini care pot produce intrerupere,[...] nu voi mai putea sti care din cei doi pini a dat a doua intrerupere ?Foloseste un registru in care tii o variabila temporara, ca sa stii ce a fost acolo cand ai intrat in intrerupere. Daca ai din nou cerere imediat dupa ce ai iesit, compara ce e in RB cu ce ai in variabila temporara si detectezi de la ce port vine intr. E cam scarpinata cu piciorul stang la urechea dreapta, dar merge. Atentie, nu citi RB-ul in intr, ca-ti sterge conditia de port change. Stii ce zic, da?Cirip Link spre comentariu
TECH_FUN Postat Aprilie 24, 2007 Partajează Postat Aprilie 24, 2007 Stii ce zic, da?Aaa, eu nu stiu :smt009 Am lucrat cu 8051, si acolo era muuult mai simplu. Adica sunt vectori de intrerupere separati pentru fiecare tip de intrerupere. E cam incurcata treaba la pic. Si totusi, ce ziceai de conditia de port change? Link spre comentariu
XName Postat Aprilie 24, 2007 Autor Partajează Postat Aprilie 24, 2007 Atentie, nu citi RB-ul in intr, ca-ti sterge conditia de port change.Nici eu nu prea am inteles la ce te referi, dar eu zic ca la intrarea in intrerupere trebuie sa incarc portul b intro variabila, deci trebuie neaparat sa fac o citire de port b Am ajuns la concluzia ca totusi nu se pot gestiona prea bine intreruperile pe port, daca eu gestionez intreruperea de la primul pin, intre timp apare intreruperea pe pinul 2 dar si dispare ft repede, inainte ca eu sa fi terminat cu prima intrerupereO solutie ar fi fost daca picul ar fi avut flag pt fiecare pin al portului, sau ar mai fi o solutie ca la fiecare cateva cicluri sa testezi portul si daca este si pe al pin sa memorezi undeva, :rolleyes: Se poate sa existe intrerupere in intrerupere, cred ca nu , ca GIE e dezactiva, dar daca eu il activez imediat la prima intrerupere?!Si se poate ca sa imi maresc stiva de mai mult de 8 biti pt ca am facut doar programele simple si am ajuns sa incarc stiva la 6 nivele :DPt proiectele care le am in cap imi trebuie o stiva imensa 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