04-01-2018, 09:48 PM (This post was last modified: 04-01-2018, 09:51 PM by mikikg.)
>>> Shvatio sam kako timer radi i mogu reci da je to fantasticna stvar...jako mi se dopada kako je to osmisljeno
Ko se jednom "primi" na tajmere/brojace taj se tesko posle odvaja od toga, evo trenutno jedan projektic sto radim koristim svih 5 komada HW tajmera/brojaca u STM32F1 i jos 14 komada SW tajmera, 64 bit : )
(04-01-2018, 09:41 PM)ronovar Wrote: Da to sam postavio dakle brojac cim dodje do 65535 pokrene interrupt u kojemu se pocetna vrijednost postavlja na 18660 naredbom:
Ovde si pogresio. Ne pokrece se interapt kada brojac dodje do 65535. Interapt se pokrece kada se izvrsi prebacivanje sa 65535 na 0. To je jos jedan inkrement.
Greska u tvom slucaju je mala, ali postoji. Ona je jednaka 256/12MHz. To ne mozes ni da osetis na primeru 1s. Kada radis sa dosta manjim vremenima, ova greska je primetna. Inace bitno je da znas da se interapt generise kada se prebaci 65535 na nulu. Odatle u onoj matematici ide 65536-x, a ne 65535-x.
U redu razumijem znacii kada interrupt se prebacuje sa 65535 na 0....znaci kod mene u mome primjeru interrupt pocinje brojati od 18661 do 65535 zatim se poziva interrupt koji postavlja led diodu on ili off postavljam u interruptu vrijednost na 18661 jer se je sa 65535 interrupt vratio na 0 i u interruptu sam ja 0 postavio da pocne brojiti od 18661....znaci sve sam dobro napisao kod samo sam se krivo izrazio
Eto sutra cu da napisem kod za multiplexing pa cemo da vidimo koliko sam i to savladao...zasad cu ici samo preko simulatora da vidim koja brojka se gasi/pali jer cekam da mi stignu sa ebaya 7 segmentni displayi...
Ta vrsta greskica se svuda provlaci, cesto se i meni dogodi da promasim nesto za +/-1 ali u testiranju se to mora pokaze, konkretno za tajmer treba Frekvencmetar i preko toga se lepo kalibrise, za testiranje brojaca treba Brojac (Timer/Counter), mora sve da se slozi, evo bas gore spomenuti moj projektic, tesirao sam tako da sam generisao preko 1 MILIJARDE impulsa, ni jedan impuls nisam "zagubio" a bio sam bas nasao gresku da sa sam morao da uradim negde -1 i posle toga sve cucnulo.
Nisi dobro razumeo. Ti si u kodu stavio ovo:
Timer1=&h48e4 ' 1sec interrupt
To je 18660. To znaci da ti tajmer broji od ove vrednosti. Tajmer ne broj do 65535, vec broji do 0 ili do 65536. Kako god hoces. Samo ne broji do 65535. Kada oduzmes 65536-18660=46876 dobijes da tajmer generise interapt na svakih 1,0000213333333333333333333333333s
Kada u tajmer upises 65536-18661 = 46875 onda ti tajmer generise interapt na svakih 1s. Greska tvog racuna je 21.3us
Vec sam napisao da ova greska nije velika za blinkanje led, ali ako budes pravio neki casovnik na ovaj nacin (ne kazem da se pravi ovako) onda ces imati na svaku sekundu gresku od 21.3us. To znaci da ces dnevno da pravis gresku od 1,84032s, a godisnje 671,7168s. Ovo su velike greske.
Zato je bolje da dok sada ucis sa tajmerom, da razumes da se UVEK racuna i onaj jedan inkrement sa 0xFFFF na 0 i to je jos jedan i tek kada se on desi generise se interapt.
Da razumijem sada...ovo je dobro da si mi napomenuo jer kako i sam kazes kasnije kod osjetljivih timinga ce ovo biti povelika neticnost...timer se postavlja na pocetnu vrijednost od koje pocne da broji a to je 18661 u mome slucaju...znaci kod ukljucenja napajanja timer pocinje brojati od pocetne vrijednosti 18661 do 65536 kada krene na 0 napravi interrupt u kojemu postavlja se timer opet na pocetnu vrijednost 18661 upali/ugasi led i vrati se u glavni do loop petlju i tako se vrti u krug.
Jedan inkrement timera se racuna:
256 / 12MHz = 21,333uS
Timer1 = 65536 - (1s / 21,333uS = 46875) = 18661 postavljam kao pocetnu vrijednost timera
Provjera koliko sekundi uzima: 46875 x 21,333uS = 1sekunda...točno kao sat.
Gore navedena formula funkcionira i to sam sada bas malo računao i vidio da odgovara jedino jedna nula bjezi manje kod racunice jer je jedna sekunda 1000000us ali mislim da sa gornjom formulom su greske svedene na minimum.
Nema nikakve greske u formuli. Jedina greska je sto si ti uzeo u racunici 21,333us, a prava vrednost je 2,1333333333333333333333333333333e-5. To je samo greska zaokruzivanja.
I još dopuna. Neće baš biti tačno kao sat jer od trenutka kada se dogodi prekid do trenutka kada ti u prekidnoj rutini uneseš početnu vrednost za Timer1, prođe neko vreme. Program treba da skoči na prekidnu rutinu, sačuva sve što treba (ove stvari zavise i od MCU) pa tek onda ti na početku prekidne rutine upišeš:
Interrupt Ovf1(), Save 1 Timer1=&h48e4 ' 1sec interrupt
Dakle, imaš grešku koja može a i ne mora da bude značajna. Ima načina i da se ta greška izbegne ali za početak dovoljno je samo da znaš da i to postoji.
Da u pravu si...to je kod koji sam prepisao iz primjera fastavr-a pa nisam pratio...timer je po ukljucenju napajanja iskljucen i tek kad se timer inicializira i starta onda pocne da broji...nov sam u ovome..pa se grijesi..ali sada mi je vec jasniji timeri..trenutno proucavam multipleksiranje 3 digit 7 segmentnog displaya..jedan lik na youtube lijepo je usporio svaki segment da se vidi kako se pali gasi pojedini segment bas fino objasnjeno da se lakse shvati..jedva cekam da stignu displayi pa da pokrenem i ja tako...
Dok ti ne stignu displeji poteraj ti onaj tvoj Proteus. To treba da radi. Ja ga često koristim baš u situaciji dok mi ne stignu sve komponente. Ne možeš sve da simuliraš, drugačije je nego prototip ali pomaže dosta.
04-02-2018, 10:04 AM (This post was last modified: 04-02-2018, 10:21 AM by mikikg.)
(04-02-2018, 09:23 AM)gorankg Wrote: I još dopuna. Neće baš biti tačno kao sat jer od trenutka kada se dogodi prekid do trenutka kada ti u prekidnoj rutini uneseš početnu vrednost za Timer1, prođe neko vreme. Program treba da skoči na prekidnu rutinu, sačuva sve što treba (ove stvari zavise i od MCU) pa tek onda ti na početku prekidne rutine upišeš:
To znaci da kod AVR-a nema auto-reload za brojac?
Kod STM32 postoji auto-reload (ARR-Auto Reload Register), u taj registar se upise isto kao i kod AVR vrednost brojaca ali se ona nakon overflow (prelazak sa max pa na 0) sama ponovo automatski upise, u tom trenutku se generise interapt/flag i program moze da obradi prekid "kad god stigne" pri cemu se ne remeti tajming brojaca, on ce uvek raditi kako je zadato. Na ovaj nacin se sprecava kumulativna greska koja bi se pojavila kada bi program "sa malim (promenljivim) zakasnjenjem" obradjivao tu reload vrednost.
(04-02-2018, 09:23 AM)gorankg Wrote: I još dopuna. Neće baš biti tačno kao sat jer od trenutka kada se dogodi prekid do trenutka kada ti u prekidnoj rutini uneseš početnu vrednost za Timer1, prođe neko vreme. Program treba da skoči na prekidnu rutinu, sačuva sve što treba (ove stvari zavise i od MCU) pa tek onda ti na početku prekidne rutine upišeš:
To znaci da kod AVR-a nema auto-reload za brojac?
Kod STM32 postoji auto-reload (ARR-Auto Reload Register), u taj registar se upise isto kao i kod AVR vrednost brojaca ali se ona nakon overflow (prelazak sa max pa na 0) sama ponovo automatski upise, u tom trenutku se generise interapt/flag i program moze da obradi prekid "kad god stigne" pri cemu se ne remeti tajming brojaca, on ce uvek raditi kako je zadato. Na ovaj nacin se sprecava kumulativna greska koja bi se pojavila kada bi program "sa malim (promenljivim) zakasnjenjem" obradjivao tu reload vrednost.
Ima auto-reload funkciju, ali ovde je primer sa tmr overflow gde softverski uradi reload. Ako se koristi auto reload onda se koriste CCP registri, ali se ne spajaju fizicki na izlaze, vec samo urade reload. Kod XMEGA je to malo drugacije uradjeno. Ovo je osnovna AVR arhitektura i kod njih su neke stvari limitirane u odnosu na XMEGA.
04-02-2018, 02:01 PM (This post was last modified: 04-02-2018, 02:34 PM by ronovar.)
Napisao sam kod za 7segmentne displaye pa me zanima koliko ms mora da bude timer za interrupte?
Ako sam dobro shvatio timer treba da bude 5ms da se pokrece jer imamo tri cifre znaci za sve tri cifre potrebno je 3x5ms=15ms kad to podjelimo sa jednom sekundom dobijam da je vrijeme osvjezavanja 66,667Hz pa ako je to tako onda je to dovoljno jer frekvencija treba da bude veca od 50Hz.
Za timer koji radi interrupt svakih 5ms sam stavio prescaler na 1 posto mi je tako blize brojka interruptu 65536 i on iznosi sa 12MHz kristalom i preskalerom:
T = 1 / 12MHz = 8,333e-8s
N = 0,005s(5ms) / T = 60000
P = 1
n = N / P = 60000
Znaci $Timer1=&hea60
Jeli bolje da se koristi preskaler na 1 ili na npr da ostane 256? Ja sam gledao da bude cim blize interrupt brojki do koje broji a to je 65536.
Evo i komplet koda za display pa ako moze se pogledati dali je ok...promjenio sam nekve nazive varijabli..definirana je tablica sa decimalama kao array to tablica zauzima 9 bytova u memoriji i kod prikljucenja MCU na napajanje ona se ucita u SRAM i kasnije se samo poziva iz interrupta iz rama decimala i salje BCD kod na display....ja u proteusu nisam uspio da dobim brojanje nego mi samo treptere brojke 000 pokusat cu sada da skinem nekvi stariji proteus jer ovaj 8,6 ocito kod mene pravi probleme...
Primjetio sam i da dosta flasha koristi ovaj kod za 7segmentne displaye..presao sam na atmega8 jer mi fastavr ima za njega optimizaciju a da je 28pinski CPU...kod ATMega328p koji imam doma radi probleme FastAVR (jer nema unutarnju optimizaciju pretvarajna bas u asm) i nerade na atmega328p timeri..tako da cu sa atmega8-16pu da radim i sa 12MHz kristalom...a MCU ima 8kb flasha, 1kb srama i 512bytova eeproma..vise nego dovoljno...i tesko da cu popuniti i pola toga flasha...
(04-02-2018, 02:01 PM)ronovar Wrote: Napisao sam kod za 7segmentne displaye pa me zanima koliko ms mora da bude timer za interrupte?
Ako sam dobro shvatio timer treba da bude 5ms da se pokrece jer imamo tri cifre znaci za sve tri cifre potrebno je 3x5ms=15ms kad to podjelimo sa jednom sekundom dobijam da je vrijeme osvjezavanja 66,667Hz pa ako je to tako onda je to dovoljno jer frekvencija treba da bude veca od 50Hz.
Za timer koji radi interrupt svakih 5ms sam stavio prescaler na 1 posto mi je tako blize brojka interruptu 65536 i on iznosi sa 12MHz kristalom i preskalerom:
T = 1 / 12MHz = 8,333e-8s
N = 0,005s(5ms) / T = 60000
P = 1
n = N / P = 60000
Znaci $Timer1=&hea60
Jeli bolje da se koristi preskaler na 1 ili na npr da ostane 256? Ja sam gledao da bude cim blize interrupt brojki do koje broji a to je 65536.
Sad dali je tako ok?
@ronovar
Prijatelju, posto pocinjes polako i uspesno da ulazis u ovu pricu, moj savet ti je da vreme osvezavanja displeja krenes od neke vrednosti tipa 0,5s. Ovu vrednost sam namerno rekao, posto smanjivanjem te vrednosti videces kakva je situacija sa osvezavanjem i neprimecivanjem promene ispisa na displeju. Postoje razne price oko frekvencije osvezavanja, ali moje misljenje je da sam proeveris koja je granica i sta prija oku i koliko se to razlikuje kada puno povecas frekvenciju osvezavanja. Tako se najbolje uci i niko nece moci da ti da bolji savet, nego tvoja perzistencija vida.
Sto se tice faktora deljenja, tu opet niko ne moze da ti pomogne, osim samog sebe. Mogu da ti dam samo neke savete, kao pocetne, pa ces vremenom sam da osetis kako sta uraditi. Ja i posle 20 godina programiranja MCU-ova ne mogu da ti kaze, egzaktno kako biram vrednost delitelja. Evo nekih saveta:
Frekvencija rada MCUa!!! Kod tebe je 12MHz => Tcpu = 83,33..ns. Ako ti je TMR 8-bitni, to znaci da maksimalno moze da generise do 21,33us. Ako ovu vrednost brojis sa nekim softverskim brojacem, onda ce CPU cesto da ti prekida glavni program. To takodje moze da se manifestuje na ostale prekide. Ako dodelis TMR-u neki delitelj, onda se ovo vreme povecava, tj. skracuje se vreme prekidanja glavnog programa.
Sve je to stvar kompromisa i potreba.
Najbolje je da sam probas sve ovo i vidis kako ti se sta manifestuje. Sam ces sebi biti najbolji ucitelj,
(04-02-2018, 02:41 PM)ronovar Wrote: Evo i komplet koda za display pa ako moze se pogledati dali je ok...promjenio sam nekve nazive varijabli..definirana je tablica sa decimalama kao array to tablica zauzima 9 bytova u memoriji i kod prikljucenja MCU na napajanje ona se ucita u SRAM i kasnije se samo poziva iz interrupta iz rama decimala i salje BCD kod na display....ja u proteusu nisam uspio da dobim brojanje nego mi samo treptere brojke 000 pokusat cu sada da skinem nekvi stariji proteus jer ovaj 8,6 ocito kod mene pravi probleme...
Primjetio sam i da dosta flasha koristi ovaj kod za 7segmentne displaye..presao sam na atmega8 jer mi fastavr ima za njega optimizaciju a da je 28pinski CPU...kod ATMega328p koji imam doma radi probleme FastAVR (jer nema unutarnju optimizaciju pretvarajna bas u asm) i nerade na atmega328p timeri..tako da cu sa atmega8-16pu da radim i sa 12MHz kristalom...a MCU ima 8kb flasha, 1kb srama i 512bytova eeproma..vise nego dovoljno...i tesko da cu popuniti i pola toga flasha...
Pogledacu ovo kasnije, pa cu da ti dam savete. Inace, moj savet ti je da posto vec ulazis u pricu programiranja MCU-ova, predjes na C, umesto Basic-a. Instaliraj Atmel studio. Stojim ti na raspolaganju za bilo koje pitanje u vezi C-a i/ili AVR-ova. To su moji omiljeni kontroleri i koristim ih vec jedno 10 godina.
Moze nema problema..kad se stigne se pogleda pa mi se kaze gdje je greska...jer mi u simulatoru neradi samo su 000 osvjezene a dok stigne ovaj mjesec 7segmentni display vec bi mogao da simuliram u stvarnom svjetu...i usporio paljenje i gasenje digita...
Jos malo i usavrsit ce se ovaj 7 Segmentni 3 cifreni display i to ce da radi kako treba...e sada ako moze par prijedloga sto je najbolje korisiti za ocitavanje thermocouple senzora?
Vidim YIHUA 937 koju imam i HAKKO sheme sto su po netu koriste opampe koji jakoo mali napon pojacavaju 100x stavi se referentni napon i onda se preko referentnog napona ocitava preko ADC konvertera ocitana vrijednost i po formuli se unutar MCU izracuna temperature i naravno tu varijablu ce da pokupi MCU u interruptu i lijepo prikaze na 7 Seg displayu..dakle zanima me koji je najbolji pristup ocitavanje senzora thermocouplera?
kod MAX6675 vidim da unutra ima opamp koji pojacava slabe uV sa thermocouplera, zatim to izracuna i posalje preko SPI sabirnice rezultat izracunate temperature, i jos ima cold-junction kompenzaciju...12-bitnu rezoluciju ocitavanja senzora...stvarno mocan čip koji ima sve u sebi...dakle MCU samo pročita preko SPI sabirnice rezultat i prikaze na 7 Segmentnom displayu...jedina "mana" je da nema u DIL-8 kucistu nego samo SMD verzija ali nije ni to tako strasno..po datasheetu ima +/-3C gresku sto je odlicno...pa me zanima koliko ima gresku LM324 opamp?Mozda ako se nadje MAX6675 alternativa u DIL8 i da je lako nabavljivo...
Dakle koje bi bilo vase rjesenje za ocitavanje k-type thermocuplera?
Prijatelju, iskreni savet. Batali temperaturu termocouple, dok ne proradi displej. Samo deo po deo radi i neces imati nikakve frke. Ako krenes sve odjednom, neces nikada da zavrsis. Idemo polako i brzo cemo da predjemo na temperaturu.
04-02-2018, 04:55 PM (This post was last modified: 04-02-2018, 04:59 PM by mikikg.)
Ja volim da teram taj 7-Seg LED u High-Definition, sta 100Hz, 120Hz, more 1kHz : D ... Zgodno je za jos neke interne vremenske baze, koliko god MCU tajmera da ima ja bih sve potrosio, bolje oni da rade to sto treba nego ja da pisem program opet to isto da radi : )
Zanimljivo bit ce i to samo prvo da mi proradi 7 segmentni display u proteusu...zasada ostavljam temeperaturu dok se ne sredi ovaj display...ali opet tu je i 8 bitni kontroller pa neznam koliko on moze Hz da povuce...mada mislim da ce to biti kako sam postavio 5ms interrupt timer i 256 prescaller da ne prekida previse glavni program....a kako ce to da radi vidjet cemo kad stigne display pa cu lijepo staviti delay...i snimiti i postaviti tu snimku onda ce se najbolej vidjeti..