Sari la conținut
ELFORUM - Forumul electronistilor

Precizie perioada de timp


iuli09

Postări Recomandate

Buna ziua,

 

am construit un montaj simplu cu un microcontroller care comanda intr-o anumita secventa de timp doua relee la apasarea unui buton ; am folosit PIC 16F18313 si PIC 12F629 .

 

Am intalnit o mica problema : durata unui minut programat variaza in plaje mari fata de durata reala . La versiunea cu 12F629 am folosit oscilatorul intern si am presupus ca variatiile ar putea fi de acolo, insa la varianta cu 16F18313 am folosit un oscilator extern (cristal 4Mhz) si aici am avut cele mai mari diferente : durata minutului programat a fost de doar 15 secunde reale . Am compensat aceste diferente prin modificarea corespunzatoare a codului si motajele functioneaza pana la urma cum trebuie dar ma intreb totusi de ce a fost nevoie de aceste ajustari .

 

Acesta este codul scris in MikroC :

 

 

 

// PIC 16F18313
// Pe RA0 buton la masa.
// Pe RA1, RA2 iesiri active in 1 - rezistenta spre baza unui tranzistor.
// RA3 este configurat ca MCLR si este legat la +Vdd printr-o rezistenta de cca 10kOhm





#define Buton  RA0_bit
#define Releu1 RA1_bit
#define Releu2 RA2_bit

char i;

void minut ()   {
delay_ms(240000);
}

void main() {

   OSCEN = 0;                                   //oscilator
   TRISA = 0b00000001;                         // RA0 Intrare , restul iesiri
   PORTA = 0;                                  // reset PORTA
   ANSELA = 0;                              //digital input/output
   WPUA = 0b00000110;                   // pull-up resistor activat pentru RA1 si RA2
   FVRCON = 0;                           // disable voltage reference
   CM1CON0 = 0;                          // disable comparators
   C1ON_bit = 0;                          //
   CWG1CON0 = 0;                          //disable CWG
   ADCON0 = 0;                             //disable ADC
   DACCON0 = 0;                            //disable DAC
   MDCON = 0;                              // disable modulator



  while(1)       {                     // Bucla infinita
   while(Buton);                       // Astept aici apasarea butonului
   Releu1 = 1;                         // R1- ON
   for(i=0;i<5;i++) minut();           // R1 - 5 min ON
   Releu1 = 0;                         // R1 - OFF
   for(i=0;i<10;i++) minut();          // R1 - 10 min OFF
   Releu2 = 1;                         // R2 - ON
   for(i=0;i<5;i++) minut();           // R2 - 5 min ON
   Releu2 = 0;                         // R2-OFF
   for(i=0;i<20;i++) minut();          // R2 - 20 min OFF
   Releu1 = 1;                          // R1- ON
   delay_ms(2500);                        // intarziere 2.5 secunde
   Releu2 = 1;                          // R2 - ON
   for(i=0;i<5;i++) minut();           // R1+R2 - 5 min ON
   Releu1 = 0;                         // R1+R2 - OFF
   Releu2 = 0;                        // R1+R2 - OFF
  }
}

 

 

Problema este aici :

 

void minut ()   {
delay_ms(240000);
}

unde in loc de durata normala a unui minut (60000) a trebuie sa compensez cu un factor de 4x

 

 

Link spre comentariu
  • Răspunsuri 40
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • iuli09

    9

  • Mircea

    7

  • Bandi Szasz

    5

  • djvas

    3

Top autori în acest subiect

Imagini postate

Salut,

     Presupun ca trebuie sa-i spui compilatorului la cat este tactat uC-ul(daca ai PLL activ, trebuie luat in calcul.).  Nu stiu cum e in Microe , dar in XC8 trebuie sa definesti "_XTAL_FREQ"

 

Ex XC8:

 #define _XTAL_FREQ 20000000

 

Sper sa te ajute!

Link spre comentariu
Citat

Salut,

     Presupun ca trebuie sa-i spui compilatorului la cat este tactat uC-ul(daca ai PLL activ, trebuie luat in calcul.).  Nu stiu cum e in Microe , dar in XC8 trebuie sa definesti "_XTAL_FREQ"

 

 

Cred ca am facut deja asta :

 

 

3.png

 

 

 

 

 

