Fórum témák

» Több friss téma
Fórum » AVR - Miértek hogyanok
 
Témaindító: pakibec, idő: Márc 11, 2006
Témakörök:
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
Lapozás: OK   452 / 837
(#) Reggie válasza TavIR-AVR hozzászólására (») Jún 24, 2012 /
 
A programozo labakat lehet kimenetkent hasznalni, mert programozas alatt uzemmodot valt. Arra kell egyedul figyelni, hogy a labakon levo terheles ne legyen akkora, hogy a programozot a megengedettnel jobban terhelje.
(#) zombee válasza Reggie hozzászólására (») Jún 24, 2012 /
 
Ez pedig erősen programozófüggő! Pl. MAX3002-es kimenet esetében SEMMI nem lehet a lábakon!
De a gyári STK500 1kOhm-os kimenő(felhúzó) ellenállása miatt sem érdemes nagyon terhelni.
De pl. Doper esetében a kimenőbuffer jóval többet bír mint egy AVR kimenete, az mellett bátran terhelhető!
(#) oregharcos hozzászólása Jún 24, 2012 /
 
Sziasztok!
Egy dallamot akartam beprogramozni
ATtiny45-be, de valamiért nem azt kapom
vissza amire szükségem lenne.
Az alap programot Topitól vettem Bővebben: Link
Próbaként a skála hangjait raktam be, C-től C-ig és vissza, de a nyolc hangból, 4 hang nem a helyén szól.

  1. #include <avr/io.h>
  2.     #include <util/delay.h>
  3.      
  4.     //-------------------------------------
  5.     void m_delay_10ms(unsigned long val) {
  6.     //-------------------------------------
  7.                while(val--) _delay_ms(10);
  8.     }
  9.            
  10.     //-------------------------------------
  11.     void do_delay(uint16_t ms_delay, uint16_t num_ms, uint16_t us_delay, uint16_t num_us)  {
  12.     //-------------------------------------
  13.             uint16_t i;
  14.      
  15.             for(i=0;i<num_ms;i++) _delay_ms(250);
  16.             for(i=0;i<ms_delay;i++) _delay_ms(1);
  17.             for(i=0;i<num_us;i++) _delay_us(250);
  18.             for(i=0;i<us_delay;i++) _delay_us(1);
  19.     }
  20.      
  21.      
  22.     //-------------------------------------
  23.     void generate_tone(uint16_t frequency, uint16_t duration)
  24.     //-------------------------------------
  25.     {
  26.               uint32_t total_delay_time;
  27.               uint16_t total_ms_delay_time, total_us_delay_time;
  28.               uint16_t num_us_delays, num_ms_delays, ms_delay_time, us_delay_time;
  29.               uint16_t num_periods;
  30.      
  31.               total_delay_time = (1000000/frequency)/2-10;
  32.      
  33.               total_ms_delay_time = total_delay_time/1000;
  34.               num_ms_delays = total_ms_delay_time/250;
  35.               ms_delay_time = total_ms_delay_time%250;
  36.      
  37.               total_us_delay_time = total_delay_time%1000;
  38.               num_us_delays = total_us_delay_time/250;
  39.               us_delay_time = total_us_delay_time%250;
  40.      
  41.               num_periods = ((uint32_t)duration*1000)/(1000000/frequency);
  42.      
  43.               while((num_periods--) != 0)
  44.               {
  45.                  do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
  46.                  PORTB |=  (1<<PINB3);
  47.                  do_delay(ms_delay_time, num_ms_delays, us_delay_time, num_us_delays);
  48.                  PORTB &= ~(1<<PINB3);
  49.               }
  50.      
  51.               return;
  52.     }
  53.      
  54.     //-------------------------------------
  55.     int main(void) {
  56.     //-------------------------------------
  57.                DDRB = (1<<PINB3)|(1<<PINB4); //csak a PB3 és a PB4 kimenet
  58.                while(1) {
  59.                    generate_tone(261.63,400);
  60.                    generate_tone(293.66,400);
  61.                    generate_tone(329.63,400);
  62.                    generate_tone(349.23,400);
  63.                    generate_tone(392,400);
  64.                    generate_tone(440,400);
  65.                    generate_tone(493.88,400);
  66.                    generate_tone(523.26,800);
  67.                    generate_tone(493.88,400);
  68.                    generate_tone(440,400);
  69.                    generate_tone(392,400);
  70.                    generate_tone(349.23,400);
  71.                    generate_tone(329.63,400);
  72.                    generate_tone(293.66,400);
  73.                    generate_tone(261.63,400);
  74.  
  75.                    if(PORTB & (1<<PINB4)) PORTB &= ~(1<<PINB4);
  76.                                      else PORTB |=  (1<<PINB4);
  77.                    m_delay_10ms(250); //100*10ms = 1s
  78.                }
  79.                return 0;
  80.     }


Hogyan lehetne megoldani, hogy a hangok a helyére kerüljenek?
Előre is köszönöm a segítségeteket!
(#) kerdes10 hozzászólása Jún 24, 2012 /
 
köszönöm a válaszokat,tisztult a téma
(#) Reggie válasza zombee hozzászólására (») Jún 24, 2012 /
 
Akkor jol irtam.
(#) oregharcos válasza (Felhasználó 15355) hozzászólására (») Jún 25, 2012 /
 
Szia!
Köszönöm a választ!
Én is gondoltam, hogy nem lesz jó a tört szám.
Először én is egész számokkal kísérleteztem,
de akkor sem játszotta le a kívánt hangokat.
(#) zombee válasza oregharcos hozzászólására (») Jún 25, 2012 /
 
Hello!
Szerintem egy kis programozással hamar meg lehet csinálni, hiszen csak a megfelelő frekivel kell billegetni
a kimenő portokat. Kb. 2 éve volt egy olyan feladatom hogy boci-boci-tarka zenét játsszon le egy ATTiny2313.
A cucc 2 darab (inverz) kimenetet használt, mivel egy nagyteljesítményű H-híd hajtotta meg a szirénát.
Ez volt a legegyszerűbb, de a fenti kódhoz képest kicsit hosszabb volt. Ha előkerül a kód, közzéadom.

A "fejlettebb" verzióba volt egy poti, ami az ADC-re ment(ADC miatt ATMega48 hajtotta),
a program ez alapján a kitöltési tényezőt módosította, egyébként az egyszerű verzióban 100% volt.
Ha lenne most nálam működő t45 akkor kipróbálnám, lényegében az ADC hiánya miatt nem jó a t2313.
(#) oregharcos válasza zombee hozzászólására (») Jún 25, 2012 /
 
Szia, köszi az infókat! Most ezt az oldalt tanulmányozom.Bővebben: Link
(#) oregharcos válasza oregharcos hozzászólására (») Jún 25, 2012 /
 
Eddigi tanulmányozásom szerint, nem a frekvenciát kell megadni, hanem a periódust.
A táblázat szerint az A-hanghoz ami 440Hz, 110,758 kell beírni. A 110 a hang hossza 1/16. A 758 a periódus.
Kipróbálom és majd megírom, hogy jó lett-e.
(#) oregharcos válasza TavIR-AVR hozzászólására (») Jún 25, 2012 /
 
Szia! Köszönöm a segítséget!
Tanulmányoztam az oldaladon leírtakat is. Nagyon jó!
(#) oregharcos válasza oregharcos hozzászólására (») Jún 25, 2012 /
 
Természetesen ezek az adatok 8MHz-es belső oszcillátornál, vagy külső 8MHz-es kristálynál érvényesek.
(#) Ricsi89 hozzászólása Jún 26, 2012 /
 
Sziasztok!
Valaki épített már sebességmérőt autóhoz/motorhoz? Mi lenne a jobb, adott idő alatt mérni a beérkezett impulzusok számát, vagy az impulzusok között eltelt időt mérni és abból számolni sebességet? Esetleg valakinek egy forrás hasonló dologhoz?
(#) ATtiny válasza Ricsi89 hozzászólására (») Jún 26, 2012 /
 
Természetesen az impulzusok számát kell megszámolni egy adott fix időtartam alatt. Ehhez egy olyan AVR kell, aminek van 2 timere és az egyik 16 bites. A 16 bites számlálóval számolod a bejövő impulzusokat, akár úgy is bekonfigurálhatod, hogy a timer CLK -ja a bejövő impulzus legyen. A másik számláló időzíti a fix időtartamot, ez lehet 8 bites is. Ha ez a második számláló eléri a beállított időt, akkor egy megszakítást generálva ki tudod olvasni a 16 bites számláló értékét. Még annyit hozzátennék, hogy úgy kell belőni a bejövő impulzusok számát és az időt, amíg számolod az impulzusokat, hogy minél jobban ki legyen használva a 16 bites számláló. Tehát minél több impulzust kell begyűjteni, de a túlcsordulást el kell kerülni. A problémát a nagyon lassú sebesség mérése fogja okozni. Javaslom, hogy legyen minimum limit a kódban. Pl. minimum 2km/h
(#) Ricsi89 válasza ATtiny hozzászólására (») Jún 26, 2012 /
 
Igazából eddig van egy reed jeladóm és egy mágnesem a keréken. A kerék kerülete kb 1320mm. Szerintem rakok fel még egy mágnest a kerékre, hogy több impulzus legyen. Ráadásul 7 szegmenses kijelzőt akarok, így a multiplexhez kell egy timer.
Muszáj timer az impulzusok számlálásához? Simán megszakításból nem lenne számlálható?
(#) zolee1209 válasza Ricsi89 hozzászólására (») Jún 26, 2012 /
 
Még anno fősulin tanították, én meg már nem emlékszem rá pontosan, ha jobban érdekel a dolog, akkor utánakeresel.

A labor óra a frekvenciamérésről szólt, illetve annak pontosságáról. Hogy a határérték 1kHz, vagy 10kHz volt, erre már nem emlékszem... Adott érték felett impulzusszámlálás vezet pontosabb eredményhez (egységnyi idő alatt beérkező impulzusok), ezen érték alatt pedig periódusidő mérés. Az elvárt pontosság, illetve a mérhető jel frekvenciájának függvényében eldöntheted, melyiket alkalmazod.
(#) zombee válasza ATtiny hozzászólására (») Jún 26, 2012 /
 
Tévedsz!
Számold csak ki szépen hogy pl. 50km/h sebességhez 1 másodperc alatt hány impulzus szükséges!

Segítek. A példaautó Skoda Favorit, "165/65 R14" gumiméret, a kalkulátor szerint 1.791m a kerékkerület.
Nézzük, mi történik 50km/h sebesség mellett! 50km/h=13.889m/s; 13.889m/s / 1.791m = 7.755 1/s (Hz).
Tehát 4 mérésből 3 alkalommal 8, 1 alkalommal pedig 7 impulzust fog számolni a cuccosod.
Átszámolva a két érték 51.58km/h és 45.13km/h. Városban a kettő között fog ugrálni, NINCS ÁTMENET!

Ha már láttál multimétert, láthatod hogy a mintavételi idő kb. 1/3 másodperc, az 1.0 másodperc
már idegesítő lenne! 1/3 másodperces számlálásnál még durvább ugrálások jönnének ki!

Épp ezért, az ilyen méréseknél az impulzusok közt eltelt időt kell mérni.
Ha egy mérési cikluson belül(legyen az 1 vagy 1/3 másodperc) legalább 1 impulzus érkezik,
a sebességjelző nem fog ugrálni, és ami a legfontosabb: folyamatos az átmenet az értékek között!
(#) Ricsi89 válasza zombee hozzászólására (») Jún 26, 2012 /
 
Épp erre jutottam, hogy 60km/h sebességnél 12,5 fordulat lenne 1s alatt. Ha két jel jön fordulatonként, akkor ez 25jel/s. Ez nem túl sok.
(#) zombee válasza zombee hozzászólására (») Jún 26, 2012 /
 
REED relé: alkalmas(kb. 1kHz-en is tud kapcsolni), de szoftveresen szűrni kell a pergését.
Nem bonyolult, a szűrés lényege hogy egy impulzus beérkezése után az érzékelést letiltod egy időre.
A válaszott idő olyan sebességértékhez tartozzon, amit már biztosan nem érhet el az autód.
A fenti példaautónál a 40Hz(257.904km/h) már irreális, tehát vársz 25ms-t egy impulzus után!

Inkább hall-elemes érzékelőt javasolnék. A PC-k "brushless" ventilátoraiban olyan fajta van amiben
egy NPN tranzisztor kapcsol open-collector módban. Ilyet lehet külön venni, de ki is bonthatod
egy csapágyas ventiből. Az érzékenységük nem túl nagy, ezért használj neodym mágnest!
(#) kendre256 válasza zombee hozzászólására (») Jún 26, 2012 /
 
"REED relé: alkalmas(kb. 1kHz-en is tud kapcsolni)..."
A REED relé ilyesmire nem akalmas, mert annak is van élettartama. Kis áramoknál, kis feszültségeknél ez milliós kapcsolási számot jelent. Viszont ki lehet számolni, hogy másodpercenkénti kapcsolással néhány tíz napig működne folyamatosan, utána kinyíródna.
Én már jártam úgy, hogy a beépített Hamlin relét egy-két hónap után ki kellett cserélnem tranzisztorra, mert tönkrement a tízmásodpercenkénti kapcsolások miatt...
A hall szenzorral nem lenne ilyen baj, az szerintem is jó lenne (vagy valami opto).
(#) ATtiny válasza zombee hozzászólására (») Jún 27, 2012 /
 
Ha csak 1 impulzus megoldható kerékfordulatokként, akkor, akkor valóban az impulzusok közötti időtartam mérése a helyes.
(#) zombee válasza ATtiny hozzászólására (») Jún 27, 2012 /
 
Persze, növelhető a mágnesek száma, vagy optikai érzékelésnél a lyukak sűrűsége, a kérdés hogy megéri?
Az impulzusidő mérési elv csak egy hangyányival bonyolultabb, kis frekiknél ez a célszerű.

Hall-elemes érzékelésnél még van egy olyan előny, hogy egyetlen érzékelővel, plusz vezeték nélkül(csak 3 darab kell: +,-,jel) a forgási irány is mérhető. Ugyanis a szenzor "megjegyzi", hogy legutoljára milyen irányba ment át rajta a mágneses erővonal, és csak akkor vált ha a másik irányba elég erőssé válik(azaz körbeért a mágnes).
(#) oregharcos válasza Ricsi89 hozzászólására (») Jún 27, 2012 /
 
Szia Ricsi89!
Jól írják a fiúk, a reed nem lesz jó jeladónak, ugyanis nagyon hamar tönkremenne a sok kapcsolgatástól.
Régen az NDK kombájnokon úgy volt megoldva, hogy a keréken egy fémlemez volt, amikor elhaladt az érzékelő előtt, adott egy impulzust. Ezt lehetne feldolgozni AVR-el.
Ha időm engedi és érdekel, megkeresem az adatokat, és másik fórumon leírom, nem akarok itt offolni.
(#) Ricsi89 válasza oregharcos hozzászólására (») Jún 27, 2012 /
 
Egy bicikli km óra jeladó lett felrakva, mivel a bicikli órát próbáltam beüzemelni, de nem bírt a gyújtás okozta zavarokkal és semmit nem csinált. Ezért és más okokból is döntöttem a saját óra építésén. De akkor cserélni fogom a jeladót hall jeladóra.
(#) mzozo95 hozzászólása Jún 29, 2012 /
 
HI!
Egy avr tud több interruptot kezelni?
ADC interruptot, hogy kell kezelni? Annyi biztos , hogy a sei(): vel engedélyezni kell az általános interruptokat, de hogy "kapom" el, az interruptot(pl ha változás történik a lábon, akkor legyen valami)
PORT bemenetek változásáról hogyan lehet interruptot csinálni? (pl ha változik a port értéke, interrupt...), Uart-al már sikerült interruptot csinálni, azt már értem...

Tudna valaki segíteni, vagy cikket ajánlani?
(#) zombee válasza mzozo95 hozzászólására (») Jún 29, 2012 / 1
 
Hello!
Cikket nem tudok, az adatlapokat érdemes átolvasni. Több interrupt is van egy AVR-ben,
alapesetben mindegyik tiltva van. Amíg nincsen megszakításrutin hozzárendelve, tiltani is kell!

Egy interrupt egy esemény, ami bizonyos - előre beállítható - előfeltételek esetén aktiválódik.
Minden interrupthoz tartozik egy egy bites, úgynevezett "interrupt flag", ami 1-re állítódik MINDIG,
amikor az esemény bekövetkezik. Ennek párja az "interrupt maszk", ezt programból kell állítani.
Az interrupt flag-et tehát a hardver állítja be 1-re, és ha meghívódik a hozzátartozó interrupt akkor törlődik.
Figyelem! Ha nem interruptosan kezeled a perifériát, a puszta kiolvasás általában nem törli a flag-et!

Ha az interrupt maszk 1-re van állítva és az interrupt flag is 1, akkor meghívódik a megszakításrutin.
Mivel UART-ra már csináltál, nem részletezném, de fontos hogy le legyen kezelve, mert lefagyhat az AVR!

Az interrupt maszk programból bármikor törölhető, ezzel lehet tiltani az adott interruptot.
Fontos! Az interrupt flag akkor is be tud állítódni ha épp tiltva van(cli, vagy interrupt maszk=0)!
Ha nem vagy biztos abban, hogy az interrupt tiltása alatt nem-e következett be esemény,
az újraengedélyezéskor töröld az interrupt flag-et, másképp az engedélyezés pillanatában lefuthat!

ADC: általában úgy használjuk hogy elindítod, majd amikor végzett a konverzióval, interruptot generál.
Az interruptban a kiolvasás/értékelés után újra lehet indítani az ADC-t, így folyamatosan mér a háttérben.

Külső interruptok:
Megkülönböztethetünk egyedi és csoportos interruptokat, ez utóbbit nem minden AVR támogatja.
Az egyedi külső interrupt az INT0-INT1-stb. vonalakon van, ezekhez saját megszakítás tartozik.
A csoportos külső interrupt a "PCINTx"-el rendelkező lábakra állítható be. Általában PORT-onként
alkotnak egy csoportot, és egyetlen interrupt tartozik egy csoporthoz. A csoportnak beállítható egy maszk,
ezzel adjuk meg hogy melyik lábakat figyelje. Ha többet is figyelünk, az interruptban kell eldöntenünk
hogy melyik láb generálta az interruptot. Azt hiszem ehhez külön regiszter tartozik.

Delay:
Ha a háttérben interruptok is futnak, miközben _delay_ms vagy _delay_us is fut, a késleltetés
meg fog nyúlni, mivel a szoftveres késleltetés csak a neki jutó processzoridőt nézi.

Prioritás:
Ha egy órajelen belül aktiválódna 2 interrupt, mindig az fut le előbb amelyiknek kisebb a sorszáma.
Ez akkor is bekövetkezhet ha sei-t adsz ki miközben több, engedélyezett interrupt flag is 1-ben áll.

Egy interrupt lefutásakor automatikusan tiltódnak az interruptok, a befejezés után újra engedélyeződnek.
Ha nagyon szükséges, egy interrupton belül is kiadható a sei parancs, de arra nagyon kell vigyázni
hogy "önmagát" ne szakíthassa félbe egy interrupt.
Különben hamar betelhet a stack, és akkor megbolondul az AVR...
(#) Fizikus válasza mzozo95 hozzászólására (») Jún 30, 2012 / 1
 
Megszakitasok:
Bővebben: Link1 es az utana kovetkezo oldalak a cikkban...

AVR ADC:
Bővebben: Link2
(#) gosztola.laszlo hozzászólása Jún 30, 2012 /
 
Sziasztok!

AVR32 mikrokontrollerrel ismerkedem mostanában és az ADC konverterével harcoltam. Működik is jól, tudok vele szépen mérni, egészen addig, amíg a fejlesztőpanelen levő poti feszültségét mérem, vagy a saját DAC-jával generált jelet tolom vissza az ADC-be.

Viszont szerettem volna egy másik mikrokontroller DAC-jával jelet generálni és ezt beküldeni a kontroller ADC-jébe, viszont ha összekötöttem a megfelelő lábakat, a kimenet leült földre.
Próbáltam másik mikrokontrollerrel is, a DAC-ból kijövő fűrészfogjel ott is összeesett pár millivolt-os amplitúdóra, de a fűrészfog minta nagyjából megmaradt.

Mi lehet ennek a jelenségnek az oka és hogyan lehetne kivédeni?

Sajnos analóg technikában nem nagyon vagyok otthon, de én azt gondolnám, hogy az ADC-nek elég nagy belső impedanciájának kellene hogy legyen ahhoz, hogy ne ültesse le a jelet.

A tesztkörnyezet:
A mintavételező proci: AVR32 UC3C0512 - UC3C-EK boardon, 1 MS/sec sebességgel
A jelet generáló: stm32 vl discovery board
(#) sgt válasza gosztola.laszlo hozzászólására (») Jún 30, 2012 /
 
Szia!

Nekem is az jutott az eszembe legelőször, hogy nagyon leterheli. Tegyél be egy feszültség követő erősítőt. Az majd impedanciában oda fogja illeszteni ahogy kell.
(#) mzozo95 válasza Fizikus hozzászólására (») Jún 30, 2012 /
 
Köszönöm Fizikusnak és Zombee-nak a segítséget!
Következő: »»   452 / 837
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem