![]() |
Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Printable Version +- DIY Electronic projects (https://forum.yu3ma.net) +-- Forum: Tutorijali & teorija - Tutorials & theory (https://forum.yu3ma.net/forumdisplay.php?fid=6) +--- Forum: Tutorijali - Tutorials (https://forum.yu3ma.net/forumdisplay.php?fid=27) +--- Thread: Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C (/showthread.php?tid=39) |
Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - mikikg - 02-22-2014 <p>Hvala na komplimentima ![]() <p> </p> <p>Zamolio bih samo da pišete pune oznake PIC-eva a ne skraćene.</p> <p> </p> <p>Iskusniji tačno znaju našta se misli kada se napiše npr 887 ali početnicima je to jako zbunjujuće.</p> <p> </p> <p>Dakle u pitanju je skraćena oznaka od modela PIC16F887.</p> <p> </p> <p>Predpostavljam da će mo se u ovom tutorijalu najviše vrteti oko modela iz PIC16F i PIC18F serije i iz tog razloga da nebi bilo zabune valja pisati pune oznake.</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-23-2014 <p>Da pomognem malo Mikiju sa nekim korisnim detaljima.</p> <p> </p> <p>Možda bi za početnike bilo dobro da krenu odmah od PIC18F modela...</p> <p> </p> <p>Nema arbitracije sa memorijskim bankama (linearno adresiranje), PLL za >=40MHz oscilatora.</p> <p> </p> <p>Sve je isto kao kod starog PIC16F877 osim brzine i prilično dosadne i ponekad nezgodne arbitracije memorijskim bankama.</p> <p> </p> <p>Jedan od najjednostavnijih, kod koga se hardver poklapa sa PIC16F877 i/p je PIC18F452 i/p.</p> <p> </p> <p>Pinovi su potpuno kompatibilni.</p> <p> </p> <p>U njega se mogu bukvalno preneti sa beznačajnim izmenama svi programi pisani za PIC16F877, za koga postoji gomila besplatnih tutorijala i primera.</p> <p> </p> <p>Ovo je samo predlog za one koji bi praćenjem nekog primera za PIC16F877 još lakše to radili sa PIC18F452 jer je mlađi i napredniji model, a kompatibilan.</p> <p> </p> <p>Oba su prilično stari modeli, ali zato jednostavni i sa dovoljno mogućnosti za vrlo ozbiljne naprave.</p> <p> </p> <p>Sa bilo kojim od njih se može napraviti PLC sa 25in/out (bez ekspandera) + tastatura + LCD + RS232 komunikacija za online upisivanje bootloaderom, čim se može upravljati prilično složena mašina.</p> <p> </p> <p>Za početak ne treba birati model sa mnogo specijalnih modula unutra, jer početniku je uvek najteže da raskrsti sa setovanjem tih modula. Za upoznavanje SFR registara je potrebno vreme.</p> <p> </p> <p>Kod PIC18F452 je dovoljno u funkciji inicijalizacije (konfiguracije) MCU samo napisati instrukciju</p> <p> </p> <p>ADCON1 = 0x07; /* adc off */</p> <p> </p> <p>i svi će pinovi postati digitalni, što je početniku i najpotrebnije.</p> <p> </p> <p>Ako to ne uradite, taj MCU je inicijalno postavljen sa uključenim A/D konvertorima na ANx pinovima, što je za početnika prerano i napraviće mu zbrku.</p> <p> </p> <p>Posle toga se lako mogu obavljati razni blink testovi i slično.</p> <p> </p> <p>Vlo mladi modeli imaju gomilu modula unutra i zahtevaju vremena i posla za njihovo pravilno setovanje.</p> <p>To vam je kao kod novijih mobilnih telefona: bezbroj mogućnosti a treba vam samo nekoliko :-).</p> <p>Lakše je zato početi od jednostavnijih.</p> <p>-------------------------------------</p> <p>Kod većine PIC kontrolera korisnički pinovi mogu biti ulazni ili izlazni, po izboru.</p> <p> </p> <p>Kada se konfigurišu kao ulazni, onda imaju vrlo visoku ulaznu impendansu, jednaku uobičajenim logičkim kolima iz CMOS serije (serija 40xx ili 45xx).</p> <p> </p> <p>Za razliku od CMOS kapija, kada se na PIC pinovi koriste kao izlazni, mogu raditi sa +-25 mA po pinu, a u datasheet-u treba pogledati koliko ih odjednom sme davati toliko struje.</p> <p> </p> <p>+25mA znači da svaki pin kao izlazni može davati potrošaču 25mA iz +5V napajanja(+Vdd), gde je drugi kraj potrošača na masi(-Vss). To je praktično aktiviranje potrošača stanjem 1 na dotičnom pinu.</p> <p> </p> <p>-25mA pak znači da isti taj pin može pokretati potrošač čiji je jedan kraj "okačen" na +5V(+Vdd), a pin ga aktivira stanjem 0, tj. "povuče ga ka masi.</p> <p> </p> <p>Ne mogu svi pinovi odjednom imati po 25mA zbog ograničenja discipacije MCU.</p> <p> </p> <p>Kod npr. PIC18F452 piše:</p> <p> </p> <p>Maximum current out of VSSpin ...........................................................................................................................300 mA<br> Maximum current into VDDpin .............................................................................................................................. 250 mA</p> <p> </p> <p>To pokazuje koliko bi pinova smelo istovremeno biti opterećeno maksimalnom strujom.</p> <p> </p> <p>Ako nam je potrebno baš dosta izlaznih pinova koji bi trebalo da daju dosta struje za svoje potrošače, onda možemo primeniti "caku" da 10 pinova koristimo sa stanjem 1 kao aktivnim snabdevanjem potrošača, i istovremeno još 11 sa invertovanom logikom, tj. sa stanjem 0 kao aktivnim snabdevanjem potrošača (povuku ih ka masi).</p> <p>Tako nećemo "overiti" na primer PIC o kome sam pisao.</p> <p> </p> <p>Takođe mnogi početnici pogreše tako što pin RA4 upotrebe kao izlaz sa aktivnim 1. Taj pin je skoro po pravilu kod većine PIC open drain, tj. ima mosfet samo ka masi. Ako se koristi kao snažniji izlaz, onda mora "povući" potrošač ka masi, ili ako je potrošač slabašan onda mora imati pull-up otpornik koji će taj potrošač snabdevati stanjem 1.</p> <p> </p> <p>Daleko je jednostavnije da se odmah naviknete da taj pin koristite uvek kao ulaz (ukoliko nužda ne zahteva drugačije).</p> <p> </p> <p>------------------------------------</p> <p>Nekorišćene pinove kod bilo kog MCU ne treba ostaviti da "lebde". Ako postoje pinovi koji lebde mogu se događati vrlo neočekivane pojave. Oni pinovi koji su konfigurisani kao ulazi, vrlo su visokoimpendansni, pa samo približavanje ruke do njih ih može pobuditi sa mrežnim brumom od 50Hz, koji potiče sa vašeg tela, a zbog blizine mrežnih provodnika pored vas, a vrlo neočekivanim rezultatima rada :-).</p> <p> </p> <p>Ne treba ostavljati lebdeće pinove čak ni kada radite sa baterijama, na stolu postavljenom na livadi, jer i tada svojim kapacitativnim punjenjem (od trenja odeće), približavanjem i udaljavanjem od PIC možete menjati stanje na lebdećim ulazima.</p> <p> </p> <p>Važno pravilo broj 1 za početnike:</p> <p>-nikada ne ostavljajte neupotrebljene pinove lebdećim!</p> <p>Ili ih konfigurišite kao izlaz (i ako vam nisu potrebni), ili im stavite pull-up ili pull-down otpornike reda nekoliko do nekoliko desetina K, ka +Vdd ili -Vss, respektivno.</p> <p> </p> <p>Pravilo broj 2 za početnike:</p> <p>-svakom korisničkom pinu, odmah do čipa, povežite serijski otpornik od bar 220R najmanje. Kada greškom konfigurišete pin kao izlaz, a na njemu je npr. taster ka masi ili ka Vdd, nećete spaliti MCU (mada se PIC baš teško spaljuju, ali ipak može :-). Taj otpornik će imati ulogu ograničenja struje na max. oko 22mA ma šta vi uradili sa tim pinom, a kada pin koristite kao ulaz ni malo neće smetati, jer je impendansa ulaza toliko visoka da taj otpornik biva "nevidljiv".</p> <p>Impendansa pina kao ulaza je >5Megaohm, tj. u najgorem temperaturnom uslovu mu je potrebno max, 1uA, što će na tom serijskom otporu od 220R izazvati pad napona (umanjenje veličine ulaznog signala) za 220uV, što je potpuno beznačajna veličina, Dakle. sa aspekta ulaza taj otpornik ne postoji, a u slučaju naše greške zaštitiće pin.</p> <p> </p> <p>Ja na primer tu stavljam od 330-680R, jer to je dovoljno za pogon većine LED ili optokaplerskih LED. Ne razmišljam da li će mi potrošač biti u kratkom spoju ili da li ću slučajno "nabosti" pin ka masi ili plusu...</p> <p> </p> <p>Eto nekih korisnih info uglavnom vezanih za hardver.</p> <p> </p> <p>Kada bude vremena dodaću još po nešto korisno.</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-23-2014 <p>Dok sam još pri koncentraciji:</p> <p> </p> <p>Konfiguracija pina kao ulaznog ili izlaznog pina je ekstremno brza pojava. To je jedna jedina instrukcija i kod PIC koji radi na primer sa 40MHz ta instrukcija traje 100nS (f_osc/4).</p> <p> </p> <p>Dakle, možemo munjeviti menjati orijentaciju pina kao ulaznog ili izlaznog, istovremeno mu menjajući impendansu iz ekstremno visoke do vrlo niske.</p> <p> </p> <p>To se na primer može veoma zgodno iskoristiti na jednostavan način kao sa sličice:</p> <p> </p> <p>[attachment=7406:pot.pdf]</p> <p> </p> <p>Kada smo npr. iskoristili sve A/D konvertore, na ovaj način možemo saznati položaj nekog potenciometra, tako što na kratko konfigurišemo pin kao izlaz, kratkim impulsom napunimo C kroz 220R, potom odmah promenimo pin kao ulaz i merimo vreme do njegovog stizanja u nisko stanje (pražnjenje C kroz pot.).</p> <p> </p> <p>To je jedan od primera.</p> <p> </p> <p>ili možemo istim pinom kontrolisati dve LED (na primer različite boje) kao sa sličice:</p> <p> </p> <p>[attachment=7407:2led.pdf]</p> <p> </p> <p>Kada je pin ulaz, neće svetleti ni jedna, kada je izlaz stanje 1 aktivira jednu led, a stanje 0 drugu.</p> <p> </p> <p>To može biti veoma korisno kod PIC sa malo pinova.</p> <p> </p> <p> </p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - npejcic - 02-23-2014 <p>Društvo, usputno vas pratim, pošto imam puno obaveza ovih dana, samo želim da pohvalim Mikijevu inicijativu i zaista lep i "skockan" tutorial. Za sada ništa nebih dodavao ni oduzimao ![]() <p>Macoline postove takođe, ako u ovom trenutku ne možete da pratite (imate nedovoljno iskustva) obavezno ih negde izdvojite, "zlata" su vredni, pa kada bude došlo vreme biće itekako korisni.</p> <p> </p> <p>Još bih samo napomenuo i ovo, rednim otpornikom ka svakom pinu smanjujete mogućnost da glič iz spoljnog okruženja "zaključa" pin, odnosno "latchup"-je isti prevelikom energijom. Većina pinova konkretno kod PIC mikrokontrolera ima klamp diode ka +Vdd i Vss, i struja koju one mogu da podnesu je reda veličine 1mA (kod starijih generacija) do čitavih 20mA kod novijih mikrokontrolera. Rednim otpornicima ukoliko se ograniči ova struja, pin mikrokontrolera postaje mogu slobodno reći neuništiv. Primer za to je da sam u nekim mojim projektima koristio 1M na pin mikrokontrolera i direktno dovodio 220V AC na taj pin. Nakon 7 godina (24h/365dana) rada taj uređaj i dalje radi kako treba ![]() <p> </p> <p>Moja opaska oko konfiguratora, ako neko želi da zaista nauči rad sa mikrokontrolerima, mora se detaljno upoznati sa njegovim registrima i periferijama, opciono asembler istog, tako da je "medveđa" usluga ići odmah na konfigurator. Njega bih pre savetovao iskusnijima, da bi ubrzali proces podešavanja....</p> <p> </p> <p>Samo napred....</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - dlalkovic - 02-23-2014 <p>Moje pitanje skoro da nema veze sa tutorijalom, ali je ipak pitanje ( to se trazi u naslovu teme ).</p> <p>U jednoj primeni potrebno je da izlazni pin ide direktno na ulazni pin ( koji prati pojavu prednje ivice sa izlaznog pina).</p> <p>Kako optimalno povezati ova 2 pina?</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Milan95 - 02-23-2014 <p>Aj i ja da dodam nesto sto mi je dosta znacilo kad sam pocinjao (sto i nije bilo tako davno) ![]() <p>1. Procitati Datasheet za kontroler kojim zelite da se pozabavite (obavezno)</p> <p>2. Ako imate mogucnosti uvek koristiti interne pull-up/down otpornike</p> <p>3. Ako kacite potrosace koji vuku struju priblizno maksimlanoj struji koju pin moze da da , uvek kada imate prilike neka pin "upija" struju jer se tako manje greje kontroler. (Znaci da se potrosac pali kada je pin na niskom logickom nivou 0V)</p> <p>4. Koristiti za pocetak kontrolere koji su u DIPxx jer su mnogo laksi za koriscenje od za kontrolere u SMD .</p> <p>5. Mozda ce vas obeshrabriti programiranje u Asembleru ali po meni je to, ako ozbiljnije hocete da se pozabavite programiranjem, neophodno znati , mada za pocetak i C ili Basic (i Pascal je veoma dobar mada se meni licno ne svidja) ce raditi posao ...</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - npejcic - 02-23-2014 <blockquote class="ipsBlockquote" data-author="Milan95" data-cid="21338" data-time="1393151196"> <div> <p>2. Ako imate mogucnosti uvek koristiti interne pull-up/down otpornike</p> </div> </blockquote> <p> </p> <p>Ne nužno bolje. Interni pull-up/down su jako slabi, ekvivalent otporniku od 100-ak k, što u "šumovitom" okruženju može biti jako problematično. Ako je primena uređaja u energetskom ambijentu, ipak koristite eksterne otpornike manjih vrednosti, moja praksa je 1k.</p> <p> </p> <blockquote class="ipsBlockquote" data-author="Milan95" data-cid="21338" data-time="1393151196"> <div> <p>5. Mozda ce vas obeshrabriti programiranje u Asembleru ali po meni je to, ako ozbiljnije hocete da se pozabavite programiranjem, neophodno znati , mada za pocetak i C ili Basic (i Pascal je veoma dobar mada se meni licno ne svidja) ce raditi posao ...</p> </div> </blockquote> <p> </p> <p>I ovo je tema o kojoj možemo konstruktivno da polemišemo ![]() <p> </p> <p>Jednom prilikom je rađena analiza optimizacije koda koju generiše čovek programer u assembleru i dobrog kompajlera koji prevodi C kod iste funkcije. Analiza je pokazala da su kompajleri (napominjem, dobri kompajleri) u mogućnosti da u 90% aplikacija pokažu superiornost u odnosu na prosečnog programera. Tako da danas nema dileme, viši programski jezici su preporuka za korišćenje.</p> <p> </p> <p>Neko moje iskustvo sa ljudima kojima sam pomagao da krenu sa mikrokontrolerima je da se od asemblera prilično obeshrabre, tako da pažljivo sa tim....</p> <p> </p> <p>P.S. Ko želi da pročita jako dobre tekstove i šta znači optimizacija koda, hardvera i pristup projektovanju mikrokontrolerskih uredjaj, obavezno štivo su članci Voje Antonića (PC Press devedesetih godina) koji je impresionirao i sam Microchip. Oni su mu poklonili gomilu razvojnih alata itd... Inače Voja Antonić je projektovao, izradio i pisao OS za računar Galaksija davne 1983. godine. Kasnije je radio sa Intel 8031, 8051 i PIC mikrokontrolerima.</p> <p>Evo njegovog najpoznatijeg uređaja sa izvornim kodom na asembleru, a uređaj je baziran na PIC16F84 mikrokontroleru ![]() <p><a data-ipb='nomediaparse' href='http://ww1.microchip.com/downloads/en/AppNotes/00689a.pdf'>http://ww1.microchip.com/downloads/en/AppNotes/00689a.pdf</a></p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - mikikg - 02-23-2014 <p>Moram i ja da dam nekoliko komentara ![]() <p> </p> <p>Možda nemam toliko iskustva sa PIC-evima kao npr npejcic ili Macola kojima je to trenutno sastavni deo profesije ali imam jako dug staž u radu sa njima, bukvalno od kad su se pojavili (da baš to iz vremena <span style="color:rgb(40,40,40);font-family:helvetica, arial, sans-serif;">Voje Antonića</span>) ![]() <p>U periodu kada sam i ja to profesionalno radio, isprojektovao sam par stotina različitih apikacija. Sad sam u nekim drugim vodama i to mi je ostao samo hobi.</p> <p> </p> <p>Ono što želim da kažem je vezano za Assembler i neke druge višlje programske jezike poput C.</p> <p> </p> <p>Razvojni alati (IDE i kompajleri) su tokom vremena veoma veoma napredovali. Ne samo sto su ti alati napredovali nego su oni posledično pratili trend koji su noviji mikrokontroleri diktirali.</p> <p><strong>Pod ovim najviše mislim na to da su sadašnja procesorksa jezgra skoro potpuno optimizovana za pisanje programa u jeziku C!</strong></p> <p>To praktično znači da je skoro isto (recimo 90% isto) po pitanju zauzeća momorije i brzine izvršavanja programa pisali program u vrlo kompleksnom Assembleru ili pisali program u C.</p> <p>Prevodilac za C jezik će u većini slučajeva za neku funkciju napraviti ekvivalento isti mašinski code kao da smo to pisali u Assembler-u i to pod predpostavkom da skoro aposlutno poznajemo tu problematiku i da znamo sve best-practice i cake kako se najoptimalnije neka tražena funkcija logički realizuje.</p> <p> </p> <p>Assembler je nekada bio must-have izbor jer su mikrokontroleri bili sa skromnim brzinama i memoriskim resursima.</p> <p>Sada kada memorija i brzina više nije toliki problem kao pre, pisanje programa u C je potpuno prihvatljivo ne samo za početnike već i za surove profesionalce.</p> <p>A i kada nam ponestane resursa, šta je problem uzeti neki bolji PIC, pa sad ih prave sa po 1-2MB flash memorije i 200+MIPS i ne znam šta da pišete to ne može da se potroši ![]() <p> </p> <p>Takođe, jezik C je sad praktično standard za sva moguća programiranja i pisanja aplikacija za razne platforme, ne samo za PIC već za gomilu drugih mikrokontrolera, PC i desktop aplikacija i sl.</p> <p>Dodatno C jezik je sad vrlo vrlo sličan nekim popularnim (WEB) jezicima poput JavaScript ili PHP pa onima koji su možda malo više u tim vodama pisanje programa u C će biti opuštencija ![]() <p>Zato sam u onom tutorijali prvenstveno se bazirao na jeziku C jer u ovom trenutku ja lično smatram da Assembler nije neophodan za poznavanje, bar ne detaljno.</p> <p> </p> <p><strong>Ono što je specifično za svaki mikrokontroler su njegovi registri za kontrolu periferija u drugih internih funkcija i to treba da se poznaje nevezano za to u kojem jeziku pišemo program.</strong></p> <p>Opet ovde dolazi u prednost moderan IDE jer nas može vrlo jednostavno "posavetovati" kada krenemo da pišemo neku naredbu, dovoljno je recimo ukucati POR i zatim pritisnuti CTRL+Space i na ekranu će izaci spisak svih raspolozivih funkcija i opcija koje počinju tim slovima (code complete, npr PORTA). To je fenomenalna opcija a sećam se kako je to nekad bilo kada su se programi pisali u običnim tekstualnim editorima, muka živa.</p> <p>To je samo jedan primer ekstra korisne funkcije a spomenuti Mplab X ih ima tonu sličnih ![]() Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-24-2014 <p>Pošto je ovo zanimljivo mesto za svakakve predloge i pomoc pocetnicima i onima koji su donekle stigli u programerskom poslu, evo jednog priloga iz realnog sveta kontrole industrijskih mašina.<br><br> Pominjao sam PIC16F877, kao model za koga postoji bezbroj aplikacija i gotovih rešenja na net-u.<br><br> Kao njegovog mladeg naslednika sa nekoliko poboljšanja PIC18F452, gde su kodovi za PIC16F877 vrlo portabilni sa beznacajnim izmenama.<br><br> I sada pominjem PIC18F4620, pin kompatibilnog, sasvim slicnog sa prethodna dva, osim što ima neuporedivo veci kapacitet svih memorija (fleš,ram,eeprom) i par dodatnih modula.<br><br> Takode se u njega mogu portovati kodovi za 877 i 452, a da bi svi korisnicki pinovi bili digitalni (pomoc pocetnicima) u inicijalizaciji treba iskljuciti A/D konvertore i oba komparatora.<br><br> Ovako:<br><br> ADCON1 = 0b00001111; /* adc off */ //4620<br> CMCON = 0b00000111; /* comparators off */ //4620<br><br> Prica o ovim osmobitnim MCU je ovde da bi pocetnicima pokazala da nema potrebe bez razloga se odmah na pocetku hvatati za MCU sa preteranim resursima unutra.<br><br> Sa bilo kojim od tri prethodno nabrojana MCU, mogu se napraviti stvarno mocni PLC.<br><br> Primera radi, najsnažniji PLC koji sam napravio sa jednim ortakom, sa PIC16F877 ima 128 in/out, gde je napravljeno nekoliko in/out expandera sa Altera PLD.<br><br> Jedan malo manji od tog, takode sa PIC16F877, sa 80 in/out, upravlja jednu mašinu za brizganje plastike, kapaciteta 2Kg plastike i 800 Tona sile zatvaranja alata, u Ugrinovcima, blizu našeg forumaša HMAP.<br><br> Mašina je istocno nemacko-ruska, sa 39 hidraulicnih ventila i 40 senzora.<br><br> Ogromne špulne na ventilima (ruska posla) 24V 4,5A svaki.<br><br> U nekim fazama procesa, kroz moj PLC prolazi preko 70A struje pri 24V!!! Tim se može komotno zavarivati nešto...<br><br> No, uz malo pažnje pri rutovanju vodova, brižljivo izvedenog hardvera, sve to super funkcioniše godinama. Mrzim releje i nikada ih ne stavljam u neku mašinu, pa sve te ventilčine pokrecem low-Rds mosfetima.<br><br> ---------------------------------------------------------------<br><br> Evo jednog primera sa PIC18F452, gde se istim MCU upravljaju tri mašine odjednom.<br><br> Prica je takva da je iskorišcen VIŠAK resursa na MCU PIC18f452 (da se ne baci :-) i udružene su tri mašine pod jedno upravljanje.<br><br> Elem, na početku je nasleđen jedan sučeoni aparat za termootporno zavarivanje (punktovanje), sa višestepenim prekidačem za kontrolu snage i kontaktorima za kontrolu vremena zavarivanja.<br><br> Ono što je kritično važno u oblasti termootpornog zavarivanja (punktovanja), osim poznatog materijala i komada, su tri parametra: jačina struje, vreme, i pritisak delova međusobno.<br><br> Da bi zavar bio perfektno ponovljiv, neophodno je da ova tri parametra budu perfektno ponovljivi.<br><br> Naravno, odmah sam izbacio kontaktore, i trafou od 15KVA napravio tiristorsku kontrolu snage, faznim zasekom pomocu ultra pouzdanog TCA785. Kontrolu vremena sam izveo plasiranjem celobrojnih iznosa mrežnih perioda radi sprečavanja DC bias trafoa, ujedno precizne vremenske kontrole. Kontrolu pritiska pneumatskim cilindrima, sa preciznim regulatorom pritiska ispred...<br><br> Ono što je trebalo da se proizvodi, gde bi taj aparat bio jedan u lancu operacija, je neki žicani okvir, koji je prethodno trebalo saviti poluautomatom za savijanje žice, potom suceono zapunktovati, pa onda zapunktovati ga u više tacaka za konacni proizvod drugim punkt aparatom, nalik punkt kleštima.<br><br> Pošto tri prethodno nabrojana PIC "prirodno" obezbeduju 25 in/out, preticala je velika kolicina neupotrebljenih resursa kod kontrole samo suceonog aparata.<br><br> Naravno, odmah sam predložio da sve tri mašine koje su vezane datim procesom, stavim pod zajedničko upravljanje, i iskoristim isti trafo od sučeonog aparata za drugo punktovanje.<br><br> Tim bi sve bilo blizu i u lancu proizvodnje, istovremeno ušteđena čitava jedna punkt mašina, uz samo dodavanje još jednog pneumatskog cilindra visokostrujnih kablova i para elektroda za taj treći proces.<br><br> Predlog je prihvacen.<br><br> Pošto sve tri mašine mogu potpuno asinhrono raditi svoje poluautomatske procese, neophodno je bilo koristiti neki brzi multitasking, koji bi za korisnika izgledao kao rad u realnom vremenu.<br><br> Odmah da se ogradim:<br><br> Ja nisam školovan programer. Kada se prvi kucni racunar pojavio imao sam 16 godina i za mene je tada bio ekonomski nedostižna naprava,<br><br> Programiranje sam naucio uz put, uglavnom sam, uz povremenu pomoc jednog mog ortaka Mladena, onda Mikijevog sjajnog oca, pocivšeg Zorana Markovica (YU1ZM), i još par drugara koji su se vec bavili tim, pre otprilike 16 godina.<br><br> Tada je prilicno snažan PIC (generacija sa 16F84) bio neki PIC16F72, sa prozorcetom za brisanje pomocu UV lampe :-).<br><br> He he, tada je se stvarno moralo voditi racuna o bagovima u kodu, jer svako ponovno programiranje je koštalo 15 minuta brisanja UV lampom :-).<br><br> Tada je se pisalo u asembleru, normalno :-).<br><br> Asembler je stvarno naporan za pisanje, ali se njegovim korišcenjem dobiju par nezamenljivih koristi:<br><br> -prvo, nauci se da se u glavi drži par stotina stavki pod cvrstom konrolom,<br><br> -drugo, lako je provaliti bag koji eventualno napravi sam kompajler, posmatranjem koda kog je izgenerisao.<br><br> Da se vratim na pricu. Pocetke sam naucio od tih ljudi, posle (što je vrlo svojstveno za mene) razvijao neke sopstvene metode.<br> </p> <p>Mnogim školovanim programerima se ova moja metoda multitaskinga neće svideti, ali ona neoprostivo dobro i pouzdano radi i čitava povorka od sedam taskova se vrti sa par desetina KHz, a može i brže jer sam žrtvovao pola od tog vremena za softversko filtriranje tastera "escape".</p> <p> </p> <p>To isto pisano u asembleru je brže samo oko 15%.</p> <p> </p> <p>Dakle. uzmite u obzir da nisam školovan programer, već samouk, ali prilično efikasan.</p> <p>Takođe da zbog ranijeg pisanja u asm volim da koristim globalne varijable.</p> <p> </p> <p>Nisam imao vremena za optimizaciju koda. Sve sam napisao ad-hok, na licu mesta.</p> <p> </p> <p>Od ključne važnosti mi je bila brzina prolaska kroz sve taskove, tako da ni u kom slučaju ne propustim ni jedan input signal.</p> <p> </p> <p>MCU radi sa clk od 40MHz (HSPLL), a vreme jedne instrukcije je 100nS (f_clk/4).</p> <p> </p> <p>Samo sam sada prilegao da napišem komentare za ovu priliku, bukvalno od linije do linije, jer to je ono što je najkorisnije početnicima (a sve nas mrzi da ih pišemo, i uvek se posle par godina gorko pokajemo što smo bili lenji :-).</p> <p> </p> <p>Za stroge početnike u C jeziku, komentari su:</p> <p> </p> <p>//jednolinijski komentar, važi do kraja dotične linije</p> <p> </p> <p>/* višelinijski komentar,</p> <p> važi od znaka do znaka */</p> <p> </p> <p>Radi se samo o dve funkcije: funkcije main i funkcije automatskog rada.</p> <p>Biće dovoljno za razumevanje poente, nekima odmah, nekima kad dođe vreme...</p> <pre class="_prettyXprint"> /*-----------------------------------------------------------------------------------------------------*/ void autom_rad(void) //funkcija automatskog ili poluautomatskog rada masine { err_no=nema_err; l_err_no=nema_err; //ponisti sve greske kod ulaska lcd_clear(); //ocisti displej if(op_status==poluautom){ //ako je poluautom. rad u pitanju lcd_puts("POLUAUTOM."); //prikazi tekst } if(op_status==autom){ //ako je autom. rad u pitanju lcd_puts("AUTOMATSKI"); //prikazi tekst } if(broj_grupa>1){ //ako postoji vise grupa parametara za set razlicitih proizvoda, prikazi indeks proizvoda lcd_puts(" Pr"); //prikazi tekst lcd_goto(13); //i broj indeksa proizvoda, pocev od 13. karaktera LCD lcd_number(ofset_grupe+1,2,3,0); //varijabla, broj decimala, mesto zapete, prisustvo predznaka. } semafor_red=0; semafor_green=0; semafor_yelow=0; //pogasi trobojni semafor clr_line2(); // oslobodi liniju 2 displeja za eventualni brojac komada /* ovde, ako treba, staviti potrebne preduslove za autom/poluautom rad */ var_busy_flag=0; //!!! obavezno, da bi ponovo radila klesta i suceoni po izlasku iz greske suc_seq_no=0; kl_seq_no=0; sav_seq_no=0; TRseq_no=0; //svi taskovi u stop stanje, bitno kod povratka iz greske ped_suc_seq_no=0; ped_kl_seq_no=0; tast_sav_seq_no=0;//svi taskovi u stop stanje, bitno kod povratka iz greske /*---------------------petlja autom/poluautom rada--------------------*/ while(((op_status==poluautom)||(op_status==autom))&&(!auto_escape)){ //uslovi odrzanja while petlje //task_ticker^=1; //pin za testiranje vremena prolaza svih taskova, dok se ne zavrsi pisanje programa if(esc_test())err_no=err_ciklus; //prekinut polu/autom. rad tasterom escape, fatal err. if(not_aus)err_no=err_n_aus; //stisnut SVE-STOP, fatal err. ///////////////////////////////task pedale suceone punkt masine///////////////////////////////////////// switch(ped_suc_seq_no){ case 0: //cekamo da bude pustena pedala suceonog if(!pedala_suc)ped_suc_seq_no=0; //cekaj else ped_suc_seq_no=1; //inace udji u proveru busy i stisnute break; case 1: //cekamo da bude stisnuta ako nije busy, inace ignorisi if(!pedala_suc){ //stisnuta? if(!var_busy_flag){ //ako nije zauzeto od klesta var_busy_flag=1;semafor_red=1; //rezervisi trafo za suceoni, indikacija rada suc_seq_jump=1;suc_seq_no=1; //aktiviraj task suceonog ped_suc_seq_no=2; //idi na cekanje zavrsetka suceonog } else ped_suc_seq_no=0; //inace ignorisi pedalu, na pocetak za ponovni pokusaj } else ped_suc_seq_no=1; //inace cekaj da bude stisnuta break; case 2: //cekanje zavrsetka suceonog, ili njegove greske if((suc_seq_no==8)||(suc_seq_no==7)){ //zavrsio suceoni, ili greska suceonog? if(suc_seq_no==7)l_err_no=l_err_suceoni; //prijavi gresku suceonog, prekoracen polozaj, light err. suc_seq_jump=0;suc_seq_no=0; //deaktiviranje taska suceonog var_busy_flag=0;semafor_red=0; //oslobodi rezervaciju ped_suc_seq_no=0; //vrati se na cekanje pedale } else ped_suc_seq_no=2; //inace cekaj break; } ////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////task pedale klesta za punktovanje okvira///////////////////////////////// switch(ped_kl_seq_no){ case 0: //cekamo da bude pustena pedala klesta if(!pedala_kl)ped_kl_seq_no=0; //cekaj else ped_kl_seq_no=1; //inace udji u proveru busy i stisnute break; case 1: // cekamo da bude stisnuta, ako nije busy, inace ignorisi if(!pedala_kl){ //stisnuta? if(!var_busy_flag){ //ako nije zauzeto od suceonog var_busy_flag=1;semafor_yelow=1; //rezervisi klesta, tj. trafo kl_seq_jump=1;kl_seq_no=1; //aktiviraj task klesta ped_kl_seq_no=2; //idi na cekanje zavrsetka klesta } else ped_kl_seq_no=0; //inace ignorisi pedalu, na pocetak za ponovni pokusaj } else ped_kl_seq_no=1; //inace cekaj da bude stisnuta break; case 2: //cekanje zavrsetka klesta if((kl_seq_no==6)||(kl_seq_no==5)){ //zavrsila klesta, ili greska? if(kl_seq_no==5)l_err_no=l_err_klesta; //prijavi gresku, nedovoljan je pritisak, light err. var_busy_flag=0;semafor_yelow=0; //oslobodi rezervaciju i vrati se na cekanje pedale ped_kl_seq_no=0; //ovaj task u pocetni polozaj, stop } else ped_kl_seq_no=2; //inace cekaj break; } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////task oba tastera savijanja zice//////////////////////////////////////////// switch(tast_sav_seq_no){ case 0: //cekamo da oba tastera budu pustena if((!tast1_sav)||(!tast2_sav))tast_sav_seq_no=0;//cekaj dok ne budu pustena oba else tast_sav_seq_no=1; //inace idi na cekanje oba stisnuta break; case 1: //cekamo da oba budu stisnuta if((!tast1_sav)&&(!tast2_sav)){ //stisnuta oba? sav_seq_jump=1; sav_seq_no=1; //aktiviraj task savijanja semafor_green=1; //indikacija rada tast_sav_seq_no=2; //idi na cekanje zavrsetka savijanja } else tast_sav_seq_no=1; //inace cekaj da oba budu stisnuta break; case 2: //cekamo zavrsetak savijanja if((sav_seq_no==6)||(sav_seq_no==5)){ //task savijanja zavrsio, ili greska? if(sav_seq_no==5)l_err_no=l_err_savijanje; //prijavi gresku, istekao wdt, light err. sav_seq_no=0; //stavi task savijanja u stop stanje semafor_green=0;tast_sav_seq_no=0; //ukloni indikaciju i vrati se na pocetak } else tast_sav_seq_no=2; //inace cekaj break; } ///////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /////////////////////////////////task suceonog punkt aparata//////////////////////////////////////////// switch(suc_seq_no){ case 0: //stop, pasivno stanje blokiraj_suc=0; stegni_suc=0; break; case 1: //blokiraj komad, t_blok_suc if(suc_seq_jump){ //jednokratan prolaz CCPR1L=param[pow_suc]; //dodeli snagu power jedinici od 15KVA temp_per1=param[per_suc]; //uzmi potreban broj perioda zavarivanja iz parametara timer10ms=param[t_blok_suc]; //dodeli timeru vreme blokiranja blokiraj_suc=1; //pokreni cilindar blokiranja timeout=0; //startuj timer suc_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timeout){ //ispunjeno vreme blokiranja? suc_seq_jump=1;suc_seq_no=2; //idi na stezanje komada } } break; case 2: //stegni, t_stez_suc if(suc_seq_jump){ //jednokratan prolaz stegni_suc=1; //pokreni cilindar stezanja timer10ms=param[t_stez_suc]; //dodeli timeru vreme stezanja timeout=0; //startuj timer suc_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timeout)suc_seq_no=3; //ispunjeno vreme, idi na kontrolu mikroprekidaca polozaja } break; case 3: //proveri mikroprekidac, ako JE, zavar stop, err_suceoni, inace zavari if(!prek_suc)suc_seq_no=7; //greska, idi na poziciju greske? else{ suc_seq_jump=1; suc_seq_no=4; //sve ok. idi na zavarivanje } break; case 4: //zavari if(suc_seq_jump){ //jednokratan prolaz TR_jump=1; TRseq_no=1; //start sync taska i brojanja perioda, napajanje sa T i R faza suc_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(TRseq_no==3){ //sync TR task zavrsio? TRseq_no=0; //stavljanje TR taska u stop stanje suc_seq_jump=1; suc_seq_no=5; //idi na poststezanje-hladjenje komada } } break; case 5: //poststezanje, hladjenje komada if(suc_seq_jump){ //jednokratan prolaz CCPR1L=0; //svedi snagu zaseka na nulu, dodatna sigurnost timer10ms=param[t_hlad_suc]; //dodeli timeru vreme hladjenja timeout=0; //startuj timer suc_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timeout){ //isteklo vreme? suc_seq_jump=1;suc_seq_no=6; //ispunjeno vreme idi dalje } } break; case 6: //pusti oba cilindra if(suc_seq_jump){ //jednokratan prolaz blokiraj_suc=0; stegni_suc=0; //iskljucenje oba cilindra timer10ms=10; //vreme sigurnog odvajanja kontakta komada=100mS timeout=0; //startuj timer suc_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timeout)suc_seq_no=8; //idi na poziciju uspesnog zavrsetka } break; case 7: //pozicija greske suceonog, stopiraj zavar i pusti oba cilindra enable1=0; TRseq_no=0; blokiraj_suc=0; stegni_suc=0; break; case 8: //pasivno stanje, indikator uspesnog zavrsetka blokiraj_suc=0; stegni_suc=0; break; } /////////////////////////end task suceonog/////////////////////// ////////////////////////////////////////////////////////////////////////////////// ////////////////////////task klesta za punktovanje/////////////////////////////////////////////// switch(kl_seq_no){ case 0: //stop, pasivno stanje stegni_kl=0; //cilindar off break; case 1: //predstezanje i proveri pritisak if(kl_seq_jump){ //jednokratan prolaz stegni_kl=1; //aktiviraj cilindar CCPR1L=param[pow_kl]; //dodeli snagu power grupi pomocu pwm temp_per1=param[per_kl]; //dodeli power grupi broj perioda zavarivanja timer10ms=param[t_stez_kl]; //navij timer na vreme predstezanja klesta timeout=0; //startuj timer kl_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ if(timeout){ //inace se vrti ovde posle jednokratnog prolaza if(!v_prit_klesta)kl_seq_no=5; //greska err_p_vazd else{kl_seq_jump=1;kl_seq_no=2;} //inace zavari } } break; case 2: //zavari if(kl_seq_jump){ //jednokratan prolaz TR_jump=1;TRseq_no=1; //start sync taska i brojanja perioda, tj. start power grupe kl_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(TRseq_no==3){ //zavrsio sync task? TRseq_no=0; //stavljanje TR taska u stop stanje kl_seq_jump=1;kl_seq_no=3; //idi na poststezanje, hladjenje } } break; case 3: //poststezanje, hladjenje if(kl_seq_jump){ //jednokratan prolaz CCPR1L=0; //svedi snagu pow. grupe na nulu, dodatna sigurnost, pwm=0 timer10ms=param[t_hlad_kl]; //navij timer na vreme hladjenja timeout=0; //startuj timer kl_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timeout){ //isteklo vreme? kl_seq_jump=1;kl_seq_no=4; //idi na otpustanje cilindra } } break; case 4: //pusti cilindar if(kl_seq_jump){ //jednokratan prolaz stegni_kl=0; //deaktiviraj cilindar timer10ms=20; //sigurnosno vreme ukidanja elektricnog kontakta komada, 200mS timeout=0; //startuj timer kl_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timeout)kl_seq_no=6; //idi na piziciju uspesnog zavrsetka } break; case 5: //pozicija greske klesta stegni_kl=0; //deaktiviraj cilindar za svaki slucaj, ako sam negde zaboravio break; case 6: //indikator uspesnog zavrsetka, pasivno stanje stegni_kl=0; //deaktiviraj cilindar za svaki slucaj, ako sam negde zaboravio break; } ////////////////////////end task klesta////////////////////////// /////////////////////////////////////////////////////////////////////////////////// ////////////////////////task savijanja zice/////////////////////////// switch(sav_seq_no){ case 0: //stop, pasivno stanje spusti_spoljne=0;spoljni_cil=0;unutras_cil=0; //svi cilindri off break; case 1: //zatvori spoljne if(sav_seq_jump){ //jednokratan prolaz spoljni_cil=1; //aktiviraj prvu fazu savijanja timer_sav=0; //startuj timer kao WDT sav_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timer_sav>(param[wdt_sav]*10))sav_seq_no=5; //wdt, rezol. 100mS, na pozic.err if(spoljni_su_in){ //prvo savijanje zavrseno? sav_seq_jump=1;sav_seq_no=2; //idi na sledecu fazu savijanja } } break; case 2: //otvori spoljne i spusti ih dole if(sav_seq_jump){ //jednokratan prolaz spoljni_cil=0;spusti_spoljne=1; //aktiviraj potrebna stanja cilindara timer_sav=0; //startuj timer sav_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timer_sav>50){ //fiksno vreme 500mS sav_seq_jump=1;sav_seq_no=3; //idi na drugu fazu procesa } } break; case 3: //zatvori unutrasnje if(sav_seq_jump){ //jednokratan prolaz unutras_cil=1; //aktiviraj unutrasnje timer_sav=0; //startuj timer kao WDT sav_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ if(timer_sav>(param[wdt_sav]*10))sav_seq_no=5; //wdt, rezol. 100mS, na pozic.err if(unutr_su_in){ //drugo savijanje zavrseno? sav_seq_jump=1;sav_seq_no=4; //idi na pripremu za nov komad } } break; case 4: //otvori unutrasnje i digni spoljne if(sav_seq_jump){ //jednokratan prolaz spusti_spoljne=0;spoljni_cil=0;unutras_cil=0; //aktiviraj povratak u pocetne pozicije timer_sav=0; //startuj timer sav_seq_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(timer_sav>100)sav_seq_no=6; //isteklo vreme povratka (1000mS), idi na indikator zavrsetka } break; //pozicija greske case 5: spusti_spoljne=0;spoljni_cil=0;unutras_cil=0; //off za svaki slucaj break; case 6: //indikator uspesnog zavrsetka spusti_spoljne=0;spoljni_cil=0;unutras_cil=0; //off za svaki slucaj break; } ///////////////////////end task savijanja//////////////////////// ///////////////////////TR sinhro i brojac perioda task, scr kontroler je TCA785//////////////////////////// switch(TRseq_no){ case 0: // stop, pasivno stanje power grupe enable1=0; break; case 1: //cekamo prvi TR polutalas if(TRsync){ //pozitivna tranzicija TR_jump=1; TRseq_no=2; } break; case 2: //drugi TR polutalas, siguran prolaz kroz nulu if(TR_jump){ //jednokratan prolaz if(temp_per1>0)temp_per1--; //ako ima jos nepotrosenih perioda, umanji za jednu enable1=1; //odobri power grupu 15KVA, sada i ubuduce TR_jump=0; //spreci ponavljanje jednokratnog prolaza } else{ //inace se vrti ovde posle jednokratnog prolaza if(!TRsync){ //negativna tranzicija if(temp_per1<1){ //potrosene sve periode? TR_jump=0; TRseq_no=3; //idi na zavrsetak } else TRseq_no=1; //inace radi dok ne potrosis periode } } break; case 3: //indikator zavrsetka 1.power grupe, pasivno stanje enable1=0; //zabrana SCR power grupe break; } /////////////////////end TR sinhro////////////////////////////////////// if(l_err_no)disp_l_err(l_err_no); //obrada lajt gresaka, bez zaustavljanja druge dve masine if(err_no){ //ka obradi fatalnih gresaka, opsti stop, izlaz iz polu/autom. iskljuci_izlaze(); //iskljuci sve izlaze auto_escape=1; //pripremi break while petlje memo_brojac(pisi); //zapamti brojac, ako je u upotrebi op_status=bazni; //ponisti status autom. } if(auto_escape)break; //prekini while } ////////////////////////////////end while autom. rada ////////////////////////////////// /*-------------------------------------------------------------------*/ } //////////////////////////////////end autom. funkcije//////////////////////////// /*-------------------------------------------------*/ void main(void) { ///////////////////////////// processor_init(); //inicijalizacija (konfig) MCU lcd_init(); //inicijalizacija LCD semafor_red=1; //test alarm lampe i butovanja MCU animate(message[0]); //reklamna animacija skrolujucim tekstom lcd_goto(line2); //idi na liniju 2 LCD lcd_puts(message[1]); //ime masine delay_ms(1500); //vreme prikaza lcd_clear(); //ocisti LCD lcd_puts(message[2]); //ime firme lcd_goto(line2); delay_ms(3000); //vreme do kraja reklamne poruke //ocisti_ee(); /* obavezno uraditi kod prvog upisivanja programa */ get_group(); //dohvati parametre iz eeprom delay_ms(10); memo_brojac(citaj); //preuzmi stanje brojaca iz eeprom // if(opt_p&&(n<2))opcija_p(); //opcija plati gazda! Za one koji su sumnjivi oko placanja delay_ms(10); TMR0ON=1; /* Ukljucen timer0 */ //TMR1ON=1; /* ukljucen timer1 */ lcd_clear(); //ocisti LCD disp_base(); //prikazuj set baznih poruka semafor_red=0; //iskljuci alarmnu lampu CCPR1L=0; //pwm1=0 //////////////////////////////// while(1){ //radi kb_sc_execute(); //sken i izvrsenje tastature, test rad i rucni rad if((op_status==poluautom)||(op_status==autom))autom_rad(); //poluautomatski i automatski rad }//end main while(1) } //end main ///////////////////////////////////////////END programa//////////////////////////////// //line1297 ////////////////////////////////////////////////////////////////////////////// </pre> <p>Iskusnijima će možda ovo nešto i koristiti, možda i ne, ali početnicima će sigurno razjasniti mogućnosti upravljanja pomoću prilično "siromašnog" 8 bit MCU i neke od načina za realizaciju.</p> <p> </p> <p>Početnici će to sve "pohvatati" iz komentara (a razbio sam se pišući ih samo za vas :-).</p> <p>Kasnije će im biti jasnije (zanimljiv stih).</p> <p> </p> <p>Pozz</p> <p> </p> <p>P.S.</p> <p> </p> <p>Zaboravih da napomenem: iz hardverskih razloga za inpute koristim negativnu logiku, tj. if(!inputx) je pitanje tipa da li JESTE.</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-24-2014 <p>Prethodni primer pokazuje da 8 bit MCU nisu uopšte naivni kako se misli, i sve dok se ne zahteva žešća i brza matematika, sa ciframa koje nisu celobrojne i veće od dva bajta, 8 bit MCU su stvarno potpuno dovoljni za prilično ozbiljne naprave.</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-24-2014 <p>Nekom sledećom prilikom, kad dobijem vremena, objasniću jednu moju jednostavnu metodu za brzu hardversku konfiguraciju PLC sa MCU, gde se izbor "in" ili "out" izvodi samo prevrtanjem optokaplera na istoj pcb i stavljanjem potrebnih elemenata ka spoljašnjoj sredini. (otuda potiče korišćenje negativne logike za inpute)</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-24-2014 <p>Što možeš noćas, ne ostavljaj za sutra...</p> <p> </p> <p> [attachment=7426:in_out_config.pdf]</p> <p> </p> <p>Uz malo mašte možete sebi predočiti kako uraditi ostatak ka spoljašnjoj sredini:</p> <p> </p> <p>Mosfet, BJT, SCR, PNP input, NPN input, AC input, itd itd...</p> <p> </p> <p>Uz malo jumpera i pametne pcb to nije teško.</p> <p> </p> <p> </p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-24-2014 <blockquote class="ipsBlockquote" data-author="dlalkovic" data-cid="21336" data-time="1393149973"> <div> <p>Moje pitanje skoro da nema veze sa tutorijalom, ali je ipak pitanje ( to se trazi u naslovu teme ).</p> <p>U jednoj primeni potrebno je da izlazni pin ide direktno na ulazni pin ( koji prati pojavu prednje ivice sa izlaznog pina).</p> <p>Kako optimalno povezati ova 2 pina?</p> </div> </blockquote> <p>Pitanje je zašto povezivati ulazni pin na izlazni?</p> <p> </p> <p>Stanje izlaznog pina se može direktno saznati iz "LAT" registra.</p> <p> </p> <p>Dakle, na primer u C:</p> <pre class="_prettyXprint"> If(output_pinX) uradi_nesto; // tako saznajes stanje, sa kasnjenjem od par stotina nS, sa 40MHz //------------------------------------------------------------------------------ /* ako ti treba cekanje same tranzicije tog pina, i ako se ne bavis ni sa cim drugim u tom trenutku (MCU, ne ti :-) onda ovako: */ while(output_pinX); //cekamo da prestane prethodno pozitivno stanje while(!output_pinX); //dogodila se silazna tranzicija uradi_nesto; // dogodila se opet uzlazna tranzicija // ili while(!output_pinX); //cekamo da prestane prethodno negativno stanje while(output_pinX); //dogodila se uzlazna tranzicija uradi_nesto; // dogodila se opet silazna tranzicija //-------------------------------------------------------------------------------- /* ako jos nesto obavljas u isto vreme (naravno opet MCU), onda ovako: */ unsigned char seq; while(uslov){ //ovakva while "zuji" u krug sa par MHz, zavisno od kolicine toga u njoj. radi_nesto_drugo_u_medjuvremenu; //sa korisnickog aspekta paralellni dogadjaj switch(seq){ case 0: if(!output_pinX)seq=1; //skoci u case 1 kada se dogodi silazak u nisko stanje else seq=0; //inace cekaj break; case 1: if(output_pinX)seq=2; //skoci u case 1 kada se dogodi uzlazna tranzicija else seq=1; //inace cekaj break; case 2: uradi_nesto; // uradi nesto na svaku uzlaznu tranziciju seq=0; // vrati se na cekanje silazne break; } radi_nesto_trece_u_medjuvremenu; //sa korisnickog aspekta paralellni dogadjaj radi_nesto_N_u_medjuvremenu; //sa korisnickog aspekta paralellni dogadjaj if(neki_uslov)break; //raskini while po potrebi } </pre> <p>Kačenjem input pina na output pin, gubiš jedan pin bez potrebe, a ništa ne dobijaš na vremenu.</p> <p> </p> <p>Ali ako već želiš tako, onda input pin zakači na output pin kroz min. 220R.</p> <p>Ako slučajno oba postaviš kao output, to će spasti MCU.</p> <p> </p> <p>Pozz</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - mikikg - 02-24-2014 <p>Jos jedan koristan komentar a koji je vezan sa slobodne nožice.</p> <p> </p> <p>Po ovim tekstovima se uviđa da se vrlo "sitničari" za slobodne nožice, jedna nožica više-manje, što baš toliko pravimo pitanja oko toga ![]() <p>Kada budete krenuli sa korišćenjem ovih PIC mikrokontrolera videćete da je svaka slobodna nožica zlata vredna ![]() <p> </p> <p>Ovde se meša jedna nezgodna stvar a to je kada tamo vidite u specifikaciji da određeni PIC ima brdo nekih modula, I2C, USART, A/D i slično, kada se premota malo dalje specifikacija videćete tablicu gde je prikazano koji pin može da ima koje funkcije i tu iskače čest problem recimo da I2C port deli nožice sa USART (RS232) portom a kao za inat vam trebaju oba porta odjenom! I tu nema pomoći, mora da se izabere PIC sa više nožica gde su ti moduli razdvojeni.</p> <p>Isto tako ICSP port (za programiranje) često deli port sa drugim seriskim modulima i ako bi hteli da koristite obe funkcije moralibi na PCB pločici da imate nekakve jumpere za prespajanje kada se programira i kada je u normalnom radu.</p> <p> </p> <p>Dakle kada birate model PIC-a, dobro se prebrojite oko slobodnih nožica i pogledajte specifikaciju koje se funkcije dele!</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - enaB - 02-24-2014 <p>Druže Macola, jedno pitanje ![]() <p> </p> <p>Ovakav način čekanja uzlazne tranzicije sa switch izgleda pomalo komplikovan, ali pretpostavljam da nije slučajno, pa se pitam da li je tako efikasnije ili zbog nečega drugog daje bolje rezultate nego kad bi se radilo recimo ovako, što na prvi pogled izgleda kraće</p> <pre class="_prettyXprint"> unsigned char preth=1; //... if(output_pinx && !preth) { //uradi nesto } preth=output_pinx;</pre> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-24-2014 <blockquote class="ipsBlockquote" data-author="enaB" data-cid="21392" data-time="1393242254"> <div> <p> </p> <p>Druže Macola, jedno pitanje ![]() <p> </p> <p>Ovakav način čekanja uzlazne tranzicije sa switch izgleda pomalo komplikovan, ali pretpostavljam da nije slučajno, pa se pitam da li je tako efikasnije ili zbog nečega drugog daje bolje rezultate nego kad bi se radilo recimo ovako, što na prvi pogled izgleda kraće</p> <pre class="_prettyXprint"> unsigned char preth=1; //... if(output_pinx && !preth) { //uradi nesto } preth=output_pinx;</pre> </div> </blockquote> <p>Skoro da nema razlike drugar. Oba koda će konzumirati sličan broj instrukcija posle kompajliranja, ako posmatramo samo saznavanje te jedne tranzicije.</p> <p> </p> <p>Ovo što si napisao izgleda kraće i elegantnije, dok ono sa switch obezbeđuje eksterni monitoring događaja praćenjem stanja varijable seq.</p> <p>Switch je možda lakši za višestruki copy-paste, kada ima dosta toga. posle se samo izmene brojevi i untrašnjost.</p> <p> </p> <p>Kada se posmatra samo dva moguća događaja, onda switch nema nikakvih prednosti, ali ako je više od dva događaja, tri ili još više, kao na pimer:</p> <p> </p> <p>-da li ćekamo jednu tranziciju?</p> <p>-da li čekamo drugu tranziciju?</p> <p>-da li se događa izvršenje potrebnog?</p> <p> </p> <p>Tada switch dobija prednost lakog eksternog monitorisanja, od strane nekog drugog procesa, i nekog trećeg odlučivanja na osnovu njegovog trenutnog stanja, posmatranjem njegove varijable koja menja brojnu vrednost.</p> <p> </p> <p>Sve to veoma zavisi od konkretnog zahteva.</p> <p> </p> <p>Dlakovic je postavio nedovoljno precizan zahtev, pa sam napisao samo neki od mogućih primera (može to na još koji način).</p> <p> </p> <p>Prava pitanja, od kojih zavisi način, bi bila:</p> <p> </p> <p>-da li je potrebna samo prva uzlazna tranzicija?</p> <p>-da li se posmatra svaka uzlazna?</p> <p>-u kom vremenskom okviru se mora saznati događaj?</p> <p>-šta treba uraditi posle detekcije?</p> <p>-da li se za vreme izvršavanja potrebnog sme propustiti neka od sledećih tranzicija?</p> <p> </p> <p>-itd itd. bla bla....</p> <p> </p> <p>Šta je konačno efikasnije? </p> <p> </p> <p>-Što se pisanja tiče, ono gde se manje piše (bolji način kada nema frke sa procesorskim vremenom).</p> <p>-Što se vremena izvršenja tiče, ono što će posle kompajliranja imati manje asm instrukcija (bolji način kada je frka sa vremenom, a ružniji za pisanje).</p> <p> </p> <p>Pozz</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - dlalkovic - 02-24-2014 <p><span style="color:rgb(40,40,40);font-family:helvetica, arial, sans-serif;">Dlakovic je postavio nedovoljno precizan zahtev, pa sam napisao samo neki od mogućih primera (može to na još koji način).</span></p> <p> </p> <p><span style="color:rgb(40,40,40);font-family:helvetica, arial, sans-serif;">Da pojasnim zasto pin na pin. Izlazni pin je hardverski izlaz iz komparatora u PIC-u ( poredi testerast napon sa impulsom konstantne amplitude koji se periodicno vise puta pojavljuje u periodi testerastog napona ), a ulazni pin je konfigurisan da inkrementira TMR1 na prednju ivicu ( trenutak komparacije). Ovo treba da se izvrsava nezavisno od programa. U nekom trenutku citam tajmer i u njemu imam ukupan broj pozitivnih komparacija u nekom zadatom vremenskom periodu.</span></p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Gosha - 02-24-2014 <blockquote class="ipsBlockquote"> <p> </p> <p><span style="color:rgb(40,40,40);font-family:helvetica, arial, sans-serif;">poredi testerast napon sa impulsom konstantne amplitude koji se periodicno vise puta pojavljuje u periodi testerastog napona</span></p> </blockquote> <p>Ako ti je impuls konstantne amplitude i poredis ga sa testerom uvek ces u istom trenutku imati tranziciju komparatora. Ne razumem bas najbolje ovo.</p> Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - enaB - 02-24-2014 <p>Hvala ![]() Pitanja u vezi tutorijala | Programiranje PIC mikrokontrolera u jeziku C - Macola - 02-25-2014 <blockquote class="ipsBlockquote" data-author="dlalkovic" data-cid="21412" data-time="1393261864"> <div> <p><span style="color:rgb(40,40,40);font-family:helvetica, arial, sans-serif;">Dlakovic je postavio nedovoljno precizan zahtev, pa sam napisao samo neki od mogućih primera (može to na još koji način).</span></p> <p> </p> <p><span style="color:rgb(40,40,40);font-family:helvetica, arial, sans-serif;">Da pojasnim zasto pin na pin. Izlazni pin je hardverski izlaz iz komparatora u PIC-u ( poredi testerast napon sa impulsom konstantne amplitude koji se periodicno vise puta pojavljuje u periodi testerastog napona ), a ulazni pin je konfigurisan da inkrementira TMR1 na prednju ivicu ( trenutak komparacije). Ovo treba da se izvrsava nezavisno od programa. U nekom trenutku citam tajmer i u njemu imam ukupan broj pozitivnih komparacija u nekom zadatom vremenskom periodu.</span></p> </div> </blockquote> <p>Ni meni nije baš jasno šta želiš.</p> <p> </p> <p>Otvaraju se nova pitanja:</p> <p>-koji PIC je u pitanju?</p> <p>-da li meriš frekvenciju?</p> <p>-da li možda ne praviš diskretni A/D?</p> <p>-da li možda ne "hvataš" neke stihijske pojave u određenom vremenskom intervalu?</p> <p>-da li možda precizno meriš vreme imulsa?</p> <p>-da li generišeš precizno vreme impulsa?</p> <p> </p> <p>Ne bi bilo loše da izložiš osnovnu ideju (ne moraš sve detalje ako je tajna), nacrtaš bar deo eksternog hardvera i možda talasne oblike koje očekuješ.</p> <p> </p> <p>Za sve ovo nabrojano postoje specijalizovani moduli u nekim od PIC, koji su hardverski i ne opterećuju program.</p> <p> </p> <p>Onda ti može sigurno više nas pomoći u rešavanju toga.</p> |