Citat

Daca vreti precizie, folsiti intreruperea generata de unul din timere.

 

 

Din pacate asta ma depaseste ; totusi nu e vorba ca as vrea vreo precizie deosebita ...dar nici abateri de 4 ori fata de realitate .

Editat de iuli09
Link spre comentariu

Setarile par corecte. Daca nu gresesc seriile astea de PIC-uri cu numele alcatuit din 5 cifre sunt modele destul de noi si nu este exclus ca compilatorul sa seteze aiurea anumiti registrii, daca a trebuit cumpensat durata de 4x pare sa fie activat PPL -ul pe 4x si PIC-ul lucreaza de 4 ori mai repede. Incercati sa setati manual toti registrii legati de osc manual din cod. Eu am avut probleme cu librariile MikroC si modelele mai noi de PIC in idea in care ADC, SPI, I2C, etc.. pana nu le-am configurat din registrii ori nu mergeau deloc ori mergeau aiurea, nu m-as mira sa aiba ceva scapelnite si la osc.

Editat de Bandi Szasz
Link spre comentariu

Intr-adevat 16F18313 este un model nou , am si avut unele probleme legate de transferul codului dar am reusit in cele din urma sa le depasesc .

 

O sa incerc sa setez manual registrii legati de oscilator . Am vazut ca sunt mai multi ...

 

 

Insa cam acelasi lucru mi s-a intamplat si cu o versiune mult mai veche si mai simplista de chip precum 12F629 ...

 

Codul este in proportie 99% identic .

Editat de iuli09
Link spre comentariu

La 12f629 ai zis ca ai folosit oscilatorul intern... Cel mai probabil PIC-ul mergea la 500 Khz. A explicat @Mircea   aici de ce   https://www.elforum.info/topic/142188-pic-uri-cu-probleme/

 

Am intampinat si eu problema asta de mai multe ori la oscilatorul intern dar cum era ceva simplu m-am multumit cu 500Khz si nu mi-am batut capul.

Link spre comentariu

La modul general daca vrei precizie la timp, atunci folosesti ASM , acolo stii exact cat dureaza o instructiune ; asa cu compilatoarele de C  depinde de compilator ; acum intr-adevar eroarea este destul de mare in cazul tau.

Link spre comentariu

Cind vrei sa faci temporizari nu se folosesc anumite tipuri de functii.

Nu sint programator ca sa explic cum trebuie dar ideea este ca nu se folosesc functii care pot avea durata variabila in timp.

Exemplu functia "while" sau, in general, orice tip de bucla. Programele pt temporizari de de real time utilizeaza un mers liniar daca pot sa spun asa.

Link spre comentariu

@iuli09

Ca sa te convingi ca greseste soft MikroC,

Pune un oscilator extern de 16Mhz fara sa modifici nimic in setari.

Sau

Seteaza in fereastra "MCU Clock..."=1Mhz. si lasa 4Mz extern.

Merge?

Prea frumos suna acel x4 :)

Chiar nu intelegeti ca omul nu are nevoie de precizie? A spus.
Ce ASM si intreruperi ?
Vrea delay de zeci de minute cu precizie de secunde.

Link spre comentariu

@iuli09, ieri seara m-am razboit cu o vechitura de 18F45K22. Asta dupa ce acum 2 zile am avut probleme cu 18F25K50 care nu mergea pe SPI caci frecventa era cu totul alta decat in Edit Project.

 

Compilator Mikrobasic 7.1.0.

 

Ca si cum il apuca strechea la oscilator. Si iti pot garanta ca 45K22 am programat o multime si nu avea problema asta. 

 

In final, dupa ce nici cu temporizarea oscilatorului, am lasat balta Edit Project si am setat totul registru cu registru. 

 

Mi-a fost lene sa reinstalez, era 11 noaptea, dar posibil sa fie ceva corupt in compilator. Nu e numai chestie de PIC.

Link spre comentariu

Liviu , am uitat sa-ti raspund (scuze!) . Am inlocuit in montaj cristalul de 4Mhz cu unul de 16MHz si nu s-a schimbat nimic in ceea ce priveste perioada temporizata ; unde inainte aveam interval de 5 minute , am avut tot 5 minute .

Link spre comentariu

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 cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări