Sari la conținut
ELFORUM - Forumul electronistilor

POR si BOR


Postări Recomandate

Am un montaj cu PIC ce merge pe masina. Am o variabila numita NrKm_Total. La alimentare sistem ii citesc valoarea din EEPROM intr-o variabila obisnuita de ram si lucrurile continua, anume variabila de ram este incrementata la fiecare 1 Km parcurs iar valoarea este scrisa si in EEPROM.Este cert ca lucrul cu EEPROM-ul este corect (folosesc CCS C compiler care are niste functii speciale pt asta). "La etaj" cand scriu softul in PIC scriu si valoarea initiala in EEPROM, de exemplu 165000. "Pe asfalt", adica pe masina, constat ca este Ok, valoarea din EEPROM este citita corect si apoi incrementata, a functionat (s-a incrementat corect) saptamani intregi. Am dat jos bateria mare de pe masina iar la reconectare (dupa cateva ore) am constatat ca variabila NrKm_Total are o valoare gresita. Aceasta valoare gresita este incrementata corect in continuare. Intrebare: Cum se rezolva cazul cand dau jos bateria mare si se petrece o scadere de la 5V catre 0... nivele logice pot fi "confundate"? Este problema atat la disparitie cat si la aparitie alimentare?Ce trebuie sa fac in soft ref la POR si BOR? Folosesc 18F452 si CCS C Compiler vers 3. Multumesc.

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

Top autori în acest subiect

Intrebare: Cum se rezolva cazul cand dau jos bateria mare si se petrece o scadere de la 5V catre 0... nivele logice pot fi "confundate"? Este problema atat la disparitie cat si la aparitie alimentare?Ce trebuie sa fac in soft ref la POR si BOR? Folosesc 18F452 si CCS C Compiler vers 3. Multumesc.

Sincer, nu prea inteleg intrebarea, te rog sa o formulezi mai clar.
Link spre comentariu

Consideram ca vrem sa facem un sistem care sa incrementeze o valoare la fiecare minut cat timp este alimentat si sa o afiseze pe un LCD.

Deci dupa o intrerupere a alimentarii si apoi (dupa ore sau zile) reluarea alimentarii, se cere sa continue numararea de la valoarea la care ramasese.

Cum se face asta?

Softul face anumite initializari la main (parcurse o singura data la fiecare alimentare) dupa care intr-o bucla in care pandeste cumva scurgerea timpului de 1 minut.

Intreruperea alimentarii poate sa survina oricand, chiar si in intervalul de timp in care scrierea in EEPROM este "in progress".

In afara de scrierea valorii in EEPROM la fiecare modifficare si citirea valorii la fiecare alimentare mai trebuie facut ceva ca sa mearga ce am spus?

Ceva ref la POR (Power-On Reset) si la BOR (Brown-Out Reset)?

Link spre comentariu

BOD provoaca doar resetul. Chiar daca sesizezi pri BOD ca tzi-a picat tensiunea, picul sta, este in reset. De ce ai avea tu nevoie este un early warning pentru caderea alimentarii, rutat la intreruperi, care de altfel este implementat la unele picuri. Acuma mai depinde shi de valoarea capacitatzii pe linia de alimentare, anume cat timp mai ai la dispozitzie sa-tzi salvezi valoarea in eeprom, pentru ca asta ia cateva ms/octet, plus ca pentru scriere in eeprom itzi trebuie o tensiune minima (parca~).O alta solutzie este sa foloseshti alternativ doua locatzii (A shi B) pentru variabila ta, plus o metoda de verificare a validitatzii datelor stocate. Astfel incat chiar daca itz moare alimentarea in timpul scrierii in locatzia A(resp B), astfel incat valoarea este compromisa, vei putea recupera informatzia din B (resp A). Astfel incat in cel mai rau caz recuperezi penultima informatzie stocata.

Link spre comentariu

pai tinand cont ca circuitul merge la 5V, iar tu il alimentezi la 12V, mai poti folosi un condensator care sa iti dea destul timp cat sa stochezi valoarea in memorie. si e buna si ideea cu stocarea in 2 locatii, sau stocarea in mai multe locatii cat sa poti recupera datele in orice situatie.

Link spre comentariu

