Programare

Da, merge cu pull-down de 10K.

1) Vreau sa folosesc intreruperi ca sa pun procesorul in sleep de cate 1ms pe durata apasarii oricarui buton, respectiv power-off continuu cand nu-i nici un buton apasat, cu trezire la intreruperea oricarui buton.
2) Desi am setat intreruperea sa se activeze la rising edge (apasare), numararea intreruperilor nu-i suficienta. Asa cum am prevazut, apar mai multe intreruperi in momentul apasarii, uneori apar intreruperi si in timp ce butonul sta apasat si destul de frecvent mai apar niste intreruperi si la ridicare. Asadar, m-am gandit sa pun cate doua timere la fiecare buton care sa contorizeze timpul de la apasarea anterioara, respectiv de la ridicarea anterioara, ca sa ignor apasarile si ridicarile f. scurte.

Inca nu m-am apucat de scris codul, dar ma gandesc in avans ca exista o posibila interactiune nedorita intre metoda cu timer si power-management-ul propus. Timerul ala mai merge in timpul power-down? :what:
The Timer/Counter is designed to count cycles of the peripheral clock (PCLK)
The LPC213x supports two reduced power modes: Idle mode and Power-down mode. In Idle mode, execution of instructions is suspended until either a Reset or interrupt occurs. Peripheral functions continue operation during Idle mode and may generate interrupts to cause the processor to resume execution. Idle mode eliminates power used by the processor itself, memory systems and related controllers, and internal buses.
In Power-down mode, the oscillator is shut down and the chip receives no internal clocks. The processor state and registers, peripheral registers, and internal SRAM values are preserved throughout Power-down mode and the logic levels of chip pins remain static. The Power-down mode can be terminated and normal operation resumed by either a Reset or certain specific interrupts that are able to function without clocks. Since all dynamic operation of the chip is suspended, Power-down mode reduces chip power consumption to nearly zero.
La power-down nu zice nimic de peripheral clock. Eu ce sa inteleg? Ca timer-ul o numere in continuare in timpul power-down sau ia si el o pauza?
As putea folosi RTC-ul in loc de timer si cu ocazia asta invat si despre RTC. Dar documentatia placii nu scrie ce ceas foloseste RTC-ul. Ochiometric, placa are un singur oscilator si nu stiu daca e alimentat in timpul power-down.

Idei? Opinii? Recomandari?

PS: DA, imi place sa ma complic. La nebunie. Mai ales cand in final imi iese! :happydork:
 
În documentație scrie ce ceas folosește RTC-ul și cum să-l folosești pentru wake up (hint: oscilator extern setat prin regiștri, vezi dacă ai pe placă un cristal de 32768).

Since the RTC operates using one of two available clocks (the APB clock (PCLK) or the 32 kHz signal coming from the RTCX1-2pins), any interruption of the selected clock will cause the time to drift away from the time value it would have provided otherwise. The variance could be to actual clock time if the RTC was initialized to that, or simply an error in elapsed time since the RTC was activated.While the signal from RTCX1-2 pins can be used to supply the RTC clock at anytime, selecting the PCLK as the RTC clock and entering the Power-down mode will cause a lapse in the time update. Also, feeding the RTC with the PCLK and altering this time base during system operation (by reconfiguring the PLL, the APB divider, or the RTC prescaler) will result in some form of accumulated time error. Accumulated time errors may occur in case RTC clock source is switched between the PCLK to the RTCX pins, too.
The RTC interrupt can bring the microcontroller out of power-down mode if the RTC is operating from its own oscillator on the RTCX1-2 pins

Butoanele nu-s perfecte; pui un cooldown cu timestamp pe fiecare (ex: 30ms). Măsoară cât de repede poți apăsa butonul și setează cooldown în funcție de asta. La rising edge crești contorul doar dacă au trecut mai mult de X ms de la ultimul rising edge.

În funcție de ce fire mai ai pe lângă se întâmplă să apară și curenți induși. Eu am un contor de AC care are și ieșire de monitorizare (practic dă un impuls la fiecare Watt măsurat). Versiunea naivă (întrerupere pe impulsul ăla) n-a funcționat de nici un fel, pentru că contorul stă pe un rail DIN cu tot felul de siguranțe and stuff, iar firele de monitorizare treceau pe lângă tot restul de fire de AC - dacă aprindeai sau stingeai lumina clar credea că e un impuls :smile:. Dar în specificațiile contorului scrie că impulsul are 50 de milisecunde - iar asta m-a ajutat să îl fac să meargă perfect - ignorând tot ce nu are între 47 și 52 de milisecunde. Și atunci am putut să obțin chestii de genul ăsta (înainte de asta rezultatul era ceva super noisy, diferența între min/max fiind foaaarte mare).

1580546973005.png
 
În documentație scrie ce ceas folosește RTC-ul și cum să-l folosești pentru wake up (hint: oscilator extern setat prin regiștri, vezi dacă ai pe placă un cristal de 32768).
RTC deci. OK. O sa ma uit diseara ce se poate face.
Butoanele nu-s perfecte; pui un cooldown cu timestamp pe fiecare (ex: 30ms). Măsoară cât de repede poți apăsa butonul și setează cooldown în funcție de asta. La rising edge crești contorul doar dacă au trecut mai mult de X ms de la ultimul rising edge.
Nu merge cu un singur timer. Exemplu:
Cooldown 250ms (max. teoretic 4 apasari/secunda, care e un ritm f. decent). Daca cumva am tinut apasat butonul 260ms (o apasare ceva mai lunga, care e foarte probabil sa apara) si la ridicarea butonului mai apare o intrerupere aiurea, o sa mi-o numere si pe aia. In afara de durata apasarii (rising-edge -> off), mai trebuie un contor care numara de la ultimul moment cand butonul inca era apasat pana la urmatoarea apasare/intrerupere, adica trebuie o bucla care monitorizeaza periodic butonul apasat, astfel incat sa contorizeze doar perioada "off", nu si durata apasarii.
Ghinion ca intreruperea nu merge setata pentru ambele "edge". BTW, ar merge "level", dar imi tine procesorul continuu treaz pe toata durata apasarii; nu mai merge "sleep" de cate 1ms.
 
Clar trebuie să detectezi când s-a întâmplat și deconectarea, acolo trebuie să pui cooldown-ul de fapt; cum o faci ca să împaci și piticii și limitările hardware e treaba ta (nu mi-e clar de ce nu poți să verifici la fiecare 1ms dacă s-a eliberat butonul).
 
RTC fail. Am incercat sa folosesc counter-ul (ala care numara 32768 de impulsuri ale ceasului intr-o secunda). Nu stiu unde e problema ca nu ma descurc sa fac debugging doar cu alea 8 LED-uri de pe placa. Deci imi trebuie intai display-ul.

In timp ce display-ul este pe drum din China, am luat din targul de vechituri o față de player auto no-name. Junk ordinar. Dar are display iluminat cu 8 caractere (din segmente) plus niste simboluri si niste bling-bling specifice playerelor auto. Din nefericire, conectarea e pe un bus proprietar, Sanyo CCB. Dar CCB seamana foarte bine cu SPI. :wink: Practic am reusit sa "scanez" toate segmentele de pe display trimitand pachete de date CCB (8biti adresa, 156biti date si 4biti power management) sub forma a 21 de pachete SPI + bit-bang pe un GPIO cu rol de ChipEnable. :bravo:
Urmeaza sa gasesc bitul pentru fiecare segment si sa "pictez" caractere cu segmentele alea.
 
Last edited:
Are doua seriale, dar nu-mi trebuie serial pentru dispozitivul final si mi-e lene sa ma apuc si de alea. :tongue:
BTW, are cineva o functie C pentru convertit long int => string (ceva human readable, dec/hex)? PS: Imi este neclar ce inseamna "int" in contexul unui microcontroller. 16 bit? 32bit?
 
Int depinde de combinația compilator + CPU, deci trebuie să te distrezi.

Pentru int => string nu mai bine folosești ce-ți dau bibliotecile de C? sprintf / snprintf? Că de-aia folosești C și nu scrii biți în flash cu lanterna, că nu e nevoie să reinventezi roata la fiecare pas. Și atunci nici nu contează cât e intu'.
 
unsigned char x[8];
x="bla bla";
imi da warning ca se face conversie intre signed si unsigned. Adica un caracter grafic va avea valoare negativa? WTF?!
 
Total neaplicabil. Nu am stdio.h, nici strcpy(). Dar am inteles cam ce vrea sa zica tipul ala.
Sa imi explice cineva ce anume fac ghilimelele duble, ca n-am inteles.
 
Da, o porcarie. ASM-ul nu face nici o diferenta intre signed si unsigned cand vine vorba de string-uri, ca oricum lucreaza numai cu PTR [ceva]. Porcaria este la IDE si compilator care considera char != unsigned char si, simultan, char != signed char, de parca ar exista trei stari diferite. Deci daca am pus cumva signed sau unsigned la vreo variabila, pointer, [orice!], care va interactiona vreodata cu ceva declarat cu ghilimele, atunci... ghinion, nu se compileaza indiferent ce --signed_char sau --unsigned_char ii setez dupa aia.
Sa-i ia dracu'.
 
Da, ăștia care inventează limbaje de programare de nivel înalt cu sintaxa lor rigidă cu tot, să fie arși pe rug! N-au auzit de sinonime, de "io vreau asta da' altfel"? Niște încuiați.
 
considera char != unsigned char si, simultan, char != signed char, de parca ar exista trei stari diferite.

Chiar sunt 3 stări diferite: una în care zici că nu contează semnul și 2 în care ții cont de el.

Nu mai bine ne zici ce vrei să faci, nu cum vrei să faci?
 
Vreau sa am totul unsigned, explicit. Aparent, daca vreau asta, trebuie sa scriu string-urile index cu index.
str[0]='S';
str[1]='U';
str[2]='X';
 
Și vrei unsigned pentru vreun motiv practic anume și explicabil, sau fiindcă piticul cu logica ta?
 
1) Sanse mai mici de a gresi.
2) Am contoare care se dau peste cap (intentionat).
3) Nu trebuie sa fac conversii intre signed si unsigned.
Oricum, discutia e degeaba acum, ca am sters unsigned de la string-uri.
 
Back
Top