Jump to content
ELFORUM - Forumul electronistilor
nassus

Cine poate sa imi faca o introducere explicita?

Recommended Posts

vreau sa invat de la A la Z cum se folosesc intreruperile (cum se declara, cum se apeleaza.. etc)folosesc un 16f877a si compilatorul HTPIC © 10x..

Intreruperile sunt o smecherie creata pentru a ameliora neputinta microcontrolerului de a functiona la viteze suficient de mari.Atunci cand este tratata o intrerupere, se abandoneaza programul principal, se salveaza niste registrii esentiali (de obicei W, STATUS, PCLATH insa nu obligatoriu toti) si se trece la rularea portiunii de cod situata la adresa 04h numit si adresa vectorului de intrerupere.Cat timp ruleaza rutina de intrerupere (Interrupt Service Routine), programul principal este mort. Utilizarea ISR cu un compilator implica sa cunoasteti *exact* ce registrii salveaza compilatorul. La multe compilatoare utilizarea operatorilor matematici in ISR duce la "umflarea stivei" sau la timpi morti datorati salvarii/restaurarii automate a unor registrii de lucru.Pentru ca sa putem trata o intrerupere corect este nevoie sa cunoastem exact logica de generare a acesteia. Pentru PIC16F877 utilizat de initiatorul acestui topic, ea se gaseste la pagina 129 a filei de catalog DS30292C, downloadabila gratuit de aici:http://ww1.microchip.com/downloads/en/D ... C16F877%22Observati ca pentru a trata in ISR intreruperea TMR0IF este nevoie de doua setari: TMR0IE si GIE (registrul INTCON pagina 20) trebuie setata in 1 logic din programul principal (main program). Odata facut acest lucru numaratorul de program (program counter-ul) zburda spre adresa 04h (ISR) unde se poate testa TMR0IF si utiliza de exemplu pentru incrementarea unui counter. Dupa fiecare testare a lui TMR0IF acesta trebuie resetat prin software.Odata intrat in ISR, GIE este dezactivat si intreruperile sunt blocate.La iesirea din ISR in mod automat GIE este setat din nou si intreruperile sunt activate. Asadar, in programul principal, intreruperile trebuiesc activate doar pentru a intra prima data in ISR, si dezactivate ori de cate ori se doreste blocarea unei intreruperi specifice (bitii cu terminatia IE) sau in mod global din GIE. O noua intrare in ISR din programul principal implica o noua setare a GIE sau a intreruperii specifice (poate fi PEIE + intreruperea periferica).Pentru tratarea intreruperii TMR0 in ISR este nevoie de dimensionarea prealabila a prescalerului (registrul OPTION, pagina 19) si setarea corespunzatoare a lui T0CS si PSA (acelasi OPTION). Toate operatiile de acest gen se realizeaza in programul principal pentru pot fi consumatoare de timp.Observati ca tratarea lui TMR0IF in ISR ca intrerupere singulara este un moft, ea poate fi executata la fel de bine in programul principal (fara setarea lui TMR0IE), cu conditia ca lungimea programului sa nu afecteze "pierderea" tranzitiilor TMR0IF din 0 in 1 logic la depasirea numararii (rollover).TMR0 este un timer de 8 biti, adica valoarea maxima pe care o poate memora este 255 ( de la 0 la 255 sunt 256 de stari). Depasirea numarariisi setarea lui TMR0IF are loc la tranzitia 255->0). Pentru a realiza un numarator precis cu TMR0 trebuie ca frecventa quartului potrivita cu divizarea prescalerului si eventual a unui numarator suplimentar sa genereze exact divizarea dorita. Nu toate cuarturile pot realiza acest lucru, de aceea simplificarea maxima a codului apre utilizand cuarturi multiplu 2 la puterea n (ca cel de 4.096MHz sugerat sau de 3.2768MHz mai greu de gasit). Asta nu inseamna ca ceasul va functiona fara eroare...Pentru PIC16F877, TMR1 este dedicat realizarii orologiului de timp real fie utilizand cuart extern de 32.768 KHz fie tactul procesor (Fclk/4) deoarece are din start 16 biti + un prescaler la dispozitie.
Link to comment
Share on other sites

