pull down

igram se s PIC-om, i imao sam problema za koje sam zakljucio da imaju veze sa "float" stanjem na pinu. i sad gledam, mislio sam nalemiti otpornik na pic i dobiti (kako sam shvatio) pull-down otpornik, te bih dovodjenjem +5V na pin njega "upalio", dok bi ostatak vremena bio uzemljen ILI imao fizicki prekidac koji kad je OFF je spojen na masu, a ON pusta tih 5V. medjutim, vidim da u PDF-u postoji RBPU registar koji je po defaultu iskljucen, ali je interni "pull up", pull down nema? konkretno 16f722, a vidim to i na 18f2450

sta bi to znacilo? da je zapravo uvijek inzenjerska praksa da se uvijek na fizicki prekidac odnekud dovodi GND, koji prekidac kad je "ukljucen" salje dalje do MCU? ako imam zicu od 5m izmedju prekidaca i MCU-a, nece li se desiti da nesto "iscijedi" taj napon i bez sklopke?

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn
Loading thread data ...

Nema, ima samo pull-up. Nisam jos koristio mikrokontroler koji ima i interne pull-down otpornike ali se cini da neki imaju i jedne i druge.

S ukljucenim pull-up otpornicima gumb spojis na masu pa low na ulazu znaci da je gumb stisnut - zasto bi ti trebalo da znak da je gumb stisnut bude bas high?

--
Chupo
Reply to
Chupo

zato sto sad upravo mjenjam program zbog toga varijable su do sada bile nesto tipa: "pin=varijabla=true". sad ocito to nije tako, nego je sad "varijabla je NOT pin" nema veze, promjenit cu to, nego nisam za tu praksu uopce znao (nemam profesionalno veze sa strujom)

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

Da. S obzirom da postoje samo interni pull-up otpornici, nema se izbora nego ili gumb spojiti prema masi i program promijeniti tako da stisnuti gumb --> low, ili koristiti vanjske pull-down otpornike. Program bi morao mijenjati i ako bi postojali interni pull-down otpornici, a ako bi bio napisan uz koristenje #define i direktiva za uvjetno kompajliranje, bi kod prebacivanja s pull-down na pull-up morao promijeniti samo jedan flag. Recimo umjesto:

#define STISNUTI_GUMB high

bi stavio:

#define STISNUTI_GUMB low

--
Chupo
Reply to
Chupo

IMHO, jednostavnije je. Ne treba ti externi napon, jednostavna integracija s open collectorom, itd.

Ni¹ta neæe "iscijediti" napon na 5m kabla (radi se o uA), a na smetnje nije otporan ni jedan komad drota.

--
Pozdrav! 

     Tomy, 9A5ALL 
 Click to see the full signature
Reply to
Tomy, 9A5ALL

a oprosti, da li imas kakva iskustva sa mikroBasicom za PIC?

naime, nikako ne mogu pronaci nacin da definiram "boolean" varijable, iako mi se to cini trivijalnim odnosno, cini mi se da je moguce kao komad bajta ali samo za predefinirane adrese, odnosno, moguce je ovo:

symbol step1_not_on_max_position =portb.0 'LOW = on position symbol step1_not_on_min_position =portb.1 'LOW = on position

i tada imam boolean varijablu step1..... koja je true ili false ali ne mogu izmisliti svoju bolean varijablu ni na koji nacin, nesto tipa: "dim completed as boolean"

pokusavao sam izmisliti nesto kao: "dim info as byte" "dim completed as info.1"

ali izgleda da tako ne moze

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

dac

U?

tnje =

ha nista, napravit cu tako, nema druge :)

-- =

Using Opera's mail client:

formatting link

Reply to
nn

Nisam radio s MikroBasic-om, moguce da kompajler nema tip boolean pa umjesto njega koristis variablu koja zauzima jedan byte (char?), pogledacu kasnije koja je tocno syntaxa pa ti javim.

--
Chupo
Reply to
Chupo

hm, da, u pravu si... imaju nekakav char i byte koji su izgleda isto?... a sad vidim da ima i nekakav sbit a onda bi iz toga mozda bio put kao:

dim info as char dim nesto as sbit at info.1

al opcenito su me razocarali 8-bitni mcu-i. stekao sam dojam da cim ljepsi kod sam napisao, koristeci strukture i sl, tim sporije je bilo izvrsenje koda. odnosno, vise taktova je oduzelo, i naoko uspori cijeli MCU!

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

Da ali moras racunati na to da ce ti takav nacin stednje RAM-a *mozda* usporiti program jer bez da provjeris ne mozes znati da li ce compiler individualne bitove testirati s instrukcijom za testiranje bita ili ce ih testirati preko maske i logickih operacija, da li ce svako testiranje rezultirati pozivom neke genericke rutine koja sluzi za jos par drugih stvari, ...

Nazalost, dosta je mukotrpno zakljuciti sta je Basic compiler napravio i kako ga natjerati da napravi bolji kod, jedini nacin je da disassembliras vremenski kriticnu rutinu, ovo je recimo primjer gdje sam disassemblirao neki firmware:

formatting link

I to je 99% da je taj kod napravio MikroBasic-ov compiler, zakljucio sam to po nekim drugim dijelovima gdje su se parametri poklapali s nekima od parametara naredbi s MikroBasic-ovoga popisa.

Ovaj dio koda je inace nista drugo nego obicna IF-THEN rutina, ovdje mozes vidjeti po cemu sam to zakljucio:

formatting link

Isto tako je vrlo lako zakljuciti da bi bez koristenja Basic-a ili koristenjem C compilera napisao daleko efikasniju rutinu koja bi radila isto.

Ovdje:

formatting link

mozes vidjeti jos jedan primjer disassembliranja neke funkcije, ne sjecam se vise da li je to bio kod iz istog firmware-a, u komentarima ima par gresaka koje sam otkrio tek kasnije ali screenshot-ovi mogu posluziti kao uvid u postupak. Istina, ja sam tu disassemblirao tudji firmware za kojega nisam imao source, ali prakticki ti dodje na isto i kad analiziras sta je compiler napravio od tvog programa.

Puno ovisi o compileru, da si koristio C, kod bi sigurno bio puno brzi ali se najvjerojatnije moze ubrzati i taj kojega si napisao. Ako kod nije tajna, stavi ovdje:

formatting link

copy/paste stvari za koje ti se cini da trose previse taktova (ukljuci 'Plain Text' i makni kvacicu s 'Run code') pa cu vidjeti da li se i u Basicu moze napisati znatnije brzi kod (koji onda mozda vise nece biti tako lijep ko sta je sad, ali ce biti brzi).

--
Chupo
Reply to
Chupo

hvala, ali iskreno, gledajuci sve ovo, razumio sam samo da je to asembler :) (dobro, shvatio sam sto zelis reci, ali nisam mogao iz asemblera nista shvatiti)

nadam se da sam dobro pejstao?

formatting link

hvala na trudu, NIJE POTREBNO DA SE MUCIS, pejstam to cisto razgovora radi i to mislim ozbiljno!! imat cu boljih pitanja :)

recimo tamo je dio koda, odnosno funkcija koja ima samo jedan zadatak, pomak stepera za +1 ili -1 i zapamtiti novi polozaj stepera. no, posto nju pozivam iz interrupta, koji pogoni tajmer, cini se da je u ovom obliku prilicno zahtjevna. prije nje sam imao steper zapisan u obliku strukture pa sam tako mogao zvati npr: stepper.current_position = xxx ili stepper.goto_position = ccc i sl. ali to je bilo JOS sporije. a jedan od nacina primjecivanja sporosti jest na nacin da - pozovem delay_ms(5000) sekundi i vidim da je ponekad potrebno 6-7 sekundi, u ovisnosti u kodu. interrupti su timer0, timer1, PORTB i RX/TX.

dakle, jos jednom, NEMA POTREBE DA NADJES BOLJI KOD ZA OVO.

a pitanje koje imam jest - da li veca brzina rx/tx smeta brzini koda? i jos jedno pitanje. prekidac izgleda radi smetnje, nasao sam da se radi o potrebi za debounce i stavio sam ovako nesto:

if intcon.rbif=1 then 'ocitaj stanje, i provjeri treba li stati delay_ms(1) 'debounce delay od prekidaca (uzrokuje nekoliko puta pali-gasi bez toga) sys_info1=read_sysinfo set_control(sys_doit) intcon.rbif=0 'kaza datasheet da samo citanje porta brise interrupt, ali mislim da moram i ovo end if

i sad pitanje: sta taj delay_ms radi? ako sam dobro shvatio, napravit ce na TOM ISTOM MJESTU neke vrste petlju, a posto je to petlja UNUTAR interrupt rutine, onda je nemoguce da se desi bilo koji drugi interrupt dok se jedan obradjuje? sta ako naidje bajt na TX/RX za to vrijeme? hocu li ga izgubiti?

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

Tako izgleda krajnji program kojeg napravi compiler a kad je nesta stvarno kriticno sta se tice brzine, onda taj dio moras napraviri u assembleru. Ali koliko sam pogledao ovo sta si paste-ao, ne vidim da bi tu ista bilo vremenski kriticno.

Cini se da pauzu uzrokuje nesta drugo a ne sporost koda, dio za kojeg si napisao da pretpostavljas da je spor traje zamenamrivo vremena. Kolika je frekvencija clock-a? Iz komentara u liniji 25 ispada da je

0.5 MHz?? Izracun prema tom komentaru daje vrijednost 63036 a u TMR0 se u zakomentiranom dijelu koda upisuje 0xcf2c (53036) - za 1000 manje. Tvoj kod u TMR0 upisuje 195 a u komentaru pise 225 = 1000, na sta se to odnosi? Sta je bps - da li je to brzina komunikacije (bits per second)?

Znaci imas jednu interrupt rutinu koja se poziva svaki put kad nastupi bilo koji interrupt a unutar nje s IF testiras flagove da bi odredio koji je tocno nastupio? TMR0 ti sluzi za kontrolu brzine step motora, na PORTB si izgleda spojio gumb i ukljucio interrupt na promjenu brida, RX/TX interrupt ti sluzi za RS232 komunikaciju, a za sta koristis TMR1?

Kako su tocno konfigurirani interrupti? Da li koristis high i low priority vectore (setiran IPEN) ili samo jedan interrupt vector (default)? Mislim da bi tu mogo biti uzrok problema.

I to doslovno nema jer taj dio koji te zabrinjava trosi samo par desetaka T stanja.

Svaki prekidac kod ukljucivanja i iskljucivanja generira cijeli niz impulsa:

formatting link

pa ako ga spojis tako da promjena generira interrupt, i kod pritiska i kod pustanja gumba ce se generirati na desetke ili cak stotine interrupt-a. Za sta tocno koristis gumb? Da li ti treba samo detektiranje pritiska ili i pritiska i pustanja gumba? Postoje razni nacini eliminiranja problema koji nastaju zbog debounce-a. Jedan od jednostavnijih je da kod detektiranja promjene stanja odredjeno vrijeme pocekas (1 ms nije dosta), pa onda ponovo ocitas stanje i vidis da li je jos uvijek isto. Pauza izmedju ocitavanja mora biti veca od maximalnog trajanja debounce-a a koje ovisi o vise parametara (najvise o vrsti prekidaca). Ili mozes periodicki ocitavati stanje na ulaznom pinu na kojeg je spojena tipka, pa ako je zadnjih n puta ocitana ista vrijednost, prihvatiti ju kao stacionarnu.

Tipka se obicno ne spaja tako da bi generirala interrupt (osim ako je debounce rijesen hardware-ski), ali ako je vec tako spojena onda moras moci razlikovati da li je interrupt nastao zbog debounce-a ili je tipka ponovo stisnuta nakon sta je bila pustena (ili pustena nakon sta je bila stisnuta), a to moze biti problem.

Mislim da je to zbog resetiranja RBIF. Datasheet kaze:

'A mismatch condition will continue to set this bit. Reading PORTB and waiting 1 TCY will end the mismatch condition and allow the bit to be cleared.'.

Vjerojatno bi odmah iza te naredbe trebala biti naredba intcon.rbif=0 a debounce bi trebalo rijesiti drukcije. Ali za to treba podatak o tome kakva je funkcija gumba.

Ovisi kako je sve skupa konfigurirano. Moze se desiti vise interrupt-a istovremeno i o tebi ovisi sta ce se desiti. U jednom uredjaju (istina to sam za razliku od programa na screenshot-evima radio na Atmelu, ali je princip isti) mi je trebao podatak o trenutku pritiska na tipku koju sam spojio na pin na kojem je bio ukljucen interrupt na padajuci brid. Timer mi je generirao interrupte svakih 1/1000 s i to je bila vremenska baza. U interrupt-u od tipke sam odmah iskljucio daljnje interrupt-e na padajuci brid (da se ne generiraju zbog debounce-a) i setirao flag koji je u interrupt-u od timer-a signalizirao da se zapamti trenutno vrijeme i da se pokrene odbrojavanje od (cini mi se) 20 ms. Ako je nakon isteka tog vremena na ulazu i dalje bio low, onda sam ranije memorirano vrijeme prihvatio kao vrijeme pritiska na tipku i ponovo ukljucio interrupt na padajuci brid. Ako pak je nakon isteka tih 20 ms, na ulazu bio high, onda je to znacilo da se je interrupt na padajucem bridu generirao zbog debounce-a kod otpustanja tipke ili zbog neke smetnje, i taj sam pritisak zanemario. Ali to je bila specificna situacija gdje mi je gumb generirao interrupt samo zato da bi se uz obavljanje jos par stvari moglo odrediti tocno vrijeme pritiska (kasnije je umjesto gumba doso Hall senzor).

Ovisi kako je program napisan. Moguce je da interrupt s vecim prioritetom prekine interrupt nizeg prioriteta i da se za vrijeme dok se izvrsava njegova ISR propusti jedan ili vise novih interrupt-a nizeg prioriteta ali to bi znacilo da je program lose napisan. Ali ako nisi koristio high/low priority vectore, onda slijedeci interrupt nece prekinuti ISR rutinu prethodnog nego ce se slijedeci izvrsiti tek nakon izlaska iz ISR-a koji se izvrsava trenutno - i u slucaju lose napisanog programa bi se isto moglo desiti da se propusti jedan ili vise interrupta nizeg prioriteta.

Ali ako mikrokotroleru saljes komandu preko RS232, onda slijedecu ne bi trebao slati prije nego mikrokontroler javi da je ovu izvrsio. Osim toga, ako bi se i propustio koji TMR0 interrupt, motor bi opet stigo u krajnju poziciju, samo kretaje ne bi bilo ravnomjerno.

Stavi cijepi program pa cemo vidjeti otkud pauza koju spominjes. Kako se taj zastoj tocno manifestira - da li se motor krece ravnomjerno ili zastajkuje?

--
Chupo
Reply to
Chupo

Ovdje je 'nizeg prioriteta' visak jer je to slucaj kad se interrupt rutine izvrsavaju kako koja naidje i niti jedna ne moze prekinuti onu koja se vec izvrsava.

--
Chupo
Reply to
Chupo

ok, moze biti.

posto je program jos u izradi, dio koda je zakomentiran radi "vracanja ako treba" ili zbog promjene 16F/18F serije u hodu frekvencija stepera je ili 500 ili 1000 pps, ovisi sta odlucim zao mi je zbog zakomentiranih dijelova koda koje nisam izbrisao i stvorio pomutnju interrupti su low, nisam siguran niti da li ovaj pic ima jace i slabije interrupte

switch nije za krajnjeg korisnika, nego je ocitanje krajnjih mrtvih tocaka kretanja kolica po vodilici. gugl kaze da je 20ms preporuceno, ali onda mi predugo ostaje u interruptu. znaci, mala je vjerojatnost da se "pritisne pa otpusti", pritisnut ce se i ostati tako koju minutu.

The user, in the Interrupt Service Routine, clears the interrupt by: a) Any read or write of PORTB. This will end the mismatch condition. b) Clear the flag bit RBIF. A mismatch condition will continue to set flag bit RBIF. Reading or writing PORTB will end the mismatch condition and allow flag bit RBIF to be cleared.

ovo kaze da se port MORA procitati inace ostaje rbif upaljen, ali sam ja bio shvatio da ce to i ponisiti rbif, ali izgleda da rbif ostaje (?) upaljen dok ga se ne ugasi.

a sta cu onda s njima? moram ih spojiti na interrupt da znam kad sam dosao do kraja ili cu morati imati petlju koja svakih 100ms cekira stanje, pa cak i tada necu imati nista rijeseno, jer cu isto moci imati situaciju u kojoj na

99ms tipka bude stisnuta, i imat cu podatak koji nije debouncean? jednostavno ne vidim kako ako ne preko interrupta.

negdje mi je u glavi da za proc bez low/high interrupta "kada se desi interrupt, neki register je high, i dok je registar, drugi interrupt ne moze doci dok se ovaj ne clear-a" negdje nekad sam to procitao. mozda to ne stoji, stvarno ne znam. ono sto jos ne znam jest - da li ima neki stack interrupta? da li ih gomila negdje, pa onda kad kazem recimo RBIF=0, i onda on izadje iz interrupt rutine, da uzme iz stacka slijedeci? ako to tako radi, onda nemam problema sa propustanjem TMR0 ili sl, nego ce samo kasniti par desetaka cpu taktova, ali ce stici

uff... malo me je sram koliko si se potrudio! :) ako te bude zanimalo, poslat cu ti cijeli program na mail, ali jedino ako si bas znatizeljan, inace si mi dao dovoljno informacija :)

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

In article , nn says...

Mozda ce bas ti komentari dovesti do otkrivanja greske. U kojem mode-u ti radi TMR0, u 8 ili 16 bitnom? U zakomentiranom dijelu je ocito bio predvidjen za rad u 16 bitnom mode-u a ako si ga tako ostavio i kao pocetnu vrijednost upisao 195, on ce se vrtiti do 65535 a ne do 255 a to traje 65340 taktova. Nisi napisao kolika je frekvencija clocka mikrokontrolera. Da li koristis interni oscilator ili vanjski kristal/rezonator? Da li si ispravno podesio izvor clock-a i prescaler za TMR0? Izvor moze biti interni clock ili vanjski signal. Kazes da je glavni problem sporost - da li to znaci da sve radi kako treba samo je vremenski razmak izmadju koraka motora prevelik?

Da, izgleda da ima interrupt samo na promjenu stanja.

Ta se pauza ne ubacuje unutar interrupt rutine nego bi se to napravilo onako kako sam opisao u prethodnom mail-u (primjer s detektiranjem trenutka promjene stanja na jednom od ulaza).

Za to ti onda nije potreban interrupt nego samo nakon svakog koraka provjeri ulaz s prekidaca/senzora i ako detektiras krajnju tocku upali neki flag kojeg ona mozes koristiti u cijelom programu. Trebalo bi i sloziti da se flag upali tek nakon sta low na ulazu s prekidaca/senzora malo potraje - tako da si siguran da ce se isfiltrirati eventualne vrlo kratkotrajne promjene stanja zbog smetnji ili situacije kada signal sa senzora oslicira (mozda treba jos samo jedan korak pa da postane stabilan). Ali za pocetak mozes u svrhu zaustavljanja kolica mozes zanemariti da ce se stanje promijeniti zbog neke smetnje i mozes ih zaustaviti cim detektiras prvu promjenu u kombinaciji s LOW. To ce biti znak da sada kolica smiju krenuti jedino u suprotnom smjeru ali ce problem biti kada ona i krenu - jer ce se zbog debounce-a kod iskljucivanja prekidaca/senzora generirati puno impulsa tako da bi kolica stala cim bi krenula. Zbog toga treba napraviti debounce i kada se detektira krajnji polozaj i nakon sta kolica krenu u suprotnom smjeru, najprije treba biti siguran da se se sklopka/senzor iskljucila (tu opet treba debounce), a tek onda ponovo cekati signal da su kolica u krajnjem polozaju (vjerojatno imas 2 sklopke - po jednu za svaki krajnji polozaj - mozes ih spojiti ili na 2 razlicita pina na portu B, ili cak i na isti pin jer ces po smjeru kretanja znati da li se je aktivirala jedna ili druga).

Ne, kaze:

The interrupt-on-change can be used to wake the device from Sleep. The user, in the Interrupt Service Routine, can clear the interrupt in the following manner: a) Any read or write of PORTB (except with the MOVFF (ANY), PORTB instruction). This will end the mismatch condition. b) Wait one or more instruction cycles. c) Clear flag bit, RBIF.

A mismatch condition will continue to set flag bit, RBIF. Reading PORTB will end the mismatch condition and allow flag bit, RBIF, to be cleared.

formatting link
(strana 101)

A prije toga je i objasnjeno:

'The pins are compared withthe old value latched on the last read of PORTB. The "mismatch" outputs of RB7:RB4 are ORed together togenerate the RB Port Change Interrupt with Flag bit'.

Znaci, cijelo vrijeme se trenutne vrijednosti z ulaza na portu B koji mogu uzrokovati interrupt usporedjuju s vrijednostima procitanim u proslom prolazu i na taj se nacin dobiju 4 bita (svaki od njih oznacava da li je bilo ili nije bilo promjene na propadajucem ulazu (RB7:Rb4) pa se s operacijom ILI izmedju tih bitova generira interrupt flag (ako se je promijenio jedan ili vise ulaza, setirati ce se interrupt on change flag).

Interrupt on change flag se znaci setira kada se detektira 'mismatch condition' - kada se trenutno stanje na ulazima razlikuje od prethodnog. Ako samo obrises flag dok 'mismatch condition' jos uvijek traje, to ce uzrokovati njegovo ponovno setiranje pa bi rezultat bio kao da ga nisi obrisao. Zato treba procitati PORTB (to ce resetirati interne signale koji preko ILI generiraju interrupt flag, port B se ne smije procitati s instrukcijom 'MOVF (nesta), PORTB' ali za to ce se valjda pobrinuti compiler - taj bi ti podatak trebao ako bi radio u assembleru.), pocekati najmanje jedan takt, i tek onda obrisati interrupt flag. Tako sam ja shvatio datasheet.

Ja bi napravio tocno kao sta sam opisao u proslom postu - u interrupt-u bi nakon detektiranja LOW zabranio daljnje interrupte kod promjene stanja, setirao neki flag koji bi interrupt rutini za timer overflow signalizirao da je detektirana promjena, ta bi rutina onda ili smanjivala neki counter pa nakon odbrojavanja ponovo provjerila da li je na ulazu jos uvijek LOW, ili bi se neko vrijeme (odredjeni broj puta) stalno provjeravalo ulazno stanje i gledalo da li je zadnjih n ocitanja bilo isto. Tu bi onda imao 2 parametra (broj uzastopnih kontroliranja stanja na ulazu i n) s kojima bi mogo nastimati da sve radi kako treba, a ti bi se parametri - ako bi bilo potrebno - mogli dinamicki mijenjati (ovisiti o brzini kolica/frekvenciji koraka itd.).

Nema stack-a za interrupt flag-ove. Ako se za vrijeme dok se izvrsava jedna interrupt rutina, flag za neki drugi interrupt setira par puta, nakon izlaska iz prve rutine ces samo moci znati da je generiran i drugi interrupt ali neces moci znati da li ih je bilo vise. Program mora biti napisan tako da se (ako bi to uzrokovalo pogresan rad uredjaja) takva situacija ne moze desiti. U ovom slucaju se za vrijeme dok se izvrsava interrupt rutina od TMR0 moze desiti da se zbog debounce-a za to vrijeme pojavi vise impulsa s senzora/prekidaca ali to nije problem i zato ti treba debounce. Teoretski bi bilo moguce cak i da LOW na prekidacu generira interrupt, a da se vec do trenutka dok se pocne izvrsavati interrupt rutina i dok ti detektiras koji je njegov izvor, pa dok procitas stanje - to staje vec promijeni, zato nakon 'on change' interrupt-a ne mozes imati samo jedno ocitanje nego moras napraviti nesta od gore navedenog ili izmisliti mozda i bolji nacin.

S par elemenata mozes napraviti i hardware-ski debounce (mozda bi bio dovoljan samo jedan kondenzator) pa onda vise o njemu ne bi morao voditi racuna u programu, ali s obzirom da se s programom to moze napraviti vrlo jednostavno, a mikrokontroler kojeg koristis za sve ovo skupa nije iskoristen valjda niti 5%, nema razloga da dodajes nove vanjske elemente. Sve sta si opisao se s tim mikrokontrolerom najvjerojatnije moze napraviti tako da on preko 90% vremena bude u sleep-u!!

Ma kakav sram :-) Nema razloga. I meni su te stvari zanimljive i to mi dodje ko razbibriga. Osim toga, dugo nisam koristio nijedan PIC nego vecinom Atmele pa mi dobro dodje da se malo podsjetim na njihovu arhitekturu.

Dovoljno je da, kad sve skupa proradi, javis da je proradilo. Ako ce te jos sta zanimati, pitaj.

--
Chupo
Reply to
Chupo

glavni problem je da mi na PC-u stuca stream podataka kad dolazi. odnosno, kad stavim progress bar, vidim da nije glatko popunjavanje. problem je ili neki buffer u komunikaciji, ILI ono cega se bojim - sporost u interrupt petlji

nema stacka, ali ces moci znati da je bio generiran RAZLICIT interrupt? znaci, moguce je da dok sam u interrupt rutini, i cekiram RBIF, da se desi bilo koji drugi PIR i da izlaskom iz interrupt rutine, koja istovremeno moze obradjivati samo jedan, odmah opet ponovo ulazi u nju sa drugim interruptom? znaci, kad dok obradjujem TMR0 a stigao je i RCIF, interrupt ce ponovo uci? znaci, znati ostali interrupti ce biti "upamceni" da su se u medjuvremenu desili?

pa mozda da napravim to? gledao sam vec prije neke sheme, ali nisam htio petljati po plocici, a nekako mislim ni da necu... kako bi ona izgledala sa samo jednim kondom? gledao sam neke sheme i ispada da mi treba 1 kond, 1 otpornik i 1 dioda. (ovaj gore na slici je valjda pull up otpornik koji se ionako nalazi u procu?)

formatting link

eh, tesko... mislim da je opterecen 95% vrti se timer0, timer1, TX/RX, RBIF, PWM1, PWM2, (koji vjerojatno koriste timer2) i nesto te matematike za inkrementaciju

i ne znam koji od njih najvise gusi...

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

Koje podatke i u kojem trenutku mikrokotroler salje kompjuteru? Opet nisi napisao koja je frekvencija clock-a mikrokontrolera i da li koristis interni oscilator ili vanjski kristal/rezonator/RC, ...

U registru/registrima su interrupt flag-ovi i kada je ispunjen uvjet za neki interrupt, samo se setira odredjeni flag. Znaci, ako je generiran interrupt zbog timer overflow-a i program se nalazi unutar interrupt rutine a za to vrijeme nastupi jedan ili vise interrupt-a zbog promjene stanja na portu B, hardware ce setirati flag koji oznacava da je ispunjen uvjet za generiranje interrupt-on-change interrupta i nakon sta se izadje iz rutine za obradu trenutnog interrupt-a ce se generirati novi interrupt. Interrupt flagovi se setiraju neovisno od tijeka programa jer to radi hardware tako da se interrupt nece propustiti, osim ako ih se ne generira vise istih za vrijeme dok se izvrsava rutina od prethodnog.

To, naravno, vrijedi samo ako ne koristis interrupt priority mode.

Ja ne bi stavljao nove elemente nego bi sve napravio software-ski, ali svejedno je koju ces metodu odabrati ako radi.

To je primitivna metoda koja bi *mozda* funkcionirala.

Ovo prije Vout je Schmitt-ov okidni sklop a ne ulaz u mikrokontroler.

Ne!! :-) Timeri i interrupt-i rade neovisno od programa i ne trose processorsko vrijeme. Vrijeme ti trose samo glavni program i interrupt rutine koje bi trebale biti vrlo kratke. U mojem uredjaju s ATmega8 koji radi na 1 MHz koristim interrupte na padajuci brid i na timer overflow, preko SPI sabirnice update-am ekran od Nokie 3310 (za update cijelog ekrana treba poslati 504 byte-a), racunam s 64 bitnim brojevima, skeniram tipke, generiranu grafiku u RAM-u s XOR crtam preko postojece slike pa ju tek onda saljem u ekran itd. a mikrokontroler je prakticki cijelo vrijeme u sleep-u, glavni program mi izgleda ovako:

for (;;) { // beskonacna petlja // u interrupt-u ce se, kad bude trebalo, ukljuciti update_screen sleep_mode(); // iskljuci se i cekaj interrupt if (update_screen) { display_data(); update_screen = 0; // iskljuci update ekrana } // if (update_screen) } // for (;;)

Beskonacna petlja unutar koje processor ode u sleep i ceka interrupte, u jednom od interrupt-a se po potrebi setira flag update_screen koji je globalna variabla (mogo sam koristiti i samo jedan bit pa u jednom byte-u imati vise flagova), ako nakon izlaska iz interrupt rutine ne treba update-ati ekran, mikrokontroler ponovo ide u sleep i ceka novi interrupt. Interrupti na ATmega8 imaju svaki svoju rutinu pa unutar njih ne treba provjeravati koji je bio uzrok a slozio sam da rutine medjusobno komuniciraju s flagovima/porukama.

Nisam detaljno analizirao timing-e ali bi, ako bi trebalo, na taj nacin mogo ubaciti jos na desetke interrupt rutina slicnog vremenskog trajanja, a bez da bi se javili bilo kakvi problemi zbog brzine izvrsavanja programa. S obzirom da ovo sta radi tvoj program zahtijeva vise nego 100 puta manje vremena nego ovo sta sam opisao, a mikrokontroler kojeg koristis moze izvrsavati i 12 puta vise instrukcija u sekundi nego ATmega8 na 1 MHz, znaci da si nesta napravio jako pogresno.

--
Chupo
Reply to
Chupo

ah... sad sam iskljucio timer1, nisam slao nikakve podatke i ostavio samo timer0 (8-bitni) i stavio da inkrementira varijablu i salje ju na PC svake 2-3-4 sekunde se vidi ko neka jeeeedva vidljiva pauzica u data streamu, a ne znam od cega je. kada rukom drzim osovinu stepera (da se ne moze pomaknuti) i saljem mu signale, u tim trenutcima osjetim trzaj, pretpostavljam da je tada onaj "jaci moment" o kojem smo pricali jer je usporio niz signala prema njemu...

ne znam, da pokusam staviti PIC 18F na 48 MHz?

evo, poslat cu ti veselje na mail :)

--
Using Opera's mail client: http://www.opera.com/mail/
Reply to
nn

Posalji cijeli program pa cu ti naci gresku. Tesko je napamet zakljuciti gdje je greska kad neznam niti kako si program koncipirao.

Napisi kolika je frekvencija clock-a...

--
Chupo
Reply to
Chupo

Ne sjecam se da smo o tome pricali :-/

Odgovorio sam ti na mail pa pogledaj highlight-ane stvari...

--
Chupo
Reply to
Chupo

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.