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   674 / 837
(#) Kovidivi válasza Droot hozzászólására (») Jún 18, 2015 /
 
Szia. Köszi a tippet. A takarítás nehézkes, mert pókháló a szerelés, nagyon kis helyre bezsúfolva. Először kipróbálom a kódot másik AVR-en, nehogy a kód legyen rossz. Utána egyesével leszedem a lábakról a vezetékeket, hátha ott lesz gond. Ha mindet leszedtem, és még mindig sok a felvett áram, akkor pedig jön az IC csere...
De lehetséges egyáltalán, hogy a hősokktól egy periféria zárlatos lesz? Úgy már jártam, hogy egy 100nF smd kondi zárlatos lett, úgyhogy el tudom képzelni... Ma este úgyis kiderül
(#) Kovidivi válasza mbalint1 hozzászólására (») Jún 18, 2015 /
 
Próbáltad már ArduinoISP-vel felrakni csak simán a .hex-et bootloader nélkül? Minek kell a bootloader, ha van kész .hex-ed?
(#) mbalint1 hozzászólása Jún 18, 2015 /
 
Igen próbáltam, de úgy se megy. Azt olvastam így kell beállítani 8Mhz-re.
(#) kapu48 válasza mbalint1 hozzászólására (») Jún 18, 2015 /
 
És ezt a tanácsot megfogadtat?: „You’ll need the Arduino software (version 1.0.1 or 0022). Installation”
(#) k3gy3tl3n hozzászólása Jún 18, 2015 /
 
Sziasztok, lenne egy bugyuta kérdésem. Építettem egy hajót aminek a motorját pwm-mel vezérlem N-channel fet + AVR. A biztonság kedvéért tettem be diódát, hogy megvédjem az áramkört, viszont a 0.7V fesz esés észrevehető a motoron (kicsit lassabb). Szóval a kérdés: ha párhuzamosan rakok több diódát azzal csökkenthetek a feszültség esésen? Vagy csak az áramkört hagyjam a dióda mögött, de a motor tápot vegyem a dióda elől, közvetlenül az akkuról?
(#) Kovidivi válasza k3gy3tl3n hozzászólására (») Jún 18, 2015 / 1
 
Vagy a diódát cseréld ki FET-re, ami csak akkor vezet, ha jó a polaritás. Akkor minimálos lesz a fesz. esés. Bővebben: Link
(#) k3gy3tl3n válasza Kovidivi hozzászólására (») Jún 18, 2015 /
 
Köszi a gyors választ!
(#) Droot válasza Kovidivi hozzászólására (») Jún 18, 2015 /
 
Minden lehetséges.
Vagy a hősokktól (egy alkatrészt sem forrasztunk 15 percig) vagy pedig a "pókhálótól" nőtt meg az áramfogyasztás.
Feleslegesen próbálod ki másik avr-el, nem fog többet fogyasztani szerintem.
Azt próbáld meg inkább hogy pl a proci hex fájl nélkül mennyit fogyaszt, egy portlábat billegtetve mennyit fogyaszt.
(#) Kovidivi válasza Droot hozzászólására (») Jún 19, 2015 /
 
Megtörtént a csere, mert az alvó program volt az IC-ben, minde lába szabad volt, kivéve a tápláb, és 10mA-t vett fel. Nem gond, mert így sokkal szebb lett a pókháló V2 Egyszerűbben javítható, átlátható. A másik IC pedig jó lesz olyan tesztekre, mint LED-et hajtani nagyon rövid impulzusokkal, előtét ellenállás nélkül, két kimeneti láb rövidzárlata, stb. Most is volt érdekes: sleep módban minden PORT kimenet, méghozzá magas szinten, kapcsoló pedig GND-re húzta le (normál esetben a belső felhúzó ellenállást), néztem is, hogy miért folyt 40mA mikor nyomom a gombot... Annak a kimenetnek persze semmi baja nem lett Jó strapabíró ez az Atmega328!
(#) Max26 hozzászólása Jún 19, 2015 /
 
Sziasztok!

Az alábbi kód: Pergésmentesítés 4x4-es gombmátrixra. Csakhogy a kikommentált sorok nem működnek. A pergésmentesítést az oszlopokra szánnám mégis csak a 4. sorban levő (* 0 # D) elemekre működik. Van valakinek ötlete miért nem funkcionál a pergésmentesítés a többi nyomógomba?

Bővebben: Link
(#) kapu48 válasza Max26 hozzászólására (») Jún 19, 2015 /
 
Ez a sor várja meg, hogy felenged a billentyűt: while(!(PINC&(1<<OSZLOP2)));

Viszont ha „//” jeleket raksz eléje, akkor a fordító csak megjegyzésnek értelmezi!
És nem kerül bele a kódba: //while(!(PINC&(1<<OSZLOP1))); // ??????????????
(#) csabeszq válasza Kovidivi hozzászólására (») Jún 19, 2015 /
 
Ezek így vannak tervezve. Én UART-nál rendre felcserélem, hogy melyik az RX, melyik a TX, mégsem mennek tönkre. A logikai jeleket általában tetszőlegesen be lehet kötni, legfeljebb sokat fogyasztanak.

Idáig logikai jelek félrekötése miatt nem ment nálam tönkre semilyen hardver.
(#) csabeszq válasza kapu48 hozzászólására (») Jún 19, 2015 /
 
Mondjuk pergésmentesítést while ciklussal ebben a formában nem lehet csinálni.

Én azt szoktam csinálni:
- ha le van nyomva, akkor tovább küldöm, hogy 1
- ha nincs lenyomva, de az elmúlt 30ms alatt le volt nyomva legalább egyszer, akkor 1
- ha nincs lenyomva és a megelőző 30ms alatt sem volt lenyomva, akkor 0

Ebben a formában a lenyomást azonnal érzékeli, a felengedést 30 ms múlva. Persze fordítani is lehet.
(#) kapu48 válasza csabeszq hozzászólására (») Jún 19, 2015 /
 
Ezt mért nekem íród?

A fenti program részletet nem én írtam!
Csak észrevételeztem, hogy mért mükszik az 0, 10, 11 és 15-ös gombnál, többinél meg nem!

Imádom, hogy minden HSZ-embe bele kötsz! Tán nem tetszik, hogy én is létezem?
A hozzászólás módosítva: Jún 19, 2015
(#) csabeszq válasza kapu48 hozzászólására (») Jún 19, 2015 /
 
Nem akartam kötekedni, csak leírtam, hogy nem fog működni. Rólad tudom, hogy képes vagy működőképes pergésmentesítő algoritmust írni.

Igazából nem neked szólt a hozzászólás. Arról szól, hogy ebben a formában while ciklussal nem hiszem, hogy menne, semmi értelme sincs.
A hozzászólás módosítva: Jún 19, 2015
(#) kapu48 válasza csabeszq hozzászólására (») Jún 19, 2015 /
 
Az előtte meghívót, rutint nem közölték: keypad=keypad_beolvas(); ???

Ha az jól van, megírva még működhet is!(A kérdező állítása szerint is működik a fele billentyűzet)
(#) Max26 válasza kapu48 hozzászólására (») Jún 19, 2015 /
 
Azt pontosan tudom, de azért kommenteltem ki, mert azokra nem erényesül a pergésmentesítés. Ellenben azokra, amiket bent hagytam (komment nélkül) érvényesül a pergésmentesítés.
Tehát a *#0D-re működik. A kérdésem: Miért nem működik a pergésmentesítés a többi nyomógombra, ha nincsenek kikommentelve a hozzájuk tartozó while(!PINC&(1<<OSZLOPx)));?
(#) killbill válasza Max26 hozzászólására (») Jún 19, 2015 /
 
A kerdes jo. Lehet, hogy nem megfelelo bitet vizsgalsz azokon a helyeken, ahol nem mukodik. Nem latjuk a keypad_beolvas() fuggvenyt.

De ettol fuggetlenul ezt az egeszet nem igy kellene megcsnalni. Miert kell 15 helyen elvegezni pontosan ugyanazt a feladatot? Ha mar mindenkeppen ugy akarsz pergesmentesiteni, hogy egy lenyomast kovetoen megvarod, amig felengedik es utana meg meg is allitod a processzort, akkor azt csinald meg egy helyen:
  1. for(;;){                                // while(1) helyett...
  2.   keypad = keypad_beolvas();
  3.  
  4.   if(keypad != 0xff){                   // valamit benyomtak
  5.     while(keypad_beolvas() != 0xff);    // megvarjuk, amig felengedik
  6.     _delay_ms(PERGES);                 // kesleltetes
  7.  
  8.     switch(keypad){                    // feldolgozas
  9.     ...
  10.     }
  11.   }
  12. }
(#) Max26 válasza killbill hozzászólására (») Jún 19, 2015 /
 
Rendben, köszönöm. A keypad_beolvas() tartalma:

  1. unsigned char keypad_beolvas(void)
  2. {
  3.         unsigned char keypad_input=0xff,keypad_output=0xff;
  4.         KEYPAD_PORT=0xfe;
  5.         _delay_us(2);
  6.         keypad_input=KEYPAD_PIN & 0xf0;
  7.  
  8.         if(keypad_input==0xe0)
  9.                 keypad_output=0x01;
  10.         else if(keypad_input==0xd0)
  11.                 keypad_output=0x02;
  12.         else if(keypad_input==0xb0)
  13.                 keypad_output=0x03;
  14.         else if(keypad_input==0x70)
  15.                 keypad_output=0x0c;
  16.         else
  17.                 ;
  18.  
  19.         KEYPAD_PORT=0xfd;
  20.         _delay_us(2);
  21.         keypad_input=KEYPAD_PIN & 0xf0;
  22.  
  23.         if(keypad_input==0xe0)
  24.                 keypad_output=0x04;
  25.         else if(keypad_input==0xd0)
  26.                 keypad_output=0x05;
  27.         else if(keypad_input==0xb0)
  28.                 keypad_output=0x06;
  29.         else if(keypad_input==0x70)
  30.                 keypad_output=0x0d;
  31.         else
  32.                 ;
  33.  
  34.         KEYPAD_PORT=0xfb;
  35.         _delay_us(2);
  36.         keypad_input=KEYPAD_PIN & 0xf0;
  37.  
  38.         if(keypad_input==0xe0)
  39.                 keypad_output=0x07;
  40.         else if(keypad_input==0xd0)
  41.                 keypad_output=0x08;
  42.         else if(keypad_input==0xb0)
  43.                 keypad_output=0x09;
  44.         else if(keypad_input==0x70)
  45.                 keypad_output=0x0e;
  46.         else
  47.                 ;              
  48.                
  49.         KEYPAD_PORT=0xf7;
  50.         _delay_us(2);
  51.         keypad_input=KEYPAD_PIN & 0xf0;
  52.  
  53.         if(keypad_input==0xe0)
  54.                 keypad_output=0x0a;
  55.         else if(keypad_input==0xd0)
  56.                 keypad_output=0x00;
  57.         else if(keypad_input==0xb0)
  58.                 keypad_output=0x0b;
  59.         else if(keypad_input==0x70)
  60.                 keypad_output=0x0f;
  61.         else
  62.                 ;
  63.         return keypad_output;
  64. }
(#) mpetrooo hozzászólása Jún 22, 2015 /
 
Üdv, vettem egy RTC modult, de egyszerűen nem tudom működésre bírni. Nemtudom hogy hol lehet a probléma. Atmega8-at használok a beépített 1MHz-s órajellel. Az i2c jeleket 1,5kOhm-os ellenállásokkal húzom fel, és az i2c órajel 100MHz-s (elméletileg), mellékelem a kódot hátha meglátjátok hogy mi a gond. Per pillanat arra szeretném használni, hogy 1Hz-s órajelet adjon, és ezzel okoz interruptot az int0 bemeneten. Lehetséges, hogy a hiba az i2c protkolban van, mert az én próbáltam megírni.
Amikor kiszámolja a TWBR értékét a "((F_CPU/F_SCL)-16)/2" képlettel, akkor negatív szám jön ki, ami unsignedbe 250 körüli szám, amit visszaírva a képletbe mint pozitív akkor nem jön ki az 100kHz, akkor mégis hogyan kéne számolni ?

main.c:
  1. #define RTC_WRITE_ADD 0xD0
  2. #define RTC_READ_ADD 0xD1
  3.  
  4.  
  5. int main(void)
  6. {
  7.         shift_reg_init();
  8.         shift_reg_byte_out(~1);
  9.         shift_reg_byte_out(~1);
  10.         shift_reg_byte_out(~1);
  11.         shift_reg_byte_out(~1);
  12.         _delay_ms(1000);
  13.         //beállítjuk az órajelet az rtc-n
  14.         i2c_init();
  15.        
  16.         i2c_start();
  17.         i2c_sendaddr(RTC_WRITE_ADD);
  18.         i2c_write(0x07); //control regiszter
  19.         i2c_write(0b00010000); //ezzel kapcsoljuk be az 1 Hz-es órajelet
  20.         i2c_stop();
  21.         i2c_start();
  22.         i2c_sendaddr(RTC_WRITE_ADD);
  23.         i2c_write(0x00);   //másodperc regiszter
  24.         if(i2c_write(0b10000000)) //bekapcsoljuk az rtc oszcillátorát
  25.                 ;
  26.         i2c_stop();
  27.        
  28.        
  29.  
  30.  
  31.         //beállítjuk az interruptot  
  32.  
  33.         initInterrupt();
  34.  
  35.  
  36.  
  37.         while(1)         
  38.         {
  39.        
  40.                
  41.         }      
  42.         return 0;
  43. }

és itt a i2c master header fájl:

  1. /*
  2.  * i2c_master_lib.h
  3.  *
  4.  * Created: 2015.06.21. 21:41:05
  5.  *  Author: Petró Máté
  6.  */
  7.  
  8.  
  9. #ifndef I2C_MASTER_LIB_H_
  10. #define I2C_MASTER_LIB_H_
  11. #ifndef F_CPU
  12. #define F_CPU 1000000UL // 1 MHz-s órajel a default
  13. #endif
  14.  
  15. #define F_SCL 100000UL // I2C 100 kHz-el megy
  16.  
  17. #define TW_START 0xA4
  18. #define TW_READY (TWCR & 0x80)
  19. #define TW_STATUS (TWSR & 0xF8)
  20. #define TW_SEND 0x84
  21. #define TW_STOP 0x94
  22. #define i2c_stop() TWCR = TW_STOP //betölti a leállító byte-ot
  23.  
  24. void i2c_init()
  25. {
  26.         TWSR = 0; // nincs további órajel osztás, ez nagyobb frekvenciákon kéne
  27.         TWBR = ((F_CPU/F_SCL)-16)/2; // datasheetbe lévő képlet
  28. }
  29.  
  30. uint8_t i2c_start() //kiküldi a start jelet
  31. {
  32.         TWCR = TW_START; // start jel
  33.         while (!TW_READY); // addig várunk amíg nincs kész
  34.         return ( TW_STATUS == 0x08 ); // ha sikerült kiküldeni akkor 1-et adunk vissza
  35. }
  36.  
  37. uint8_t i2c_sendaddr(uint8_t addr) // kiküldjük a sínre a slave címét
  38. {
  39.         TWDR = addr; //betöltjök a címet
  40.         TWCR = TW_SEND; // küldés
  41.         while (!TW_READY); // várunk
  42.         return (TW_STATUS==0x18); // ha sikeres akkor  egyet adunk vissza
  43. }
  44. uint8_t i2c_write (uint8_t data) // adat küldése a slave-nek
  45. {
  46.         TWDR = data; // betöltjük az adatot
  47.         TWCR = TW_SEND; // küldés
  48.         while (!TW_READY); // várunk
  49.         return (TW_STATUS!=0x28); // ha sikeres akkor egyet adunk vissza
  50. }
  51.  
  52.  
  53. #endif /* I2C_MASTER_LIB_H_ */


ui. ha van valakinek egy működő i2c könyvtára az elfogadnám

Üdv,
Máté
A hozzászólás módosítva: Jún 22, 2015
(#) killbill válasza mpetrooo hozzászólására (») Jún 22, 2015 /
 
1 MHz orajellel sosem lesz 100kHz SCL, mivel a legkisebb osztas, amit el lehet erni az adatlap szerint az 16+2*10 = 36. A TWBR nem lehet 10-nel kevesebb. Igy aztan javaslom, hogy allitsd TWBR-t 10-re, es akkor kapsz egy szep 27.7 Khz-ces SCL-t. A tobbi reszet nem neztem a kodnak.
(#) mpetrooo válasza killbill hozzászólására (») Jún 22, 2015 /
 
sajna még mindig nem jó, a cím küldés még elméletileg működik, de amikor adatot akarok küldeni, akkor a függvény már hibát ad vissza.
(#) kapu48 válasza mpetrooo hozzászólására (») Jún 22, 2015 /
 
Itt nem alkalmazhatunk „==” egyenlő e?: return ( TW_STATUS == 0x08 );
Helyesen „=” legyen egyenlő: return ( TW_STATUS = 0x08 );
És ez több helyen is előfordul a programodban!
(#) kapu48 válasza mpetrooo hozzászólására (») Jún 22, 2015 /
 
Hogy segítsek is!
Itt a fórúmon találsz témába illőt:
HMC6352 iránytűmodul - I2C (TWI) használata AVR-rel

Egészen jól körbejárja a témát.
(#) mpetrooo válasza kapu48 hozzászólására (») Jún 22, 2015 /
 
köszönöm átnyálazom az írást.
==-re azért gondoltam hogy megvizsgálja hogy a TWI_STATUS egyenlő-e 0x08, és ha egyelő akkor logikai igazra értékelődik ki és az adódik vissza, ha nem egyenlő akkor meg hamis.
(#) killbill válasza kapu48 hozzászólására (») Jún 22, 2015 /
 
Es az ugy is van helyesen! Ez 'C' nyelv, nem bézik!
(#) killbill válasza killbill hozzászólására (») Jún 22, 2015 /
 
Nem egyertelmu, amit irtam, csak mar nem tudom szerkeszteni. Szoval, igenis hasznalhatunk ilyet egy C programban, hogy return TWI_STATUS == 0x08;
Ez teljesen elfogadott es ez is ramutat a C nyelv lehetosegeire. mpetrooo magyarazatahoz csak annyi, hogy az == es a tobbi relacios operator valamint a ! nem logikai igaz vagy hamis, hanem 1 vagy 0 erteku int tipusu eredmenyt ad vissza. Akar azt is le lehet irni, hogy

a = b + (c < 20);

Ha 'c' kisebb, mint húsz, akkor b + 1, egyebkent meg b + 0 megy az 'a'-ba.
(#) mpetrooo válasza killbill hozzászólására (») Jún 22, 2015 /
 
köszönöm a segítséget. Rájöttem hogy mi a gond Enyhén szólva buta vagyok a DS1307 0x00-s regiszterének MSB-je 0-ra aktiválja oszcillátort, nem 1-re
köszönöm mindenki segítségét
(#) killbill válasza mpetrooo hozzászólására (») Jún 22, 2015 /
 
Idézet:
„Enyhén szólva buta vagyok. A DS1307 0x00-s regiszterének MSB-je 0-ra aktiválja oszcillátort, nem 1-re”
Elnézni az adatlapot az semmiképpen nem butasag.
(#) Massawa hozzászólása Jún 23, 2015 /
 
Egy kérdés:

Az ATmega328 procin a PD5=OC1A.
Az adott progiban használom az OC1A-t a megszakitásra, befolyásolhatja ez a PD5 müködését? ( a program kezeli a PD5 portot, de a kimenet folyton high szintü). Ha megallitom a progit, akkor a port simán billenthetö az egérrel.
Következő: »»   674 / 837
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