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
Melyik cikkre gondolsz mert nem találom.
Tettem bele késleltetést, de lehet rossz helyre mert nem jó a dolog.
Hello!
A késleltetéssel - legtöbb esetben - csak baj van, egyedül a legegyszerűbb eseteknél nem gond. Nagyon rossz minőségű gomboknál előfordul hogy nyomva tartás közben is pereg. Ezeket olcsóbb cserélni mint kódot írni rá! Szűrő: a legegyszerűbb ha teszel egy pár száz nF-os kondit a kapcsoló két kontaktja közé. Sajna most nincs előttem az a logaritmusos képlet amivel meghatározható a töltődés ideje, ezért próbálgatni kell! Alulmintavételezés: a késleltetős megoldáson alapul, tehát a mintavétel ritkábban történik mint a pergés ideje lenyomáskor/felengedéskor. Ezt időzítő interrupttal lehet hatékonyan megoldani. Hogy ne engedjelek el üres kézzel, adok egy kódot amiben késleltetés van. A késleltetés ideje 750us, de a while ciklus maga is eszi a CPU-t, így egy ciklus kb. 1ms. Ez ugye nem elég, ezért figyelem a nyomvatartási időt is. Ha eléri a BTIME_MIN (20ms) értéket csak akkor fogadjuk el a lenyomást. Kis apróság, hogy ha eléri a BTIME_MAX értéket(2 sec) akkor az áramkör lekapcsolja magát...
A "nem jo a dolog" helyett irdd mar le legyszi mit csinal vagy mit nem, mert igy nehez kitalalnunk mi nm stimmel
![]() Ez nagyjabol jo, csakhogy figyelned kellene a gomb felengedeset, vagy pedig eltarolnod az elozo allapotot (hacsak nem vagy eleg gyors, es el nem engeded fel masodpercen belul). Amugy elegendo ugy 20-50 ms varakozas a legtobb gomb eseteben.
Megerősítem! Késleltetős és számlálós módszernél is a gomb állapotát el kell tárolni,
másképp nem detektálható egy "lenyomás" vagy "felengedés". Csak "le van nyomva" vagy "fel van engedve" állapotot lehet így lekérdezni!
Csak akkor a rendszerben lesz egy kis késleltetés, engem speciel idegesítene ha csak felengedés után
történik meg az, amiért a gombot lenyomtam. Ha meg lenyomásra vár akkor szintén blokkolva van. Ez csak akkor lehet jó, ha a programnak nincs semmi hasznos teendője a gomb lenyomásáig/felengedéséig.
Az adatlapja donti el a minoseget. Minel alacsonyabb a ppm erteke, annal jobb.
Pontosan! Nem a leg optimalisabb megoldas, hogy finom legyek. De hat tanulgatni jo ez is, meg hat vannak nagyon egyszeru alkalmazasok amibe teljesen mindegy hogyan oldjak meg a billentyu kezelest -- beallitasokhoz pl ahol nem szukseges hogy kozben tovabbra is menjen az alap funkcio, vagy be-ki kapcsolashoz, karaconyfa villogtatoba, stopper oraba stb elmegy igy is.
Stopper órába?
![]() Gondolom sütő-órára vagy bomba-visszaszámlálóra gondolsz és nem sportesemények segédeszközeire...
Köszönöm a segítséget. Látom pár napja is ezzel bénázott valaki. Bővebben: Link
Ezekből is szemezgetek egy kicsit. ![]()
Nos, hogy teljes legyen. Itt jól kivesézi a srác a kérdést:Bővebben: Link
Az olvasottak alapján a következőt hoztam össze szoftveres pergésmentesítésre:
Létrehoztam a button_is_pressed() függvényt így csak ezt kell paraméterezni és kész. A programban bárhol használható. Tesztk alapján tökéletesen működik. Atmega168 az MCU 16MHz órajellel. Mi a véleményetek? Esetleg programozástechnikai hiba? Még csak most szokom a C-t.
Amúgy itt meglelhetők egész jó források pergésmentesítésre: Debounce Code - one post to rule them all
Pergésmentesítéshez olvasmány: Bővebben: Link
Olvastam, de én megszakítás nélkül szeretném. A mellékelt dolgot hogyan használod, ha PD2 (INT0) lábad már foglalt?
Kérdés, milyen IC-d van, pl. van-e rajta INT1, INT2, stb.
Ezen kívül még van a PCINT, ha erre csak 1 kimenetet állítasz be akkor olyan mint ha egy INT lenne. Még van az ICP1 is, erre is beállíthatsz interruptot. Illetve van az analóg komparátor, de ehhez 2 láb kell)...
atmega168 és a gombok 11, 12, 13, 14 lábakon vannak. De ez csak próba panel tehát általános megoldást keresek. Amit készítettem az is bugos kicsit.
![]()
Ez mukodhet, es jo lehet, csak azt a magabiztossagi valtozot kell beloni jol minden alkalmazashoz. Nyilvan a gomb lekerdezgetese fog attol is fuggeni, hogy a fo ciklusodban a tobbi elem mennyit idozik -- jelen esetben ez elhanyagolhato. De ha oda bekerul egy par-tiz ezredmasodperces kesleltetes (pl LCD-re kiiras de lehet az barmi mas is), akkor mar jelentosen none a lekerdezesek kozott eltelt ido. Tehat ha csak minden 10ms-ben kerdezgeted le, akkor 10ms * 500 = 5s ami kicsit sok lenne
![]() Egy hibat azonban felfedeztem: Mindket Confidence Levelt torolnod kellene megnyomaskor ill felengedeskor! Pl a gombot nem nyomod meg, akkor ugye a Release_Confidence_Level elkezd novekedni, es minden 500. alkalommal torlodik. De ha pl a 250. alkalomnal magnyomtad a gombot, akkor felengedeskor mar csak 250-et var, magyarul lehet meg a perges elott ugy dontesz minden rendben van...
Sziasztok!
Puli122 AVR-es tesztpaneljét építettem meg és az lenne a kérdésem, hogy milyen típusú kijelző kell hozzá, mert csak annyi van megadva, hogy olyan kivitelű, amin oldalt vannak a kivezetések, úgy meg nem kérhetek. Előre is köszönöm!
Én a következő megoldást használom:
~50 ms késletetéssel hívok meg egy függvényt. Ez a gombok állapotát vizsgálja. Amennyiben egy gomb egymás után ugyanazt az állapotot adja, tehát 100ms eltéréssel, akkor le van nyomva. A felengedést hasonlóan vizsgálja. De végeredményben a logikája teljesen mindegy, a fontos az, hogy mindez valamelyik timer interruptjából hívódik meg fix időközönként. A kódom természetesen nagyon gyorsan lefut. Ha nem tudsz olyan hatékony kódot írni és félsz, hogy sokat időzöl egy nagy prioritású interruptban, akkor csak egy flaget bökjél meg, aztán a main ciklusban vizsgáld az állapotokat.
Sziasztok!
Most inkább ez talán programozás technikai kérdés. Kezdő vagyok még C-ben is. Építettem egy teszt panelt, hogy kipróbáljam az ötleteim. Ezen van egy atmega168. Amit csinálok: SPI-n keresztül vezérlek egy Shift regisztert 74HC595 ami vezérel egy tranzisztor mezőt ULN2804 ami reléket kapcsol ki-be a hozzájuk tartozó nyomógombok segítségével. Ezt az egészet még megfűszereztem egy RS232 vezérléssel majd C#-ban is készítettem neki kezelőfelületet. Most szeretném gatyába rázni a kódot az AVR-en. A relék vezérlésénél bizonytalanodtam el. Létrehoztam egy változót:
Alap értéket is kapott:
Mikor lenyomom a reléhez tartozó gombot akkor beállítom a szükséges bit-et
Itt pont az első reléhez tartozó módosítás látható. Kérdésem, hogy jó ez így, hogy a releal változó az unsigned char ? Nekem az a fontos, hogy egy 8 bit-es vagyis 1 byte-os változóban tudjam tárolni az összes relé állapotát és innen kezelni. Remélem érthetően fogalmaztam. Új még nekem a C világa és kicsit fáradt is vagyok. sikolymester Még csiszolgatok a pergésmentesítésen mert nem az igazi, ha több gombot kezelek és nem csak egy ledet kapcsolok. Most az IF feltételek végére beszúrtam egy _delay_ms(250); sort és így egyenlőre jó, de javítanom kell még rajta.
Igen, jo az ugy. De hasznalhatsz uint8_t -t is akar, illetve definialhatsz magdnak tipust:
Nezd meg, hogy a deklaracios sorban is lehet inicializalni a valtozot - ez amiatt jo, mert igy azonnal latod, hogy nem felejtetted el ezt megtenni... Azonkivul a foditok az ilyen inicializalgatasokat optimalizalva vegzik el, igy gyorsabb, mintha egyesevel tenned meg ugyanezt.
De komolyan. Rossz nézni ahogy szenvedsz. Használd már azt az átkozott timert és tegyél alá egy state machinet.
Az ilyenek:
meg az ilyenek:
elkerülése végett, mert frászt kapok ha ránézek. Itt egy állapot gépre egy példa. Ez egy forgalmi lámpa megvalósítása:
Nyomógombbal mindennel együtt, és frankón működik.
Szia!
Én atmega168-at használok gyakorláshoz. Próbapanelen csináltam egy teszt áramkört és ez van benne DIP28 tokkal. [off] Sikerült összehozni a programozást?
Sziasztok!
Gondom támadt az SPI-vel. MCU: Atmega168 Freq.: 16 MHz Az SPI-n keresztül vezérlem a 74hc595 shift regisztert ami egy uln2804 tranzisztormezőt vezérel. Szépen működik is a dolog. Hibát akkor észleltem mikor használni szerettem volna a maradék B portot. Konkrétan PB0 és PB1. PB0-ra egy nyomógombot kötöttem, PB1-re egy LED-et. Nos az utóbbi nem működik. SPI init:
A LED init:
Ha LED init az SPI init elé kerül akkor működik, de nagyon halványan. Ha viszont az SPI init után teszem akkor a működés teljesen összezavarodik. Mi lehet a gond? Másik kérdés: Bővebben: Link Itt azt írják a 6.oldalon, hogy SPI/ISP közös használatakor használjunk soros védőellenállást. Én 10k tettem be. A gond az, hogy mikor programozom akkor kapcsolgatnak a kimeneti relék amit az SPI vezérel. Ezt hogyan lehetne kiküszöbölni úgy, hogy programozás előtt ne kelljen kapcsolókat állítgatni?
A fentebbi két sor, teljesen törli az SPI beállításait, ezért szoktuk használni a | operátort, ami nem fogja bántani ![]() Másik kérdésedre a válasz. Mivel CMOS IC-t használsz, ezért ha ujjadat húzod végig, akkor is befognak húzni a relék, mert elég egy apró tüske is a CMOS-nak. Első körben TTL-t használnék, vagy tegyél kondikat a CMOS lábaira. Ui. nekem még a 8 bites shift regiszterrel egyáltalán nem sikerült kapcsolatot létesítenem SPI-al. Egyelőre sima port billegetéssel csinálom, de nekem is rá kéne feküdni, hogy mi lehet a baja.
Mega328.
Memória, szolgáltatások és ár alapján... M48-at hamar kinövöd....
A 10k és a shiftregiszter közé tegyél be fel/lehúzó ellenállásokat, mert ugye az a baj, hogy amíg te programozol addig legtöbb láb HiZ állapotban, és ezekkel az ellenállásokkal statikus szinten tudod tartani.
Az ATMega168 es 328 azert is jo valasztas, mert az Arduino is erre epul, amire rengeteg tutorialt es projektet lehet talalni a neten...
Bakker. Igazad van
![]() Módosítottam a kódot most már tökéletes:
|
Bejelentkezés
Hirdetés |