probabil ca am sa insist pana am sa renunt si am sa gasesc alta cale de rezolvare.

 

trebuie facut ceva anume la initializari, la functia main? ce?

sau poate vreo directiva?

 

trebuie facut ceva in bucla pentru a detecta scaderea periculoasa a tensiunii de alimentare? ce?

 

if( ceva biti testati aici, poate ceva cu BOR ) { // . inseamna ca tensiunea de alimentare va disparea foarte curand  // . hai sa fac ceva care sa imi asigure recuperarea corecta a datelor //   in momentul cand tensiunea o sa reapara //}

Intrebari:

1. care este conditia din if?

2. ce trebuie facut intre acele acolade ale if-ului?

 

probabil ca este ceva uzual ca tensiunea de alimentare sa fie suficient de constanta etc..

dar eu ma refer exact la cazul in care alimentez si dezalimentez tot montajul in mod intentionat, sa spunem la interval de cateva minute. in aceste conditii ii cer sa isi faca treaba, sa continue o activitate (incrementarea unui numar in exemplu) de la valoarea la care ramasese in moment disparitie alimentare.

Link spre comentariu

Sugestii:1. Foloseste modulul "Low voltage detect" (vezi foaia de catalog, sectiunea 18). Cand vezi ca se ia tensiunea, nu mai initiezi nici o scriere in eeprom. Pe alimentare trebuie sa ai un condensator (eventual si o dioda) care sa tina tensiunea de alimentare valida pentru inca cateva milisecunde, timp in care orice scriere deja initiata sa aiba timp sa se incheie.2. Salveaza variabila la 3, 5 ori 7 locatii diferite. Foloseste apoi la citire o alegere bazata pe majoritate (in caz ca s-a luat tensiunea in timpul scrierii).

Link spre comentariu
  • 2 săptămâni mai târziu...

Ai tinut cont ca un eeprom-ul tine la vreo 10.000 - 100.000 de scrieri? Adica dupa 10.000 km (PIC se lauda cu 100.000) nu mai poti garanta nimic...

Link spre comentariu

As face o sinteza a ceea ce s-a spus mai sus si as considera urmatoarele:1. Un montaj hardware care sa-ti asigure cateva ms (>10) dupa ce se ia curentul2. LowVoltageDetect - ca sa detectezi cand s-a luat alimentarea principala3. Salvezi datele doar cand se ia curentul, pentru a nu uza EEPROM-ul4. Salvezi succesiv in locatii diferite, pentru a uza uniform EEPROM-ul5. Salvezi doua versiuni si un octet de verificare a validitatiiPOR inseamna ca PIC-ul nu porneste atata timp cat tensiunea de alimentare nu e stabila, iar BOR inseamna ca PIC-ul va fi resetat de indata ce tensiunea scade sub un anumit prag (stabilit tot in word-ul de configurare) si va fi tinut in reset pana tensiunea de alimentare revine peste acel nivel.

Link spre comentariu

Ai tinut cont ca un eeprom-ul tine la vreo 10.000 - 100.000 de scrieri? Adica dupa 10.000 km (PIC se lauda cu 100.000) nu mai poti garanta nimic...

In datasheet zice 1000000. Daca folosesti si un buffer circular pentru salvarea la locatii succesive, se poate mari numarul asta de cateva ori si ajunge cu siguranta. In plus, asta e doar un "computer de bord" la nivel amator, asa ca nu cred ca trebuie neaparat sa tina >500k km.
Link spre comentariu
  • 3 săptămâni mai târziu...

Intre 10 mii de scrieri in eeprom, 100 mii si 1 milion de scrieri este deosebire cam mare.

Intr-adevar, in datasheet scrie 1 milion. Retin si chestiunea evitarii scrierii in aceeasi locatie de eeprom.

Daca as putea scapa de anumite conditionari si dificultati, toate legate de hardware, daca m-as putea ocupa numai de soft (inclusiv creare de tool-uri soft)... ar fi bine.

Nu am cum sa fac treaba unui hardist decat greoi, cu poticneli si intarzieri.

 

Editat ulterior

Revin cu o chestiune. Consideram ca kilometrajul classic arata valoarea de 164302 Km. Dorim ca board computerul sa porneasca de la aceasta valoare si sa continue contorizarea.

// 164302 = 00 02 81 CE#define DT0  0x00#define DT1  0x02#define DT2  0x81#define DT3  0xCE// 0727 = 02 D7#define DP0  0x02#define DP1  0xD7#include  <16F876A.H>#device   ADC=10          // conversie A/D pe 10 biti#rom      0x2100 = {DT0, DT1, DT2, DT3,    DP0, DP1}#use      delay(clock=16000000)#fuses    HS, PROTECT, NOWDT, NOLVP, BROWNOUT//

Desconsideram tot ce apare mai sus ref la DP (Distanta Partiala).

In cazul in care scriu in EEPROM valoarea de 164302 (0x00, 0x02, 0x81, 0xCE) "la etaj", pe un programator iar apoi duc controllerul cu 7 etaje mai jos si il infig in soclul lui, in placa aflata pe masina, constat ca valoarea variabilei in cauza (DT = distanta totala) este Ok, este citita corect din eeprom si utilizata in continuare (incrementare la fiecare 1 Km parcurs, rescriere in eeprom cand se schimba).

Aceasta operatie (cu scrisul in eeprom pe programator) am repetat-o de mai multe ori (cu ocazia rescrierii intregului soft) si a fost bine de fiecare data.

Desconsideram orice referire ca "se uzeaza" eepromul, ca e bine sa se scrie la alte locatii, ca e bine sa se scrie mai rar etc - se va face!

 

Dupa aceste desconsiderari ramane concluzia: dintre cele 2 fenomene (alimentare sistem si dezalimentare sistem) se pare la la alimentare este bine!

Inseamna, cred, ca greseala se intampla la dezalimentare: se (poate) scrie ceva prost in eeprom.

 

Care este cea mai putin laborioasa tratare a cazului?

Este suficient sa pun BROWNOUT acolo in directiva fuses si sa nu mai fac nimic altceva in soft?

Link spre comentariu

Depinde cum citesti 164302 din EEPROM: ca word, ca dword, ca byte sau ? Pentru ca daca il citesti ca si dword, trebuie sa il scrii CE 81 02 00. Daca activezi BOR, nu iti garanteaza nimeni ca nu o sa ai probleme cu scrieri partiale. Ar trebui dupa cum s-a zis mai sus sa foloseste doua locatii unde sa scrii valoarea succesiv, si astfel in cel mai rau caz pierzi 1 km.

Link spre comentariu

Variabila NR_KM_TOTAL este de tip "binar complement la 2 pe 32 de biti", tipul U32 (unsigned int32 in forma originala), nu cred ca este problema cu asta sau cu ordinea celor 4 bytes.

 

Pentru scris/citit in/din eeprom folosesc asa ceva:

#define S01       signed int1#define S08       signed int8#define S16       signed int16#define S32       signed int32//#define U01       unsigned int1#define U08       unsigned int8#define U16       unsigned int16#define U32       unsigned int32//// . . .//void write_U16_eeprom(U08 ADDRESS, U16 data){ write_eeprom(ADDRESS+0, MAKE8(data,0)); write_eeprom(ADDRESS+1, MAKE8(data,1));}U16 read_U16_eeprom(U08 ADDRESS){ return MAKE16(           read_eeprom(ADDRESS+0),           read_eeprom(ADDRESS+1)      );}void write_U32_eeprom(U08 ADDRESS, U32 data){ write_eeprom(ADDRESS+0, MAKE8(data,0)); write_eeprom(ADDRESS+1, MAKE8(data,1)); write_eeprom(ADDRESS+2, MAKE8(data,2)); write_eeprom(ADDRESS+3, MAKE8(data,3));}U32 read_U32_eeprom(U08 ADDRESS){ return MAKE32(           read_eeprom(ADDRESS+0),           read_eeprom(ADDRESS+1),           read_eeprom(ADDRESS+2),           read_eeprom(ADDRESS+3)  );}
iar apelurile sunt asa:

write_U32_eeprom(0, NR_KM_TOTAL);    write_U16_eeprom(4, NR_KM_PARTIAL );//// . . .//    NR_KM_TOTAL   = read_U32_eeprom(0);    NR_KM_PARTIAL = read_U16_eeprom(4);

Functiile read_eeprom(...) si write_eeprom(...) sunt ale compilatorului.

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