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   709 / 837
(#) kapu48 válasza rolandgw hozzászólására (») Nov 29, 2015 /
 
A gondolásból még nem éert az AVR!

Mivel a Mainban növeli "statet"!
  1. int main(void)
  2. {
  3.        
  4.         DDRB = (1<<LED);                                                        // Set LED as an output
  5.         PINB &= ~( 1 << LED );            // write 0 to disable internal pullup
  6.         PORTB |= (1<<LED);                                          // Turn off LED
  7.         Init_Timer1();
  8.         set_sleep_mode(SLEEP_MODE_IDLE);
  9.        
  10.     while (1)
  11.     {
  12.                
  13.                 cli();
  14.                                                
  15.                         State ++;   <<<<<<<<<< ITT növeli
  16.                                
  17.                 if (State > 0x03) {
(#) rolandgw válasza kapu48 hozzászólására (») Nov 29, 2015 /
 
Látom,de akkor mit tesztel az IT-n,ha már azt írta ?
(#) fecus hozzászólása Nov 29, 2015 /
 
Köszönöm mindenkinek.
Az biztos, hogy kijön a megszakításból mert szépen másodpercenként villogtatja a LEDet, de csak egy állapotát és nem lép.
Már úgy is megírtam amikor a növelés az IT rutinban volt. Úgy sem változott. Egyszerűen nem incrementál.
(#) zombee válasza Gj hozzászólására (») Nov 29, 2015 1 /
 
Az a buktató hogy az RS485 meg az I2C teljesen másra lettek kitalálva ezért nem tudsz belőle konvertert készíteni. Kezdjük ott hogy az RS485(így az UART) úgy működik hogy az egyik végpont belenyom a buszba X bitet, aztán várakozik. A többi végpont ezt látja, olvassa, ami alapján egy
-kis idő- múlva válaszol.

Ellenben az I2C úgy néz ki hogy az egyik végpont kiadja a címet, közben az SCL vonalon szinkronizál. Erre a megszólított végpont -válaszol- az ACK bit lehúzásával, majd időnként igénybe veszi az SDA vonalat is miközben az SCL-en továbbra is a master szinkronizál. Az átvitel kezdetét/végét szintén a master adja.

Nagyobb távolság áthidalásánál két fontos lépés van. Az egyik a jelfeszültség megemelése, ezt használják az RS-232 esetén is ami kb. 10-20 métert átfed. Csavarás, árnyékolás nélkül, kis sebességgel. A következő lépés a kábelek megcsavarása, amivel a zavarjeleket ki lehet szűrni. Megpróbálhatod csak simán, csavart kábelpárokkal átvinni a jelet(SCL+GND; SDA+GND), ehhez viszont mind a két oldalon kis értékű(~470Ohm) felhúzó ellenállás kell, amit az IC-k még elbírnak. A nagy sebességet pedig felejtsd el, a hosszú kábel kapacitása(különösen ha csavart) így is sok energiát felemészt. Ne felejtsd el mind a két oldalon védődiódákkal ellátni a jelvezetékeket, de még a tápokra is tegyél mert elég a közelben egy mobiltelefon és valamit szét fog csapni!

A másik, gusztusosabb megoldás egy I2C buffer alkalmazása. Bővebben: Link
Tény hogy nem olcsó az IC, de egy ilyen hálózatnál érdemes megejteni. Működésének lényege a feszültség megemelése mellett a csavart érpáron a polaritás megfordításával adja-veszi a jeleket. Ha az egyik oldal inaktív(pl. várja a jelet) akkor a másik oldal által adott jelet is képes érzékelni mind az SDA, mind az SCL oldalon.

És jegyezd meg: attól hogy csavart kábelt használsz, még nem lesz RS485 a hálózat.
A hozzászólás módosítva: Nov 29, 2015
(#) kapu48 válasza fecus hozzászólására (») Nov 29, 2015 /
 
Én pedig, Egyszerűen nem értelek!

Van 1 timered engedélyezet Timer1_OVF_INT-el.
De nincsen ami lekezelje azt!
Hol marad a:
  1. ISR(Timer1_OVF_vect)
  2.    {
  3.            // TODO???
  4.    }
(#) fecus válasza kapu48 hozzászólására (») Nov 29, 2015 /
 
Már csináltam ilyet a nixie órámban. Ilyenkor visszatér a fő programba. Gondolom default ret van benne. De megpróbálom.
Most 32kHz-re gyanakszom, de nem tudom mi lehet.
(#) kapu48 válasza fecus hozzászólására (») Nov 29, 2015 /
 
Mivel a föprogramod végén ez a rutint hivod:
  1. #if defined(__DOXYGEN__)
  2.  
  3. extern void sleep_mode (void);
  4.  
  5. #else
  6.  
  7. #define sleep_mode() \
  8. do {                 \
  9.     sleep_enable();  \
  10.     sleep_cpu();     \
  11.     sleep_disable(); \
  12. } while (0)
  13.  
  14. #endif


Tehát ide tér vissza a megszakításod?

vagy esetleg ide:
  1. int main(void)
  2. {   <<<<<<<<<<<<<<<?????????
A hozzászólás módosítva: Nov 29, 2015
(#) fecus válasza fecus hozzászólására (») Nov 29, 2015 /
 
Mea culpa, mea maxima culpa!! Így működik!

kapu48: Igazad volt. Köszönöm. Esküszöm már megírtam egyszer ezen a módon, de akkor nem ment.

  1. ISR(TIMER1_OVF_vect)
  2.     {
  3.             State ++;
  4.                        
  5.                 if (State > 0x03)
  6.                         {
  7.                                 State = 0x00;
  8.                         }
  9.     }
(#) Gj válasza zombee hozzászólására (») Nov 30, 2015 /
 
És ha azt csinálom, hogy csak az rs485-nél alkalmazott kábelezéssel és SN75176 IC-kkel, két érpárral, 12V-tal "felerősítem" az I2C-t? A csatolt képen látszik, hogy mire gondolok.
Azért akarok ennyire I2C-t, mert I2C-s szenzorokat kéne összekötni mikrovezérlőkkel és nem akarok minden szenzorhoz berakni egy MCU-t, hogy az I2C-n kidobott jelet átnyomja UART-ra.
Az ugye nem gond, ha egyszerre az Adás és a Vétel engedélyező pin is fel van húzva?

És még két kérdés:
-Hogyan kell bekötniaz SN75176 IC-ket, hogy a buszokon 12V legyen?
-Az érpárokra is kellenek fel/lehúzó ellenállások, de mekkorák, és melyikre melyik?

Előre is köszönöm!
(#) zombee válasza Gj hozzászólására (») Nov 30, 2015 /
 
negatív.

Az IC nem képes +/- 5V-nál nagyobb átviteli feszültségre, de 30-50 méteren és csavart érpáron még 100% hogy működik egy UART jel átvitele.

A baj ott van, hogy az adott konverter IC-nek "tudnia kell" hogy mikor van adás az ő oldalán, vagy éppen vétel. I2C-nél pl. a címzésnél a master oldalon kell hajtani, azán ki kell kapcsolnia a DE-t, hogy a másik oldalon a slave(I2C periféria) bekapcsolja, mert ACK-ot fog küldeni, aztán meg vissza mindent. Ja meg a slave lehúzva tart(hat)ja az SCL-t ami újabb érdekes kérdéseket vet fel. Igazából a master és slave oldalon is kellene 1-1 I2C protokoll IC(akár AVR-el is) ami az I2C protokollt ismerve tudja mikor kell az ő oldalán az SDA/SCL vonalon a DE-t engedélyezni. Az I2C ezért (is) nem erre való!

Ha már van egy AVR a periféria oldalon, akkor az legyen egy UART+I2C - képes típus, ami a master oldalról érkező RS-485 parancs alapján elindít egy I2C lekérést a mellette lévő I2C periférián, majd - igény esetén - nyugtázza az átvitelt. Mindkét oldalon kell 1-1 extra láb hogy az SN75176 IC-vel tudassa mikor ő az adó. És persze kell hibadetektálás, hiba esetén adásismétlés, stb.

Ha tisztán I2C kell akkor továbbra is I2C buffer használatát javaslom. Bővebben: Link

SN75776 nincs. A vezetékvégeken lezáró ellenállás kell, csavart érpárnál ez kb. 120-150 Ohm
A hozzászólás módosítva: Nov 30, 2015
(#) dc001 válasza Gj hozzászólására (») Nov 30, 2015 /
 
Ez így biztos nem fog működni, pl.:
Az SN75176 RE lába invertált vagyis, ha +5V-ra kötöd azzal tiltod a R kimenetet, csak a D bement lesz aktív az összes buszmeghajtónál.
A másik gond a megoldásoddal, hogy bármely IC (AVR vagy szenzor) lehúzza a SDA vagy SCL vonalat és az adott buszmeghajtó épp H jelet ad kimenetén, akkor ott rövidzár lesz!

Amit esetleg ki lehetne próbálni: van egy egyszerű kapcsolás (mellékletben), amellyel 3,3v és 5v-os I2C-t lehet illeszteni. Ezt egy kicsit átvariálni úgy, hogy a 3,3v-os oldala néz az IC illetve az AVR felé, csak épp 3,3v helyett 5v-ra kötve, az 5v-os oldala van a busz fele, de pl. 12v-ra kötve. Ekkor kaphatsz egy 12v-on működő I2C.
(#) Gj válasza dc001 hozzászólására (») Nov 30, 2015 /
 
Ez egyirányú léptetést valósít meg, nem? A buszról jövő jeleket nem tudja fogadni. (Csak kérdezem, mert egyébként persze tudok belőle két irányút csinálni. Magam is agyaltam ilyesmin, csak optocsatikkal.) Milyen MOSFET-et lenne érdemes használni?

És nincs valami cél IC a csavart érpár hajtására, hogy akkor azon küldjem a 12V-os I2C-t?
Olyasmire gondolok, aminek beadok egy logikai szintet, ami ha 0, akkor a két kimenetén 0-t dob ki, ha pedig +5V, akkor egyik kimenetén +5V-t, másikon -5V-t ad ki, valamint van visszaalakító része, ami az érpár negatív ágát tükrözve és a két ágat összeadva kiejti a zavarjelet és ad nekem egy logikai alacsony, vagy magas szintet, amit egy másik ilyen IC-vel felküldtem az érpárra?
A hozzászólás módosítva: Nov 30, 2015
(#) kendre256 válasza Gj hozzászólására (») Dec 1, 2015 /
 
Amit zombee ajánlott ebben a hozzászólásban. annak az IC-jét megnézted?
A doksiban mindenféle példa van különböző távolságokra, sebességekre, lapos telefonkábelen, csavart érpáron, optocsatolóval leválasztott megoldásokra.
(#) zombee válasza Gj hozzászólására (») Dec 1, 2015 / 1
 
P82B96, ezt már több hozzászólásomban megemlítettem. Ez az a cél IC amit keresel!
Úgy működik mint a "rendes" I2C, csak az inaktív (HI) állapot kicsit gyengébben van meghajtva a csavart érpáron. Azaz az I2C busz bármelyik oldalán ha lehúzást (LO) tapasztal akkor a csavart érpár aktív állapotba kerül, és nem csinál rövidzárlatot. Jó hír hogy a "nagyfeszes" rész 5V-al is hajtható, de 10m-nél nagyobb távolságokra nagyobb meghajtófeszültség ajánlott.

Hasonlót meg lehet csinálni az RS-485 meghajtókkal is, csak nagyon sok körítés (diódák, fel/lehúzó ellenállások, komparátorok) kellenének mindkét oldalra. Ezt egyesíti a kétirányú cél IC.
A hozzászólás módosítva: Dec 1, 2015
(#) Gj válasza zombee hozzászólására (») Dec 1, 2015 /
 
Még egy kérdés, ez csak kíváncsiságból:

Ez az IC, ha jól értelmezem az adatlapot, nem a zavarkiejtéses, polaritásváltós módon dolgozik az érpáron, hanem az érpár egyik erén simán föld/"nagyfesz" fut a jel ér mellett.
Ez kevésbé hatékony módszer a jelalak mmegőrzésére, vagy rosszul gondolom?
(#) zombee válasza Gj hozzászólására (») Dec 1, 2015 /
 
Ahhoz amit Te mondasz, oldalanként kellene 4-4 darab SN75176 vagy MAX485, P82B96 meg csak 1.

Hatékonyság ide vagy oda, azt is nézni kell hogy egy ilyen egyszerű rendszer a klassikus polaritásváltásos módban zárlatot okozhat! A hatékonyságot az adja, hogy kis kapacitású csavart érpáron vagy sima telefonkábelen használod, nem koaxiális vezetéken, és a felhúzó ellenállás elég kicsi(~390Ohm) lehet. Azt is nézd, hogy 4 vezetéken nem csak az SCL/SDA jelet, hanem a (nagy)feszt is átvezeted, amivel táplálhatod a céláramkört is. Ez a rendszer tud 100-250m távolságot is, de csak kis sebességű(25-100kHz) módban, és a felhúzó ellenállásokat nagyon jól be kell lőni hogy a vezeték hullámimpedanciáját kiejtse.
A hozzászólás módosítva: Dec 1, 2015
(#) zombee válasza zombee hozzászólására (») Dec 2, 2015 /
 
Kb. erről beszélek (lásd: kép). Ez tényleg "hatékony", egy a baja hogy csak két végpont összekötésére alkalmas, elhasznál 8 vezetéket és 8 darab SN45176/MAX485 IC-t egy mezei I2C kapcsolathoz. Azaz egy UTP kábel már nem lesz elég ha tápot is át akarsz vinni(persze egy graetz csodákra képes). Aztán még jöhetnek rá védődiódák is(és akkor nem kell graetz).

A működés lényege hogy az I2C vonalon az adó és vevő részt szét kell szedni. A csavart érpáron a vevő részre bejövő alacsony-aktív jel az adót nem befolyásolhatja, különben reteszelődik a cucc. A vevő jeléből a D1 és D2 diódák lecsípnek kb. 1.4V-ot, ami elég T1 meghajtásához. T1 már ezen a kis feszültségkülönbségen sem engedi T2-nek hogy lehúzza az adó jelét. Ellenben, ha az SDA/SCL vonalon érkezik a lehúzás akkor T1 lezár, T2 kinyit és lehúzza az adó bemenetét. Megépíteni csak saját felelősségre...

Hasonló módon működnek az I2C izolátorok(pl. ADUM1250) meg a P82B96 is. Utóbbi csak egy 2 érpárt használ, és egyetlen IC-ben benne van minden ami kell!
A hozzászólás módosítva: Dec 2, 2015
(#) killbill válasza zombee hozzászólására (») Dec 2, 2015 /
 
Idézet:
„elhasznál 8 vezetéket és 8 darab SN45176/MAX485 IC-t”
Pazarlás a 8 IC, mert pl. a 75179 az pont 1 ado, 1 vevo. Abbol eleg lenne 4 db is.
Egyébként meg az egész topik (mármint az i2c hosszú dróton) egy rossz irany. Miert kell mindig mindent masra hasznalni, mint amire valo? Az I2C buszt keszuleken belulre talaltak ki, nem pedig arra, hogy hosszu meterekre elvigyek.
(#) zombee válasza killbill hozzászólására (») Dec 2, 2015 /
 
Az adó és vevő szétszedése egyetlen IC-vel jó ötlet, ezzel kétirányú UART-om is lehet egy IC-vel...

Idézet:
„Az I2C buszt keszuleken belulre talaltak ki, nem pedig arra, hogy hosszu meterekre elvigyek.”

Egész eddig ezt szajkóztam, ha egyszer nem érti akkor nem érti.
A hozzászólás módosítva: Dec 2, 2015
(#) killbill válasza zombee hozzászólására (») Dec 2, 2015 /
 
Idézet:
„Az adó és vevő szétszedése egyetlen IC-vel jó ötlet, ezzel kétirányú UART-om is lehet egy IC-vel...”
Igen, mivel erre való. Lásd még: RS-422.
(#) vyky hozzászólása Dec 3, 2015 /
 
Sziasztok.
Olyan kérdéssel fordulok hozzátok,hogy tud-e valaki egy kapcsolást amivel egy Atmega8 -at össze tudnék kötni a nyomtatóban lévő dc motorral amihez van enkodercsík.
Előre is köszönöm.
(#) fecus hozzászólása Dec 5, 2015 /
 
Azt szeretném leprogramozni, hogy az adatrögzítőm működjön 30 napig, a végén írja ki az adatot és egy flag-et az EEPROM-ba. Ezután hiába megy el a táp vagy resetel ne kezdjen semmit újra csak ha én kívülről törlöm a flag-et az EEPROM-ban. Azután viszont kezdjen új mérést ha bekapcsolom.
Hová kell tennem az EEPROM flag vizsgálatát és az attól függő iniciális beállításokat? A main-be vagy elé?
Pl. az alábbi változónak
  1. volatile int endcnt = 0x00;                                     // nincs vége a számolásnak

függenie kell az értékének attól, hogy az EEPROM-ban a flag mit mutat. Ettől függ az is hogy felengedem-e az IT-t.
(#) Droot válasza fecus hozzászólására (») Dec 5, 2015 /
 
Ha az eeprom-ban akarod tarolni, akkor ott tarold es pl a main-ben folyamatosan frissitsd. Pl a 0-as cimen tarolhatod.
Endcnt = eeprom_read_byte(0);
(#) Kovidivi válasza Droot hozzászólására (») Dec 5, 2015 /
 
Én inkább a indítás után 1x olvasnám be az eeprom tartalmát, utána csak a változót kell ellenőrizni. Az eeprom olvasás lassú művelet. A változó tartalma sem veszik el, csak ha elmegy a táp. Kell lennie egy inicializáló résznek, ez tuti, én oda szoktam az ilyen dolgokat pakolni. A frissítést kell átgondolni jól. Mennyi mért adat veszhet el, és még az eeprom se menjen tönkre. Pl. lehet 10percenként menteni, ekkor max. 10 percnyi adat veszik el, vagy ha elmegy az áram, akkor több időnyi. Ez csak 4320 db írás a 30nap alatt, tehát bőven lehetne csökkenteni a 10 percet, pl 1perc-cel 43200 írás, az is korrekt.
A hozzászólás módosítva: Dec 5, 2015
(#) fecus válasza Kovidivi hozzászólására (») Dec 5, 2015 /
 
Ez lesz az! Akkor a main elején megnézem az EEPROM-ot és ettől függően beállítok egy változót ami nem vész el csak reset vagy tápkimaradás esetén. Ha végzett a regisztráció akkor egyszer beírom a mért értéket meg a tiltás flag-et az EEPROM-ba .
Mivel a mérést meg lehet ismételni (lehet az elején csak egy hetet fogok mérni, próbából) csak mérési ciklusonként egyszer írom az EEPROM-ot.
Aksiról megy, nem lesz áramkimaradás (remélem). Inkább azt kell védenem, hogy a végén nehogy véletlen újrainduláskor elrontsa az értéket.
(#) Kovidivi válasza fecus hozzászólására (») Dec 5, 2015 /
 
Arra vigyázz, nehogy valami induktív fogyasztó a közelben újraindítsa a procit, főleg ne eeprom írás közben, ezért is jobb, ha kicsit ritkábban írod. Ha a programod jó, és nem használsz ismeretlen külső könyvtárakat, akkor nem lesz gondod a lefagyással. Ha mégis félsz ettől, akkor watchdog timer-t bekonfigurálod.
(#) Auf hozzászólása Dec 6, 2015 /
 
Sziasztok!

Assembly-ben atmega 128 -nál ezt a hibaüzenetet kapom, és nem tudom miért.

../kieg.s:37: Error: bad expression
../kieg.s:37: Error: garbage at end of line

  1. pop             temp
  2.         out             SREG,temp
  3.         cbi             PORTA, 0


Az out parancs sora a 37-es sor.

Mivel lehetne ezt kijavítani?
Köszönöm előre is.
A hozzászólás módosítva: Dec 6, 2015
(#) kapu48 válasza Auf hozzászólására (») Dec 6, 2015 /
 
Szerintem az SREG memoria cimen van.

Próbáld memoriaként kezelni!
(#) kapu48 válasza Auf hozzászólására (») Dec 6, 2015 /
 
29. Register Summary:
Address Name
$3F ($5F) SREG

vagy: out $5F,temp
(#) zombee válasza kapu48 hozzászólására (») Dec 6, 2015 / 1
 
Biztosan nem ez lesz a fő gond! Az SREG mindig az I/O tartomány legfelső bájtja ($3F) helyen áll, és ez ATMega128-ra is igaz. Szerintem itt a temp definíciójával lesz a gond, vagy a fordító rosszul írja ki a hibás sort(volt már ilyen).

Csak próbaképp ezt az asm kódot adtam meg Studio-ban, gond nélkül megette:
  1. .include "m128def.inc"
  2. pop          r16
  3. out          SREG,r16
  4. cbi          PORTB, 0


Azért r16 (és nem temp) nert nem vesződtem annak definíciójával. Próbáld te is lecserélni!
A hozzászólás módosítva: Dec 6, 2015
Következő: »»   709 / 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