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   540 / 839
(#) kurosaki hozzászólása Jún 9, 2013 /
 
Üdv ismét én.
Ezernyi doksit átrágtam ADC vel kapcsolatban is.Letöltöttem más által "irt" egyszerű kódokat(Programozható led) gondoltam na végre ebből kitudom szedni ami kell de tévedtem.Szimplán egy kód kéne amivel az Attiny45 el egy LDR tudok fényviszonyhoz megfelelő ledet tudok bekapcsolni (később más szerepet szánok) de még ez se jön össze.Egy nagy gurut kérnék meg hogy egy kicsit segítsen az elindulásban már ha nem nagy kérés sehol-se találok csak is arduino hoz való kódot (ami épp azt teszi ami nekem kéne LED et kapcsol-be ha sötét van) de hát nem arduino-m van.Köszönöm előre is.Csak egy apró löket kéne akár doksi(de ne ADC mert mar a fülemen jön ki).
(#) kapu48 válasza kurosaki hozzászólására (») Jún 10, 2013 /
 
Bascom program jó lessz?
  1. $crystal = 14745600                                         'Sebesseg
  2. $regfile = "ATtiny45.DAT"                                   'Chip
  3.  
  4.  
  5. $swstack = 32
  6. $hwstack = 32
  7. $framesize = 40
  8.  
  9. 'Pinout ATtiny25/45/85
  10. '1.: (PCINT5/RESET/ADC0/dW) PB5
  11. '2.: (PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3
  12. '3.: (PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4
  13. '4.: GND
  14.  
  15. '8.: VCC
  16. '7.: PB2 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2)
  17. '6.: PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1)
  18. '5.: PB0 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0)
  19.  
  20. 'Fotoelem
  21. Config Adc = Single , Prescaler = Auto , Reference = Internal_2.56_nocap
  22.  
  23.  
  24. Config Portb.5 = Input                                      'ADC0   'Fotoelem
  25. 'Config Portb.2 = Input 'ADC1
  26.  
  27. Config Portb.3 = Output                                     'LED a PortB.3
  28.  
  29. Dim  Fenyelem As Word
  30.  
  31. Do
  32.   Start Adc
  33.   Waitms 10
  34.   Fenyelem = Getadc(0)
  35.   If Fenyelem > 120 then
  36.      Set Portb.3                                           'LED Be
  37.    else
  38.       Reset Portb.3                                         'LED Ki
  39.   end if
  40.  
  41.   Stop Adc
  42.   Waitms 200
  43. Loop
  44.  
  45. End
A hozzászólás módosítva: Jún 10, 2013
(#) kurosaki válasza kapu48 hozzászólására (») Jún 10, 2013 /
 
Atmel studio 6.1 et hasznhalok C vagy Assembler bascomot mivel tudom felhasználni??
(#) csabeszq válasza kurosaki hozzászólására (») Jún 10, 2013 /
 
Pedig érdemesebb az ADC-t gyúrni, mint trimmerrel és műveleti erősítőkkel ökörködni. Szerintem egy kapcsolásnál ne az döntsön, hogy mit tudsz most megcsinálni, hanem az, hogy hogyan érdemes. Itt pedig ha 10 embert megkérdezel, 10 ADC-t fog javasolni.

Ha már úgyis ott a mikrokontroller, akkor azzal mérsz. Ha nincs mikrokontroller, akkor OPAMP.

Én megvettem egy fényérzékeny ellenállást, ami normál fényviszonyok között 2k. Vele sorosan kötöttem másik 2k-t a 0 és 5V közé, a két ellenállás közti feszültséget mérem ADC-vel. A hardver az két ellenállás és egy 100nF-es kondi az AREF és a föld közé. Ha pontosan akarsz mérni, akkor az AVCC-re 30mH induktivitás és 100nF utána a fölre. Ennyire bonyolult.

Persze szórakozhatsz LM324-essel, schmitt triggert csinálsz belőle, amit trimmerekkel hangolsz. Ezt is csináltam már, de ha van mikrokontroller, akkor nem fogok idétlenkedni.
(#) kurosaki válasza csabeszq hozzászólására (») Jún 10, 2013 /
 
Igen tudom mert énis megépitettem BC447 (asszem msot nem vagyok biztos benne) Ledet kapcsolja(full sötétben teljesen világit stb) csak nekem "programozható" rész kell mert az kis-seb is meg stb ezért is döntöttem az AVR mellet mert van csak nem értem azt a részét oké hogy az ADC részét megírom csak a lekérdezés és használatát nemértem. Mármint Megelégednék hogy Éjszaka(ON fénynél meg OFF) a szerkezet egyenlőre de este tudom megírni mert nekem túl komplikált.Nem találok leírást ehhez csak is bonyolult exampleket.
(#) kapu48 válasza kurosaki hozzászólására (») Jún 10, 2013 /
 
Panaszkodtál, hogy a GCC túl bonyolult és nem érted, a regiszterek közvetlen programozását!
Ezért javasoltam a Bascomot! Jóval 1*űbb, Elvégzi helyetted a Regiszterek beállítását.

Bascom könyv hu.
(#) kurosaki válasza kapu48 hozzászólására (») Jún 10, 2013 /
 
Igen látom hogy könnyebb müködik is úgyhogy köszönöm.Csak C után fura nem tom h ültetem át a RGB ledet most gondolkoznom kell de köszönöm .
A hozzászólás módosítva: Jún 10, 2013
(#) kapu48 válasza kurosaki hozzászólására (») Jún 10, 2013 /
 
Vagy van C-ben az oldal alján 1 szép megoldás:
ATtiny45 ADC

Tanulni kel és gyakorolni!
A hozzászólás módosítva: Jún 10, 2013
(#) csabeszq válasza kapu48 hozzászólására (») Jún 10, 2013 /
 
Kapu48, szerintem ha az ADC 120 fölött van, akkor bekapcsoljuk a LED-et.

Sötétedik, az ADC eléri a 120-at: bekapcsoljuk a LED-et, a LED fényétől hirtelen "világos lesz", 119-re visszaesik, ennél fogva kikapcsoljuk a LED-et, akkor meg megint sötét lesz...

Nem így szokták megoldani és szerintem a szürkületi ki-be kapcsolgatás igencsak zavaró tud lenni. Ahogy jönnek, mennek a felhők, úgy fog kapcsolni.

Nálam a kikapcs, bekapcs között az ADC-n 64 fok különbség van. Ha 544-nél bekapcsol, akkor 480-nál fog kikapcsolni. Ez az a szint, ami nálam már elfogadható és tényleg sötétben kapcsol be és világosnál kapcsol ki, ahogy az életben is működik.
A hozzászólás módosítva: Jún 10, 2013
(#) kapu48 válasza csabeszq hozzászólására (») Jún 10, 2013 /
 
Mert nem olvasol vissza! A kérdező éjel/napali fényváltozásra akar valami ki/be kapcsolót!

Én vázoltam egy megoldást, minden részletes kidolgozás nélkül.
Mivel még a HW részletezése sem lett ismertetve!
Ezért, hogy milyen szinten kapcsol az megoldandó feladat maradt!

És honnan veszed hogy a LED vezérli a Napot?
A hozzászólás módosítva: Jún 10, 2013
(#) csabeszq válasza kapu48 hozzászólására (») Jún 10, 2013 /
 
Hát, a fényérzékeny ellenállásra nincs ráírva, hogy kizárólag a napot érzékeli.



Amikor LED-es zseblámpával telibekapom az ellenállást, észleli. Nem kell megsértődni, viccnek szántam az előző hozzászólást. Mindenesetre a ki-be kapcsolás független attól, hogy reggel van-e vagy este.

  1. if( adc > 130 )
  2.      led_be();
  3. else if( adc < 110 )
  4.      led_ki();
  5. else
  6.      /* ne csinalj semmit */ ;
A hozzászólás módosítva: Jún 10, 2013
(#) kapu48 válasza csabeszq hozzászólására (») Jún 10, 2013 /
 
(Lehetne még bonyolítani a programot. De az ATtiny-nak kevés a memóriája, és kelhet még más feladatra is!)
A hozzászólás módosítva: Jún 10, 2013
(#) TavIR-AVR válasza kapu48 hozzászólására (») Jún 10, 2013 /
 
Nem volt szó hiszterézisről (szürkületi átmenet), hirtelen fényerőingadozásról (villámlás, belevilágítás), a felkapcsolt fény kereszthatásáról....
De lehet belső óra is és GPS óraszinkronnal...

Tulajdonképp a feladat definíciója igen hiányos. Kapu48 adott egy _kiindulási_ alapot, amit el lehet bonyolítani. Végülis mehet 8k-n túlra is a kód és akkor a Tiny85 már kicsi lesz...
(#) csabeszq válasza TavIR-AVR hozzászólására (») Jún 10, 2013 /
 
Ezt személyesen kipróbáltam és agybajt kaptam tőle, de lehet hogy másokat nem zavar.
Amikor jött a szürkület, akkor össze-vissza kapcsolt ide-oda mindenféle szabály nélkül, hol villódzott, hol másodpercekig 1 volt utána 0.

Az említett módosításom valóban több erőforrást igényel, mert 4 byte-tal megtolja a végleges lefodított kódméretet. Ha nem maradt még 4 bájtod az attiny-n (CPI és BRLT), akkor én is azt javaslom, hogy ne tedd bele.
(#) kapu48 válasza csabeszq hozzászólására (») Jún 10, 2013 /
 
Lehet, hogy szükség van hiszterézisre? Én nem próbáltam!
Itt a hsz-ed modortalanságáról van szó!

És ne keverj Bascomos programba C sorokat!
A hozzászólás módosítva: Jún 10, 2013
(#) Sick-Bastard hozzászólása Jún 10, 2013 / 1
 
Üdv!
Itt a mai rejtvényem
  1. int main(void)
  2. {
  3. _delay_ms(1000);
  4.  
  5. SPI_Init();
  6. Init_GIC();
  7.  
  8. Init_MCP23S17(LCD);
  9. _delay_ms(100);
  10. Init_LCD();
  11. _delay_ms(1000);
  12.        
  13.         while(1)
  14.         {
  15.                 if(count == 0x01)
  16.                 {
  17.                         GoTo(0,0);
  18.                         Send_String("Mo");
  19.                        
  20.                         itoa(count,StringCO,10);
  21.                         GoTo(0,1);
  22.                         Send_String(StringCO);
  23.                         Send_String(" ");
  24.                         itoa(KeyPad[1],StringCO,10);
  25.                         Send_String(StringCO);
  26.                         _delay_ms(2000);
  27.                 }
  28.                 if(count == 0x02)
  29.                 {
  30.                         itoa(count,StringCO,10);
  31.                         GoTo(0,1);
  32.                         Send_String(StringCO);
  33.                         Send_String(" ");
  34.                         itoa(KeyPad[1],StringCO,10);
  35.                         Send_String(StringCO);
  36.                        
  37.                         for(int x=0;x<128;x++)
  38.                         {
  39.                                 GoTo(0,0);
  40.                                 Send_String("x");
  41.                                 itoa(x,StringCO,10);
  42.                                 GoTo(1,1);
  43.                                 Send_String(StringCO);
  44.                                 _delay_ms(2000);
  45.                                 GoTo(0,0);
  46.                                 Send_String(" ");
  47.                         }
  48.                        
  49.                 }
  50.                 else
  51.                 {
  52.                         itoa(count,StringCO,10);
  53.                         GoTo(0,1);
  54.                         Send_String(StringCO);
  55.                         Send_String(" ");
  56.                         itoa(KeyPad[1],StringCO,10);
  57.                         Send_String(StringCO);
  58.                         _delay_ms(2000);
  59.                 }
  60.         }
  61. }
  62.  
  63. ISR(INT0_vect)
  64. {
  65.         _delay_ms(100);                                         //prell
  66.         KeyPad[1] = MCPRD(LCD, INTCAPA);
  67.         KeyPad[1] = (KeyPad[1]&0x03);
  68.         if(KeyPad[1] == 0x01)
  69.         {
  70.                 count--;
  71.         }
  72.         if(KeyPad[1] == 0x02)
  73.         {
  74.                 count++;
  75.         }
  76. }


A problémám, hogy a count változóm csak 1 és 0 között változik. Nem tudom 1 fölé emelni. Szóval úgy néz ki a gombok működnek, de csak oda-vissza. pl.:0->1->0->1->1->1->0...

Még egy érdekesség:
Ha a count---t felcserélem a count++-al, akkor csak 1x tudom 1re változtatni, de 0ra már vissza nem és 1 fölé szintén nem megy.
(#) resystance válasza Sick-Bastard hozzászólására (») Jún 11, 2013 /
 
Ezt a nyelvet nem ismerem, de pár másikat igen. Szerintem a 70. sor csinálja. Kommenteld ki és nézd meg úgy.
(#) zombee válasza Sick-Bastard hozzászólására (») Jún 11, 2013 /
 
Ön itt volt az elmúlt fél évben? A fórumban már nagyon sokszor felmerült, és a legjobb hogy a fejlécre is kikerült:
Idézet:
„1. Ha ISR-ben használsz globális változót, az legyen "volatile"”
(#) csabeszq válasza zombee hozzászólására (») Jún 11, 2013 /
 
Ezt néha még a tapasztaltak is elrontják.

Alapvetően nem rajongok a volatile-ért, mert jelentősen növeli a program méretét.
Mindenegyes változó esetén át kell gondolni, hogy kell-e a volatile, vagy fölöslegesen pazaroljuk vele a memóriát.

Csak oda kell, amit a főprogram és valamelyik interrupt egyszerre használnak. Ha csak a főprogram / csak az interrupt / több interrupt egyszerre használja, akkor nem kell.
A hozzászólás módosítva: Jún 11, 2013
(#) Sick-Bastard válasza zombee hozzászólására (») Jún 11, 2013 /
 
Igen az ISR-ben és a főprogramban használt változóim:
  1. volatile unsigned char KeyPad[] = {};
  2. volatile unsigned char count = 0x00;


Ahogy elképzeltem:
Amint megnyomom az egyik gombot a kettőből, amik egy MCP23S17-re vannak kötve, az küld egy interrupt jelet az AVR-nek. Az ISR rutin először vár 100ms-ek (sok, de ez a software-es anti-prell), majd kiolvassa az MCP INCTAPA regiszterben található értékeket és a KeyPad[1]-be menti. Mivel az INTCAPA-ban 6 másik bit van, ami kimenetként funkcionál, így azoknak az értéke nem kell, ezért jön a
  1. KeyPad[1] = (KeyPad[1]&0x03);
kód.
Mivel mindig csak 1 gombot nyomok le, ezért az új KeyPad[1] értéke csak 0x01 vagy 0x02 lehetne vagy itt tévedek?

SB
(#) csabeszq válasza Sick-Bastard hozzászólására (») Jún 11, 2013 /
 
  1. volatile unsigned char KeyPad[] = {};


Kicsit zavarba jöttem. Lefoglalsz egy nulla méretű tömböt, amit beraksz a KeyPad pointerbe.
Ezután a KeyPad[1]-et használod.

Ez gyakorlatilag annyit jelent, hogy a countot simán felülvághatod a KeyPad[1] írásánál, de mást is, attól függően, hogy a fordító hová tette a 0 méretű tömbödet.
(#) kapu48 válasza Sick-Bastard hozzászólására (») Jún 11, 2013 /
 
Elfelejteted lekapcsolni a megszakítás kezelés végén a GIFR regisztert!

Ezért a Prel hatására közben eltárolt INT kérés aktív maradt, és lesz 1 felesleges megszakításod.
Aminek már bizonytalan az eredménye!
(#) csabeszq válasza csabeszq hozzászólására (») Jún 11, 2013 /
 
GCC-ben próbáld ki, a count értéke 0 helyett 12(!) lesz:

  1. #include <stdio.h>
  2.  
  3. unsigned char KeyPad[] = {};
  4. unsigned char count = 0;
  5.  
  6. main()
  7. {
  8.   KeyPad[1] = 12;
  9.   printf("%d", count);
  10. }


A javítás:
  1. unsigned char KeyPad[] = {0,0};
(#) Sick-Bastard válasza kapu48 hozzászólására (») Jún 11, 2013 /
 
A Prel nem közvetlen az AVR INT lábánál jelenik meg hanem az MCP23S17 adott bemenetén. Neki, meg mind1, hogy hány megszakítás lép életbe(mennyit is ugrál a gomb). Addig küldi az AVR-nek a megszakítás jelet, amíg ki nem olvasom vagy az INCTAP vagy a GPIO regisztert. Mivel ennek a kiolvasását az AVR gyorsan elvégzi, ezért ha nem lenne ott a 100ms-es késleltetés, akkor ~30-40x kapna az AVR az MCP-től egy megszakítást. Ezt le is teszteltem, valamikor a múlthéten.

A GIF Regiszterben az INTF nem áll vissza automatikusan magától?
Idézet:
„...The flag is cleared when the interrupt routine is executed. ...”
(#) csabeszq válasza Sick-Bastard hozzászólására (») Jún 11, 2013 /
 
1. az interrupt flag Atmega48 alatt törlődik az interrupt meghívásakor, a többi chipet nem ismerem. (GIFR nincs is Atmega48 alatt)
2. interruptban ne használj delay-t, sok bajod lehet még belőle. Amíg te az interruptban vagy, addig sem más interrupt, sem a főszál nem hívódhat meg. A rendszer áll és vár. Ha a sleep a főszálban lenne, akkor simán tudnál még UART-olni, ADC-zni, timer megszakítást használni,...
A hozzászólás módosítva: Jún 11, 2013
(#) kapu48 válasza csabeszq hozzászólására (») Jún 11, 2013 /
 
Van az! Csak más a neve: EIFR – External Interrupt Flag Register!
(Ilyen egyszerű)

Szóval én azért megpróbálnám!
(#) kapu48 válasza Sick-Bastard hozzászólására (») Jún 11, 2013 /
 
Itt olvasd el a Prell részt:
Megszakítások Interrupt

Igaz ez Bascom de mégis csak AVR.

atmega48.pdf
A hozzászólás módosítva: Jún 11, 2013
(#) csabeszq válasza kapu48 hozzászólására (») Jún 11, 2013 /
 
Érdekes, hogy a cikk is azt írja, hogy prell ellen tegyél sleepet a megszakításba. Ezzel viszont az UART-ot garantáltan kinyírod, TWI az jobb, mert az összes IC a buszon megvár téged, amíg sleepelsz, de egyéb baj nem lesz.

Ahogy én csinálom: 2ms-enként timer interrupt, ott a sok egyéb dolog mellett a billentyűket is kiolvasom. Ha megváltozott, akkor elindítok egy számlálót és a következő 30 timer interruptban nem olvasom ki.

Emellett az IC dumál UART-on a számítógéppel, TWI-n a többi IC-vel, dolgozza fel az eseményeket,...
(#) zombee válasza csabeszq hozzászólására (») Jún 11, 2013 /
 
A prell ellen sokféleképpen lehet védekezni. Az már elég korrekt, ha lenyomáskor a megszakításban letiltod a saját megszakítását, elindítasz egy időzítőt, és az időzítő megszakításában újra engedélyezed a nyomógombot. Ennél egy fokkal jobb, ha nem letiltod, hanem az irányát fordítod meg - tehát felengedéskor újabb megszakítást eredményez. Az időzítő megszakítása pedig az érdemi munkát végzi(pl. változó beállítása), de csak akkor, ha addig a felengedésre nem érkezett megszakítás. Ez a módszer azért jó, mert megköveteli a stabil lenyomást X ideig, hátránya hogy ugyanennyit késni fog a "hatás" is.
A hozzászólás módosítva: Jún 11, 2013
(#) fecus hozzászólása Jún 12, 2013 /
 
Attiny44A-val készítettem a tápomhoz egy mérőműszert. Egyszerű cucc indikálásra. A gond, hogy ha a két adc bemenetét a földre kötöm a kijelzett érték akkor sem 0 hanem 6.
  1. void InitADC(void)
  2.         {
  3.                 // REFS2=1 REFS1=1 REFS0=0 Internal 1,1V Voltage Reference without external bypass capacitor, disconnected from PA0 (AREF).
  4.  
  5.                 ADMUX |= ( ( 1 << REFS1 ) );
  6.                
  7.                 // ADC enable and clock divide 8MHz by 64 for 125khz sample rate
  8.                 ADCSRA |= ( ( 1 << ADEN ) | ( 1 << ADPS1 ) | ( 1 << ADPS2 ) );
  9.                
  10.                 // ADLAR=0 jobbra mind a 10 bitet használom           
  11.                 ADCSRB |= ( ( 1 << ADEN ) | ( 1 << ADPS1 ) | ( 1 << ADPS2 ) );
  12.                
  13.                 // disable digital input on analog input channel to conserve power
  14.                 DIDR0 |= ( ( 1 << ADC4D ) | ( 1 << ADC7D ) );
  15.         }

A számítás egyszerű: a max bemeneti fesz és áram esetén a mért érték 900. Ezt 3-mal osztva épp 300. A táp max feszültsége 30V árama 3A.
Ebből következik, hogy a 0 helyett 3*6=18 a zéró érték.
Mi lehet a baj? Lehet a belső ADC-nek fix offsete? Elég kivonnom a 18-at és kész?
A kijelző algoritmus jó, mert a mért érték helyett 0-t írva szép 0 lesz a számítások és kijelzés után.
A 6 nem változik, nem zavar.
A hozzászólás módosítva: Jún 12, 2013
Következő: »»   540 / 839
Bejelentkezés

Belépés

Hirdetés
XDT.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