Fórum témák
» Több friss téma |
WinAVR / GCC alapszabályok: 1. Ha ISR-ben használsz globális változót, az legyen "volatile" 2. Soha ne érjen véget a main() függvény 3. UART/USART hibák 99,9% a rossz órajel miatt van 4. Kerüld el a -O0 optimalizációs beállítást minden áron 5. Ha nem jó a _delay időzítése, akkor túllépted a 65ms-et, vagy rossz az optimalizációs beállítás 6. Ha a PORTC-n nem működik valami, kapcsold ki a JTAG-et Bővebben: AVR-libc FAQ
Az OCRA = 4.12 vicces, a fordító egyébként visszakerekíti 4-re, ne aggódj (a tömböd 4,4,4,4,4,4,4,5 lesz)
Menet közben is változtathatod az értékét az OCR-eknek, szoktam is, amikor zenét játszom. Két lehetőséged van: vagy definiálsz egy interruptot és minden 20,000. alkalom után váltasz (1s), vagy indítasz egy másik, lassabb timert, arra definiálsz interruptot. Az első hátulütője, hogy 20kHz-en két megszakítás között 400 órajelciklus telik el. Ebbe kell az interruptodnak beleférni, ez relatíve kevés, de megoldható vele, viszont érezhetően belassít minden mást, amit csinálnál. A hozzászólás módosítva: Jún 26, 2013
Jó tudni. Akkor te hogyan oldanád meg azt a freki változtatást?
Ez az interruptozás nekem kicsit magas A hozzászólás módosítva: Jún 26, 2013
Sziasztok!
Vízhőfokot kellene állanó 16 °C-on tartanom. Ezt egy keverőszeleppel kell megoldanom. Abban vagyok bizonytalan, hogy milyen hőérzékelőt válasszak. A szelep motorja max. 15mm-t mozog. Sebessége 15s/mm. Szerintetek erre elég lenne egy NTC érzékelő is vagy jobb egy DS1820 ?
Szerintem nem annyira OFF, másokat is érdekelhet a megoldás.
A1: Az ATMega128 külső megszakításait kezelő lábak a PD0-PD3 (INT0-INT3) illetve a PE4-PE7 (INT4-INT7) portlábakon találhatók. Engedélyezni ill. tiltani az EIMSK regiszterrel lehet őket egyesével, a megszakítás feltételét(lefutó/felfutó él, bármilyen élátmenet - toggle mód, és szintvezérlés - LOW állapot) az EICRA és EICRB regiszterekben lehet beállítani. A2: rajz nem lesz, csak program.
A3: A tisztán hardveres megoldás csak 16 bites időzítővel lehetséges, 8 biteshez túl nagy a CPU frekvencia: 8000000/1024=7812.5 - a legnagyobb előosztóval is nagyobb lesz mint 255. 16 bites időzítők: Timer1 és Timer3, bármelyikkel megoldható. 8 bites időzítők: timer0 és timer2. Pontosan 1s időzítéshez kell egy 8 bites segédváltozó is - szoftveres rásegítés miatt. 1024-es előosztó nem jó, mert nem ad egész értéket. Ezért 256-osat használnuk. 8000000/256=31250 - ekkora frekvenciával fog a TCNT0 lépkedni. CTC módban a komparátor regiszterbe (OCR0A) 249-et kell tölteni, ekkor a számláló 31250/250=125-ször fog körbefordulni másodpercenként. Minden körbefordulásnál növeljük a segédváltozót, ha eléri a 125-öt akkor le kell nullázni és lefuttatni azt a programrészt ami 1s-es időzítést igényel. B1: Az ATMega128 2 darab, teljesen azonos funkcionalitással és önálló regiszterkészlettel rendelkező USART egységet tartalmaz: USART0 és USART1. Az egység sorszámát ezek után "n"-el jelölöm, mivel mindkettőre érvényesek az alábbiak: - aszinkron működési mód 5-9 biten, beállítható paritásbit ill. 1 vagy 2 stopbit - szinkron működés, azonos az aszinkronnal, csak kiegészül az XCKn szinkron vezetékkel. Adó vezeték: TxDn; vevő vezeték: RxDn; szinkron vezeték(XCKn) - csak szinkron módban Aszinkron átvitel: start bittel indul, a bitek visszaállítása belső számlálóval történik - előre meg kell beszélni a sebességet - BAUD RATE. Ezt az UBRRn 16 bites regiszterben lehet beállítani: UBRRn = (F_CPU/16/BAUD_RATE)-1. Vezérlő regiszterek - nem részletezem a szerepüket: UCSRnA, UCSRnB, UCSRnC; A 3 féle megszakítás kezeléséhez(küldés kész, fogadás kész, adó buffer üres) engedélyező és a flag bitek állnak rendelkezésre, amelyek az UCSRnB, UCSRnA regiszterekben találhatók. B2: a példa az A2-ben, különbség hogy 2 gombra kell ugyanazt megoldani! B3: Az eleje ugyanaz mint A3, tehát kell a segédváltozó. Előosztó: 128; ekkor a számláló 4000000/128=31250--szer lépked másodpercenként(TCNT0). Fontos hogy 10-el osztható legyen! A komparátor regiszterbe 124-et töltünk, ekkor 31250/125=250 körbefordulás történik másodpercenként. 100ms-onként 25, tehát 300ms-onként 75. Tehát a segédváltozót minden körbefordulásnál 1-el növeljük, ha eléri a 75-öt akkor le kell nullázni és futtatni a 300ms-os programrészt. C1: Az ATMega128 8 darab ADC csatornát használ, melyek az F porton találhatóak. A konverzió a szukcesszív approximáció elvén működik. Ehhez tartozik egy számláló(minden konverziós lépéshez 13 ADC órajel szükséges), egy komparátor és egy DAC. Utóbbi a szukcesszív approximációs eljárás jellegzetessége, a konverzió alatti visszacsatolás miatt szükséges. Tulajdonságok: 10 bites felbontás, egyetlen csatorna esetén max. 15kSPs mintavételi sebesség, többféle feszültségreferencia(2.56V, AVCC, külső), differenciális bemenetválasztás, utóbbi esetén 20 és 200-szoros analóg előerősítés választható. Egyszerre csak egyetlen csatornán(differenciális bemenetnél csatornapáron) végezhető a konverzió. ADC regiszter: 16 bites, konverzió után ide kerül az eredmény ADMUX regiszter: kiválasztható vele a referenciafeszültség(REFS1 és REFS0 bitek), a bitek eltolása a 16 bites ADC regiszterben - alsó vagy fölső 10 bit használata(ADLAR bit), csatorna vagy csatornapár(differenciális bemenetnél), utúbbi esetben az erősítés is - ezek a MUX4:MUX0 biteken. ADCSRA regiszter: vezérlő-és státusz. konverzió indítás, konverzió befejezés detektálás, megszakítás engedélyezés, ADC órajel osztója(F_CPU/2^n - ahol n=1..7). C2: nagyon épít az A2 és B2 feladatra, ha azokat érted akkor nem lesz gond. Az időzítés lehet szoftveres, mivel nem adtak meg CPU sebességet. C3: UGYANAZ MINT A B3 feladat, a 100ms-es időzítésig. Mivel az órajel negyede, az előosztó is lehet negyede: 128->32. Komparátor regisztert 124-re kell állítani, ekkor a számláló 1000000/32/125=250-szer fordul körbe másodpercenként, ilyenkor a segédváltozót 1-el növeljük. Ha a segédváltozó eléri a 25-öt, le kell nullázni és tudod mi lesz... Nem biztos hogy minden hibátlan, de a gondolatmenet az már több mint értékelhető. Ha felém jársz valamikor, meghívhatsz egy sörre. A hozzászólás módosítva: Jún 26, 2013
Vegyél vissza az előosztóból, és akkor beállíthatsz nagyobb értéket is az OCRA-ba!
Még így sem biztos hogy egész, de legalább pontosabb lesz! A hozzászólás módosítva: Jún 26, 2013
Levettem az F_CPU-t 1MHz-re, prescalert 1024-en hagytam így az excel táblázatom szerint az OCRA 40-122-között változik és nincs ismétlődés.
Már csak a frekvencia változásra kell valamit kitalálni. A hozzászólás módosítva: Jún 26, 2013
CTC módot használsz? Azzal nem fog menni. Bocs, nem olvastam végig mindenki hozzászólását!
Ne haragudj, de ennek így semmi értelme. Nem 20 kHz-es jelet kellene előállítanod? Ennek a felállásnak az elméleti maximális sebessége 1 kHz.
Azt javaslom, hogy telepíts egy AVR Studio-t és alatta szimuláld végig, hogy mit csinál a timer és hogyan változtatja a kimeneteit. Miután tisztázódott, hogy mi az a prescaler, hogyan lehet a kimenetekre rákapcsolni a timert, hogyan tudsz az órajel ismeretében adott frekvenciát beállítani, akkor kérdezz.
Miért nem jó a CTC mód?
@csabeszq Úgy néz ki fáradtan nem jó ilyenekkel szórakozni. Na még egyszer akkor. 8MHz, no prescaling, CTC mód, ORCA 200, freki 19,9kHz. 8000000/(2*(1+200)) = 19900.49Hz Remélem most már nem számoltam el semmit.
Akkor már csak egy árnyalatnyit tennék hozzá, ami igazából szépség kérdése, a működést nem befolyásolja.
A TCCR0A-nak nincs WGM02 bitje. A WGM02 a TCCR0B-hez tartozik. Az |= helyett meg az = biztonságosabb.
Később, ha változtatsz valamit a kódon, az ilyen apróságokkal szokott fél nap elmenni. A hozzászólás módosítva: Jún 27, 2013
Azért nem jó a CTC, mert nincs szinkronizálás. Ha menet közben változtatod a kitöltést,
az a kimenetre is hatással van ami nem kívánatos. PWM módban a változtatás a számláló körbeérése után érvényesül. És CTC módban az OCRnA-t nem használhatod a kitöltés beállítására. A hozzászólás módosítva: Jún 27, 2013
Azért választottam a CTC-t mert itt fix az 50%-os kitöltési tényező, ami nekem megfelel, egy tranzisztort akarok vele kapcsolgatni. Csak a frekvencia fog változni, amit még egyelőre nem tudom hogyan oldjak meg.
@csabeszq Igazad van, köszi.
Definiáltam egy másik timert, TCCR1 1024-es prescalerrel. (CS13,CS11,CS10 ->1)
TCNT1-be beírtam 57723 értéket. TIMSK-ba beállítottam a TOIE1 bitet Még valami global interrupt bitet kell beállítani valami SREGbe, tovább nem tudom :/
Egy kérdés:
Mi a legjobb eljárás C ill ASM- ben irt részprogramok összeolvasztására? Kösz!
Nem triviális megérteni az asm volatile-t, olvass utána, hogy hogyan működik. A hozzászólás módosítva: Jún 28, 2013
Kösz.
Ez így szerinted jó?
Fejben elég nehéz futtatni, de
- a timer1 szerintem nem fog menni, ott is definiálni kell a WGM-et, különben áll - OCR0A-t nem állítod be az ISR végén - a TCNT1 = 57723 beállítja a timert, majd 0xFFFF-nél megszakít, utána 0-ról újrakezdi. Gondolom nem ezt akarod, ott is az OCR1A-val kellene trükközni, ahogy a timer0-nál - még megjegyzéskét: a freq változó jelenleg jó úgy ahogy van, de amint a főprogramból is elkezdenéd írni/olvasni "volatile int freq" deklaráció kell. A volatile akkor kell, amikor a főszál / interrupt egyszerre kezel egy változót. Nálad nem ez van, csak a teljesség kedvéért írtam le, hogy később ne lepődj meg, ha az interrupt módosít, de a fő szál a régi értéket használná, akkor az a volatile hiánya. A hozzászólás módosítva: Jún 28, 2013
TCCR1-nél nem láttam WGM bitet az adatlapban.
Az OCR0A = freq; -t bedobtam az ISR-be ugyanúgy a TCNT1 = 57723; -t is.
Sajna nincs oszcilloszkópom amivel le tudnám ellenőrizni hogy jó e a kimenet. Ha szerinted így jó akkor megpróbálok csinálni egy módosított verziót ami 1Hz-től 50Hz-ig változik, azt egy leddel le tudom ellenőrizni.
Az Attiny45-nek nincs 16 bites timere, a Timer1 a mega IC-ken 16 bites. A TCNT1 0 és 255 közötti egész szám lehet.
Bővebben: Doksi 89. oldaltól a 94. oldalig van minden leírva. A hozzászólás módosítva: Jún 28, 2013
Sziasztok
Lehet valamit nem tudok ami ti igen de ez a kód miért nem működik úgy ahogy kellene neki? Egy frekvencia generátort szeretnék belőle. Van egy függvény aminek beadom a kívánt frekit és az F_CPU előosztás értékét.
így viszont működik:
így is próbáltam, nem jó:
mind 2 esetben OCR1A értéke 0 (nulla). Van valami ötletetek hogy mi okozza ezt? (Fejlesztő környezet: AtmelStudio6) Üdv: Suncorgo A hozzászólás módosítva: Jún 28, 2013
Vagyis akkor a timer1-et be se lehet állítani 1sec-re? (Ha 8MHz az F_CPU)
A hozzászólás módosítva: Jún 28, 2013
@Suncorgo
1. - ez egy mikrokontroller, inkább használj egész számokat, kevesebb bajod lesz vele 2. - a te esetedben egyértelműen kerekítési hibáról beszélünk. Az 1/3-ad végeredménye 10-es számrendszerben: 0.3333333333333333.... Az 1/5-öd végeredménye 16-os számrendszerben: 0.3333333333333333.... hexadecimálisan Egyértelmű, hogy a 0,000004 az végtelen tizedestört 16-os számrendszerben az 1/5-ös osztás miatt. Értelemszerűen az
programozási hiba, mert mi van ha a végeredmény 0.09999999999. Akkor már nem egyenlő? Térjünk vissza a te esetedre:
A fordító ezt neked fordításnál kiszámolja a PC-n alkalmazott alapértelmezett 8 byte-os double-lel. Ennek pontossága 1/10^15-en.
Ezt bizony már az AVR számolja ki, ahol a double 4 byte-os, a pontossága 1/10^7-en. Nyilván a 16-os számrendszerben a végtelen tizedestörted egy kissé bezavar, ezért lehet a végeredmény más, mondjuk 124.9999, ami egészre kerekítés után 124 lesz. A hozzászólás módosítva: Jún 29, 2013
Sziasztok ! Van egy kis problémám egy avr-re kötött pillanat kapcsolóval.Start/stop funkciót lát el,engedélyezi ill.tiltja a timer megszakítást.Prell mentesítést tettem be 60ms-os újraolvasással,port beolvasás van a ciklusban,felhúzó ellenállás bekapcsolva.Viszont elég rövid a loop ciklusom,gondolom ezért bizonytalan a működés,sokszor nem vált funkciót,valószínűleg rádupláz.Hogy lehetne ezt megoldani ? Kösz !
Oké
Köszi a kimeritő választ, szép napot
Gomb lenyomáskor tegyél be egy gomb tiltó fleget.
Ezt csak felengedett állapotban tudd törölni.
Ez így jó lehet? A hozzászólás módosítva: Jún 29, 2013
Ez a kód,ha beteszek egy tiltó fleget, a loop-ban újra engedélyeznem kell,szerintem akkor ismét rá tud futni a ciklus hosszabb gombnyomás esetén...de lehet,hogy rosszul értem amit írtál.
Igen, én is így szoktam a ritka interruptokat kezelni.
Egyébként szúnyogriasztót építesz? |
Bejelentkezés
Hirdetés |