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   712 / 840
(#) csatti2 válasza wbt hozzászólására (») Dec 19, 2015 /
 
Milyen szkóp ez? Nekem egy felokosított (50MHz->100MHz) Rigol-om van otthon, azon teljesen jók a jelek (minap 64MHz-es órajelét nézegettem egy SRAM-nak), sosem volt ilyen problémám.
A nem használt csatornákat azért kell kikapcsolni, mert a max mintavételezés (pl. 1Gs) az összes csatornára vonatkozik, tehát ha 3-4 csatorna van bekapcsolva, akkor csak a negyede jut egy csatornára, 2-nél a fele, 1-nél pedig a teljes egyre jut és sokkal jobb lesz a végeredmény.
(#) wbt válasza csatti2 hozzászólására (») Dec 19, 2015 /
 
Ez Hantek 5074-es, itt nem számított az engedélyezett csatornák száma ( a memóriánál számít). Szét lesz ez kapva, azt már látom. Emlékeim szerint soha nem okozott még nekem így gondot, tehát pont belefutottam. Napi szinten használom és sok PWM meg egyéb nyalánkságot látott már. Kezd megpusztulni...vagy nem tudom...de ez már itt off-topic.
(#) killbill válasza wbt hozzászólására (») Dec 19, 2015 /
 
Mekkorak voltak az impulzusok es mekkora volt a szkop mintaveteli frekvenciaja?
(#) tursaba válasza wbt hozzászólására (») Dec 20, 2015 /
 
Engem a 300MHz-es digitszkóp lepett meg 48MHz-es quarcoszci jel vizsgálatánál, 1 csatornán.
Csak ennyit tudtam mondani: na ne már !
(#) wbt válasza killbill hozzászólására (») Dec 20, 2015 /
 
Elméletileg 1.25usec az impulzus és 1GS/s a mintavétel. (16MHz AVR 10bit PWM 3-10 érték, kb 40-től már tökéletes a megjelenítés) Szóval nem kell egyből elhinni mindent neki.
(#) killbill válasza wbt hozzászólására (») Dec 20, 2015 /
 
Nem lehet, hogy ebben a beallitasban nem 1GS/s volt az, hanem sokkal kevesebb. Mert a szkopabra kisertetiesen hasonlit arra az esetre, amikor az impulzusok rovidebbek, mint a mintaveteli idokoz. Es ezert hol elkapja, hol nem.
(#) Max26 hozzászólása Dec 23, 2015 /
 
Sziasztok!

Szeretném szabályosan megállítani a mintavételezést. A 63. sor: Ha megnyomtam a 2-es nyomógombot, akkor álljon e a mintavételezés és a program ugorjon a fomenu: cimkére.
Helyes-e a megoldásom?(ez így működik, de attól tartok, hogy a timer1 még fut).
Bővebben: Link
(#) Kovidivi válasza Max26 hozzászólására (») Dec 24, 2015 /
 
Egy while(1) szerintem nem szabályos megállás, mert onnan csak resettel indul újra a program. A Timert is ki kellene kapcsolni, vagy legalább az interruptokat tiltani (cli), de ha a fogyasztás nem lényeg, akkor hagyd. Egyébként meg alvóba kellene elküldeni az AVR-t, minden perifériát leállítva, de hogy hogyan folytatódik a program, ha egyszer megállt, azt nem tudom.
Megjegyzés: a goto-t nem szokták már használni. Működik, ahogy kell, de nem az igazi, pl. az előtte levő fv. sosem ér véget, ha a fomenu címkénél beraksz még egy gotot egy rossz helyre, stack túlcsordulásod lesz.
A hozzászólás módosítva: Dec 24, 2015
(#) killbill válasza Kovidivi hozzászólására (») Dec 24, 2015 /
 
A while(1)-bol egy break siman kihoz. Teljesen szabályos és teljesen megszokott. Ha finomkodni akarsz, akkor while(1) helyett a for( ; ; ) szebb, de PONTOSAN ugyanazt csinalja. A break ugyanugy kivisz belole.

A goto-t pl. akkor hasznaljak, ha tobb, egymasba agyazott ciklusbol teljesen ki kell jonni. Ilyenkor minden egyes ciklusbol egy feltetelvizsgalattal lehetne csak kijonni, és ennel sokkal egyszerubb a goto. De teny, hogy nagyon ritkan kell es mindent meg lehet oldani nelkule.

Goto-val nem tudsz stack tulcsordulast csinalni sehogy. A goto csak fuggvenyen belul ugrik. De egyebkent stack tulcsordulast ket modon tudsz csinalni. Rekurziv (onmagat hivo) fuggvennyel es oriasi lokalis valtozokkal, sehogy maskepp.

Boldog Karácsonyt!
A hozzászólás módosítva: Dec 24, 2015
(#) Kovidivi válasza killbill hozzászólására (») Dec 24, 2015 /
 
Arra gondoltam, ha egy függvényben ott van, hogy goto fomenu, akkor elugrunk a fomenu cimkére, és ha ott while(1) vagy for(; van, akkor a goto utáni rész nem hajtódik végre. Ha innen pedig visszaugrunk a goto elé, akkor már kész is egy vég nélküli hurok. Neked is és Mindenkinek Boldog Karácsonyt!
(#) zombee válasza Max26 hozzászólására (») Dec 24, 2015 /
 
Akkor jövök én:
Egy épeszű programban nincs goto meg címkék, elég sok a macera vele. Én úgy látom hogy
a 63. sorban a "goto fomenu" helyett egy "break" simán megállja a helyét, mert lényegében
ezt csinálja: kilép a while ciklusból, és kész. Ilyen menüs cuccoknál állapotgépet használok,
ahol az állapotjelző változót egy végtelen ciklusban vizsgálom a különböző funkciók belépőpontjánál.
Persze vannak átmeneti állapotok(pl. képernyőtörlés, visszaállítás, várakozás billentyű elengedésre)
amelyeknek szintén érdemes 1-1 állapotot fenntartani, és nem az átmeneteknél lekezelni mindent.

Mindenkinek Boldog Karácsonyt!
A hozzászólás módosítva: Dec 24, 2015
(#) killbill válasza zombee hozzászólására (») Dec 24, 2015 /
 
Idézet:
„Egy épeszű programban nincs goto meg címkék, elég sok a macera vele.”
Ha jó programozó vagy, akkor nincs vele semmi macera. Nagyon ritkán van rá szükség, de akkor nagyon hasznos. A fenti programban valóban szükségtelen, de azért azt nem mondanám, hogy épeszű programban nincs goto. Egyébként meg nem elég egy sima break, mert az a while egy if-en belül van, aminek az else ágába ugrik a goto. Bár azt nem értem, hogy ez miért jó....
(#) zombee válasza killbill hozzászólására (») Dec 24, 2015 /
 
Most látom én is hogy a "fomenu" címke az else részben van, ide egy break valóban nem lenne jó. Na erre mondom én hogy macera. Ettől még lehet jó a kód(tesztelni kell), de az ilyen megoldásokat pont azért nem szeretem mert ilyen kódokat eredményez. A galibát meg arra értem hogy az sem mindegy, hol deklarálok egy változót amikor címkék közt ugrálok.
(#) killbill válasza zombee hozzászólására (») Dec 25, 2015 /
 
Idézet:
„Most látom én is hogy a "fomenu" címke az else részben van, ide egy break valóban nem lenne jó. Na erre mondom én hogy macera.”
Attol szerintem nem macera, hogy egy if else agaba is lehet ugrani. Sőt! Pont ettől jó. De azt nem vitatom, hogy jelen esetben nem a goto a jó megoldás.
Idézet:
„A galibát meg arra értem hogy az sem mindegy, hol deklarálok egy változót amikor címkék közt ugrálok.”
Ez érdekes kérdés. Én régimódi C programozó vagyok, a függvény elején deklarálom a fv. összes változóját. A goto meg csak a függvényen belül tud ugrálni.
(#) zombee válasza killbill hozzászólására (») Dec 25, 2015 /
 
Abba remélem egyetértünk hogy (for) ciklusba ugrani már paraszt dolog lenne.
(#) Bakman válasza zombee hozzászólására (») Dec 25, 2015 /
 
Annak mi értleme lenne?
(#) killbill válasza zombee hozzászólására (») Dec 25, 2015 /
 
Idézet:
„Abba remélem egyetértünk hogy (for) ciklusba ugrani már paraszt dolog lenne.”
Nem feltétlenül. Persze egy 'mezei' for(i = 0; i < 100; ++i) esetén kevés okot látok rá, de vannak kacifántos esetek, amikor elképzelhető ez is. Ezen kár rugózni, a goto-nak is megvan a maga helye, csak nagyon ritka. Egy többszörösen egymásba ágyazott ciklus legbelsejéből kijönni egy időkritikus dologban egy goto-val sokkal célszerűbb, mint mondjuk az összes ciklusban megvizsgálni az 'lepj_ki' változót.

Hidd el, hogy a globális változók használata, főleg a rövid nevűek (i, j, a), a sok globális függvény, orrba-szájba interruptból csinálni mindent, delay()-ek használata programokban, fordító Warningok figyelmen kívül hagyása, a Warningok kikapcsolása, sokkal-sokkal nagyobb probléma és macera, mint a goto.
(#) wbt válasza killbill hozzászólására (») Dec 28, 2015 /
 
Közben kiderültek itt más érdekességek is. (most vagy én vagyok teljesen sülthal a méréshez, vagy sunyiság van). Az adott feladat különben nem nagy cucc, 2db PWM jel összekapuzásáról van szó. Van egy Timer1/10bit PWM (1-es előosztó) és egy Timer0 (256-os előosztóval). T1 kb 8kHz, T0 kb. 122Hz-re jön ki. DE!!!
Már a sírba kergetett a szinkronizálás, több szkóp van már itt, mint fogam...
Ami kijött: T1=8bit PWM (T0=8bit PWM) a két jel tökéletes szinkronban van. T1=9 bit vagy 10 bit , a T0-hoz képest el kezd mászni, tehát a frekvenciája nem jó. Mivel a jó kis pontos frekimérőm megadta magát (csak 25 éves), így a szkópok beépített mérőjével mérve nem a kívánt 64-szeres érték jött ki, hanem 63.88 körüli. Pdf-ek túrva, nekem az a gyanús, mint ha 9 vagy 10-bites PWM módban az AVR-nél pl.1FF / 3FF elérésekor azonnal nullázná a számlálót! Tehát nem várja ki a 3FF érték "idejét". Valami rémlik, talán itt olvashattam (?) hogy valaki apró impulzust mért vagy 0-nál vagy 3FF-nél is a kimeneten, szóval valami nem stimmel. Persze sokszor ez nem számít, csak pont most nekem kellett beleszaladni ebbe, a különbségnek kikeveredő jel (néha a kapuidőbe 10, néha 11 impulzus fér bele) hullámzást okoz. Szóval röviden ettől hullik a hajam... Bocs a hosszért...
(#) Kovidivi válasza wbt hozzászólására (») Dec 28, 2015 /
 
Ha ilyen jellegű a probléma, akkor ne pontosan 10bites legyen a PWM, hanem állíts be egy TOP értéket, ami neked kell. Egyébként az adatlap írja, hogy 0 és TOP értékek külőnleges helyzetet teremtenek, és hogy hogyan reagál rá a timer.
(#) wbt válasza Kovidivi hozzászólására (») Dec 28, 2015 /
 
Túrtam utána, de PWM módokban be van madzagolva az FF/1FF/3FF TOP érték
(mondjuk azt most nem fogom agyilag, hogy TOP értéknek néhány módban az ICR1 regisztert írják, ami Input Capture (!) regiszter...mi köze hozzá, ha már input...)
(#) csatti2 válasza wbt hozzászólására (») Dec 28, 2015 / 1
 
Nézd meg jobban. A timerek-nél gyakran többféle PWM mód is van, ami csak abban különbözik a megszokottól (pl. OCR1A = TOP), hogy az ICR1 regiszter tárolja a TOP értéket ezért mindkét PWM kimenete a timer-nek használható marad (OCR1A, OCR1B). pl. 14-es mód ATMEGA328p-nél.
A hozzászólás módosítva: Dec 28, 2015
(#) Kovidivi válasza wbt hozzászólására (») Dec 28, 2015 /
 
Az ICR-rel teljesen egyéni értéket tudsz beállítani! Én ezzel készítek 12bites PWM-et úgy, hogy mindkettő OCR regiszter használható. Azt hiszem más lehetőség nem volt 12bit-re, esetleg még az, ha az egyik OCR-be írom a TOP (4096) értéket, de akkor elbukom az egyik csatornát. Alapból meg talán max. 11bit-es mód van (vagy csak 10?). Atmega328-ról van szó.
(#) wbt válasza Kovidivi hozzászólására (») Dec 28, 2015 /
 
Köszönöm a segítséget, bevéstem neki 0x0400-at az ICR1-be és nincs lebegés.
Nem értem én "ezeket"... mit kell bonyolítani a dolgokat, főleg, talán a portásnak oda kellene adni kipróbálásra, ha már uC-t gyártunk...ugye. Különben nem találtam eddig utalást arra, hogy 3FF végérték az csak egy pillanatig áll (-hat) fenn, főleg azért volt érthetetlen számomra, mert 8-bit FF-nél tökéletes (!) a szinkron. A Jó Isten áldja kezetek/lábatok/stb. a felhomályosításért!
(#) filter hozzászólása Dec 29, 2015 /
 
Sziasztok!
2 db atmega 168-al és a számítógéppel szeretnék RS485-ön kommunikálni. Van egy olyan anomáliám hogy van amikor küldök és semmi választ nem kapok, csak újraindítás után, illetve többszöri újraindítás után törlődik a kontroller eeprom memóriája.

  1. void UART_send_buf(char *buffer) {
  2.     PORTD |=(1<<PIND4);
  3.         _delay_ms(1);
  4.         int k;
  5.     k=0;
  6.     while(buffer[k]!='\0') {
  7.         while (!(UCSR0A & (1 <<UDRE0)));
  8.         UDR0=buffer[k];
  9.         k++;
  10.         _delay_ms(TRANSFER_DELAY);
  11.     }
  12.     PORTD &=~(1<<PIND4);
  13. }
  14.  
  15. void UART_add_byte_to_string(char *dest,char data) {
  16.     int shossz;
  17.     shossz = strlen(dest);
  18.     dest[shossz] = data;
  19.     dest[shossz+1] = '\0';
  20. }
  21.  
  22. ISR(USART_RX_vect)  {
  23.     receive = UDR0;
  24.     UART_add_byte_to_string(receive_TMP_buffer,receive);
  25.     //parancsok NYIT1-->nekünk este, NYIT2-->szomszédnak este
  26.         //NYIT3-->nappali üzemmód
  27.                 if(receive=='\n') {
  28.                        
  29.                 if ((strncmp(receive_TMP_buffer,"NYIT1",5)) == 0) {
  30.                 KAPU_NYIT; LAMP_1_FEL; KAPU_time=10; LAMP_time=40; futas_kapu=1; futas_lampa=1; receive_TMP_buffer[0]='\0';
  31.                         receive_TMP_buffer[1]='\0';
  32.                         receive_TMP_buffer[2]='\0';
  33.                         receive_TMP_buffer[3]='\0';
  34.                         receive_TMP_buffer[4]='\0';
  35.                         receive_TMP_buffer[5]='\0';
  36.                         receive_TMP_buffer[6]='\0';
  37.                         receive_TMP_buffer[7]='\0';
  38.                         UART_send_buf("OK\r\n");
  39.                 }
  40.                                        
  41.                 if ((strncmp(receive_TMP_buffer,"NYIT2",5)) == 0) {
  42.                         KAPU_NYIT; LAMP_2_FEL; KAPU_time=10; LAMP_time=40; futas_kapu=1; futas_lampa=1; receive_TMP_buffer[0]='\0';
  43.                         receive_TMP_buffer[1]='\0';
  44.                         receive_TMP_buffer[2]='\0';
  45.                         receive_TMP_buffer[3]='\0';
  46.                         receive_TMP_buffer[4]='\0';
  47.                         receive_TMP_buffer[5]='\0';
  48.                         receive_TMP_buffer[6]='\0';
  49.                         receive_TMP_buffer[7]='\0';
  50.                         UART_send_buf("OK\r\n");
  51.                 }                      
  52.                
  53.                 if ((strncmp(receive_TMP_buffer,"NYIT3",3)) == 0) {
  54.                         KAPU_NYIT; KAPU_time=10; futas_kapu=1; receive_TMP_buffer[0]='\0';
  55.                         receive_TMP_buffer[1]='\0';
  56.                         receive_TMP_buffer[2]='\0';
  57.                         receive_TMP_buffer[3]='\0';
  58.                         receive_TMP_buffer[4]='\0';
  59.                         receive_TMP_buffer[5]='\0';
  60.                         receive_TMP_buffer[6]='\0';
  61.                         receive_TMP_buffer[7]='\0';
  62.                         UART_send_buf("OK\r\n");
  63.                 }                                              
  64.         }              
  65. }


Hol hibázhattam el?
(#) rolandgw válasza filter hozzászólására (») Dec 29, 2015 / 1
 
A megszakítást nem arra találták ki,hogy oda írjuk a főprogramot Használj ring buffert.
(#) filter válasza rolandgw hozzászólására (») Dec 29, 2015 /
 
Köszönöm, elég sokat javult
(#) Gj hozzászólása Dec 30, 2015 /
 
Üdv!

A 8 bites AVR-ek világában milyen lehetőségeim vannak olyan kommunikációra, ami képes kb. 500Kbit/s sebességű kommunikációra és a buszra felfűzhetek két AVR-t és egy EEPROM-ot? Az egyik AVR időnként felülírna az EEPROM-ban korábbi értékeket, a másik AVR pedig teljes erejével folyamatosan olvasná az EEPROM-ot (és rajzolná egy grafikus LCD-re a benne található adatokat bitről-bitre).

Az SPI-t esetleg meg lehet valahogy variálni, hogy a két Master ne vesszen össze, hogy éppen ki használja az EEPROM-ot? Én ezt gondoltam ki.
A diódákat ugye jó irányba rajzoltam?
A hozzászólás módosítva: Dec 30, 2015
(#) zombee válasza Gj hozzászólására (») Dec 31, 2015 / 1
 
Nem éri meg SPI-t gányolni, én I2C-t javaslok. Márcsak azért is, mert a forgalomban lévő EEPROM-ok nagy része I2C buszos(24C sorozat), és akár szoftveresen is megoldható hogy két vagy több master ne vesszen össze. Az I2C-t tudó eszközök nagy része tudja az 1.7MHz-es módot.

Ütközés elkerülhető egy jól megírt szoftverrel(start/stop feltétel detektálás slave oldalon), vagy összekötöd a két AVR-t két "foglalt" vezetékkel amivel mindkét IC jelezni tudja a másik felé hogy most övé a busz. Szoftveresen pedig úgy tudod, hogy az éppen adó master ha befejezte az átvitelt akkor hosszabb ideig nem nyúl a buszhoz semmilyen körülmények közt, a felszabaduló buszt a slave rövidebb idő után foglalja le egy start feltétellel. Többlöketes átvitel esetén a masternek egy I2C löket után azonnal foglalnia kell a buszt.
A hozzászólás módosítva: Dec 31, 2015
(#) csatti2 válasza Gj hozzászólására (») Dec 31, 2015 /
 
Mennyi adatról van szó? Milyen gyakran történik írás?
Jó esély van rá, hogy FRAM-al jobban meg lehet csinálni, mint EEPROM-al. Sok előnye van az EEPROM-hoz képest (és egy két hátránya).
Miért nem elég egy AVR?
(#) Gj válasza csatti2 hozzászólására (») Dec 31, 2015 /
 
A lábszám miatt nem elég.
Igazából nem is tudom, miért mondtam kapásból EEPROM-ot
Felejtő memória is teljesen jó.
Következő: »»   712 / 840
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