1. Pentru care familie de PIC va intereseaza intreruperile? Va intreb deoarece problema intreruperilor este tratata diferit la familii de PIC diferite (ma refer la PIC16xxxx, PIC18xxxx, dsPIC30xxx, etc.,)2. Din pacate nici eu nu lucrez in C, ci in ASM.Cu respect,

Link to comment
Share on other sites

eu am inceput sa pricep faza cu functia interrupt dar inca nu stiu cum este apelata functia specifica pt fiecare intrerupere, adica sa zicem ca avem:unsigned int i;void interrupt test (void){if(TMR0IF)i++;}void main(){TMR0IF=0;TMR0IF=1;GIE=0;afiseaza(i);}merge chestia asta ? adica imi incrementeaza i la fiecare overflow a lui TMR0 ?

Link to comment
Share on other sites

N-ar prea trebui să meargă. După ce îl afişează prima oară pe i se duce în... păpuşoi. Ori pui afişarea într-o buclă infinită, ori chiar în corpul rutinei de întrerupere. În ultimul caz trebuie să ai grijă ca durata reală a afişării să nu depăşească perioada întreruperii.

Link to comment
Share on other sites

Principiul de functionare al intreruperilor este valabil la toate procesoarele (mai mari sau mai mici). In momentul in care are loc intreruperea, poate fi hardware sau software, se executa asa numita rutina pentru servirea intreruperii. Intreruperile mai pot fi mascabile sau nemascabile, cu diferite nivele de prioritate. Mai concret CPU se duce si citeste instructiunea aflata la adresa 04H in cazul PIC16F876, instructiune care de obicei este un salt la adresa rutinei pentru servirea intreruperii. Asta este teoria. Concret, pentru HTPIC trebuie sa ai grija sa validezi intreruperile si sa scrii o functie void interrupt ... In ceea ce priveste salvarea registrilor nu iti bate capul. De asta are grija compilatorul. Daca te uiti in codul in limbaj de asamblare produs vei vedea asta.Nu am apucat sa lucrez cu ultima varianta a PICLite, dar tin minte ca nu permitea apelul altor functii din interiorul rutinei pentru servirea intreruperii (nasol)

Link to comment
Share on other sites

Revin. Rutina pe care ai scris-o nu functioneaza. Toate programele au o bucla principala, se invart in jurul cozii, asteptand sa se intample ceva. La PC asteapta apasarea unei taste care genereaza o intrerupere. A fost un exemplu. In cazul tau, dupa ce face afiseaza, iese din program si gata. Trebuia sa scrii ceva de genul:void interupt f1{..}void main{ initializari while(1) { . . } doObserva bucla infinita din main. Cand TMR0 face overflow, deci intrerupere, atunci se executa f1. Muta afiseaza in f1 si in felul asta ai asigurat refresh-ul. Ai grija sa resetezi flag-ul intreruperii pentru ca sa functioneze si alta data, asta o faci tot in f1

Link to comment
Share on other sites

am facut sa mearga functia fara probleme si acum pot sa afisez de cate ori trece in overflow tmr0.. .sa trecem mai departe: se stie ca tmr0 se da peste cap la al 256-lea impuls al ceasului (fosc/4), cum fac sa divizez impulsurile astfel incat sa am la sfarsit 1Hz.. (folosind si un prescaler) ca am tot incercat sa calculez dar imi da cu virgula si ba o ia inainte ba inapoi

Link to comment
Share on other sites

Citez dintr-un alt topi "ceas cu PIC16876""O varianta de distributie a divizarii ar fi cam asa.1)Divizezi cu 2^6 cu prescalerul.2)Divizezi cu puterea maxima a lui 5 care se incadreaza in 8 biti. Asta este 5^3=125. Deci vei reincarca timer0 cu 125 la fiecare expirare.3)Mai faci o divizare cu 125 cu un numarator de intreruperi.Rata totala de divizare va fi de 64*125*125=1.000.000 adica exact cat iti trebuie. "pentru ca 1000000=10^6=2^6x5^6

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines