Fórum témák
» Több friss téma |
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
A Commodore 64-nek 1 regisztere volt (A) és két index regisztere (X,Y), amit indexelésen kívül nem sokra tudtál használni.
Ha kiszámoltad az új értéket és az A regiszterben már benne volt, akkor - vagy az XOR-os csodát játszod el - vagy letárolod memóriában és visszatöltöd XOR-ral:
XOR nélkül memóriával:
Commodore 64-en az XOR egyértelműen olcsóbb volt, AVR alatt minthogy több regiszter van és teljesen más az architektúrája, ugyanannyiba kerül. AVR OR:
AVR XOR:
Annyiban jobb a XOR, hogy r24 értéke megmarad a végén.
A megadott C-ből és rajzból kiindulva: behívom a portd-t,ami bármi lehet,és így néz ki : xxxx xxxx ,a kiemelt bitek nem változhatnak visszaírás után.A példa alapján a 3-as számot szeretné kiíratni,ami kódolva a portd-re eső rész 0x89.
Tehát,szerintem a második and nem kell.
Srácok!!! Végül szándékosan csak a kódrészletet raktam fel, mert gondoltam hogy elő fog fordulni hogy nem csak arra kapok segítséget amire szeretnék, holott most egy hibára koncentrálok. Eléggé elkanyarodtatok a témától, nem tudom hogy jött a commodore (lehet hogy kellene nyitni egy commodore miértek hogyanok témát? ). Csak azt szerettem volna megtudni hogy ha csak egy digitet kapcsolok be tökéletesen megy de ha többet akkor or kapcsolattal jelennek meg a szegmensek. A probléma napok óta és még most is megven, de köszönöm hogy igyekeztetek segíteni, most itt a hétvége, majd elmerülök benne jobban és rájövök, ha maga jön rá az ember jobban megtanulja.
Ertem. Tenyleg rafkos. Csak a pelda kicsit felrevezeto, mert mind azzal kezd, hogy egy konstansot egy masik konstanssal maszkol. De tenyleg jo, ha Akkumulatoros architekturan dolgozol.
Sziasztok!
Távirányítós infra jelet akarok kiolvasni 8 Mhz-es ATMEGA168-al, TSOPxx38 vevővel, melynek kimenete INT1 lábra van kötve. Interrupt INT1-re beállítva, engedélyezve, bármilyen jelváltozásnál működésbe lép. SIGNAL függvénybe pedig nem tudom, hogy mit írjak. 8 bites trimer to count is engedélyezve van, (TCNT0) CLK/64 beállítással. Girder PC programmal előtte kiolvastam az infra távirányító 16 bites jeleit. Azt akarom elérni, hogy ugyan azt a 16 bitet olvassa be a mikrokontroller is, és beolvasása után írja azt ircode_tw regiszterbe. Arra lennék kíváncsi, mit írjak a SIGNAL függvénybe? Segítséget előre is köszönöm.
Én valahogy így csinálnám!
Némi útmutató: AVR-GCC-Tutorial/Assembler und Inline-Assembler
A hozzászólás módosítva: Szept 7, 2014
Hopssz!
Mi van, ha több egyforma Bit jön egymás után? Ehhez már ismerni kellene az adó frekvenciáját, hogy be állítsuk a timert. ... És kel egy start Bit figyelés, hogy tudjuk, mikor indítsuk a vételt! …
Őszintén szólva nagyon kezdő vagyok a témában, eddig mindent megtudtam oldani, csak az Infrát nem. C nyelvet ismerem valamennyire. Példaprogramnak köszönhetően már beállítottam mindent, csak a Signal-ban kéne úgy módosítani, hogy felismerje a 16 bites Irda jelet, úgy, ahogy a Girder PC.
Íme a mostani kód:
Szia ha a távirányító RC5 protokollt használ akkor használhatod ezt a programot is. Én INT0 megszakítást használtam, ami lefutó élre van beállítva, vagyis pontosan a start jel érkezésekor kér megszakítást. Az RC5 - nél 14 bitet kell beolvasni. Az időt pedig timer2 - vel mérem, ami 128 - as frekvenciaosztóval működik (a processzor 16MHz). üdv Gábor
Sziasztok. Lenne egy kérdésem. Nincs itt valakinek megtervezett AVR NYÁK adaptere? ISP kellene. Egyszerűen megfogalmazva van egy nyák ISP csatlakozóval, amibe berakom a különböző AVR microcontrollert és mehet is a programozás. Ebben kérek segítséget.
Sziasztok
Elore bocsatanam nagyon nagyon kezdo vagyok avr programozas teren es elkovettem egy nagyon nagy hibat...rossz fuse bit... Most nem tudom se programozni se torolni se semmit csinalni vele.. Adva van egy atmega162 ami nem egy kvarc rol kapja az orajelet hanem egy masik procirol xtal1 labra...ezeket a beallitasokat kelett volna megtegyem EESAVE BODLEVEL SUT1 CKSEL3 CKSEL2 CKSEL1 CKSEL0 tobbi bealotast nem kell kivallaszszam...Epitettem egy STK200 as programozot lpt portra ugy gondolom tokeletessen mukodott is a dolog...burn o mat al be is programoztam flash tartalmat es most jot volna fuse bit beallitas..Csakhogy ezeken a manualis bealitasokon kivul volt megy egy info hogy hex fuse beallitasokkal is be lehet allitania fuse bit eket ekkor gondoltam jobb lesz ugy beallitani mert nehogy kihagyjak valamit...H l E 0xD0, 0xF7, 0xFB ezeket allitottam en be programozonal .. csakhogy ez igy rossz mert leirasban H es L meg van cserelve igy en most ezel a hex fuse bit beallitasokkal ezt alitottam be...(utolag egy fuse bit calculatorral neztem meg) tehat ezek vannak beallitva most CKSEL3 SPIEN BOOTSZ1 BOOTSTR BOOTSZ0 EESAVE BOODLEVEL1..Ugy gondolom de nagoyn nem vagyok biztos benne egesz éjjel a googlit bujtam hogy a orajel beallitasok nem jok es ezert nem tudok most programozni se kiolvasni.. Ha az eredeti fuse beallitasokat irom be akkor sztem meg nagyobb lenne a baj mert ott nincs SPIEN es ha az nincs akkor en stk200 al nem tudnam programozni ha jol ertema dolgot..Cikkek kozott van egy HVPP programozo csak sajnos az nem tamogatja az atmega162 est van meg neten egy masik atmega fuse doctor nevre halgato reseter kapcsolas ..Csak most lehet nem kiserleteznek tovabbi epitgetessel mert lehet lesz megegy halott avr em..De lehet megiscsak megkiserlem ha nincs mas megoldas..olvasgattam meg hogy letezhet egy oylan megoldas hogy kulso orajelet kell rakotni avr xtal1 labara es akkor lehetne programozni..Ez ep kapora is jonne nekem mert ezena labon van nalam most egy 8 MHZ es orajal emit a masik mcu kuld ide...De most se tudom progizni se kiolvasni burn o mat al..se ponyproggal se bascom programozojaval Lehet tul nagy az a 8Mhz mert mindenfele 1 Mhz koruli kulso orajelet kuldenek ra..Es talaltam egy olyan infot is hogy ilyenkor le kellene csokkenteni a programozasi orajelet 1/4 reszere a kulso orajelnek...Na ezt nem tudom hol kellene megtenni.Tudtok segiteni ebben nem szeretnem mindejart a kukaba dobni a teljessen uj atmega162 est... koszonom a segitseget..
Kísérletező panel:
- veszel egy breadboard-ot (link) - veszel kábeleket hozzá (link) Hogyan csinálsz ISP csatlakozóhoz breadboard adaptert (2x3)? - veszel egy univerzális nyákot (link) - veszel ISP szalagkábel csatlakozót (link) - veszel tördelhető tüskesort (link) A varázslás ezután történik. Az univerzális nyákkal és tüskesorral kiszélesíted az ISP szalagkábel csatlakozót 2 raszterről 4 raszter szélesre. A 4 rasztert már simán be tudod dugni breadboardba, úgy hogy mind a 6 lábához köthetsz vezetéket. Tehát: - elkészíted az ISP adaptert breadboardhoz - bedugod az IC-t a breadboardba - összekötöd a vezetékeket az AVR chip leírása alapján az ISP adapterrel - az adapterbe meg bedugod a programozót A hozzászólás módosítva: Szept 10, 2014
Itt van egy hasonló leírás: link
Itt a 2x3-as ISP headerből 1x6-os sort csinál. Szerintem túlbonyolítja, mert én meghagytam a 2x3-as elrendezést, csak melléforrasztottam egy lefelé álló tüskesort. A következő kép már az én megoldásomra hasonlít, de még univerzális nyákot sem használ. (itt) Csomó vackot bedugok hasonló csalafintaságokkal a breadboardba. Van egy komplett zacskóm amiben forgatható potméterektől kezdve kismillió csatlakozón át az ethernet aljzatig az égvilágon mindent képes vagyok bedugni. A hozzászólás módosítva: Szept 10, 2014
Üdv!
Arduino 2560 boardomon tönkrement az USB chip, ezért vettem egy STK500 programozót, hogy a továbbiakban ezen keresztül programozhassak. Az utolsó programom arduinon, ami jelenleg is fut rajta, digitális kimenetként használja az 52,51,50 es pineket (SCK,MOSI,MISO) amikbe pont a programozót kellene kötni. Szabad ennek ellenére bekötni a programozót, vagy baj lesz belőle ?
Szabad, amikor elkezded programozni, akkor a programozó reseteli az AVR-t, tehát nem elsz gond. Pont hogy bemenetként nem szabad őket használni (illetve azt is lehet, de csak bizonyos megkötésekkel).
Üdv!
A következő problémával szembesültem: Egy checksum számításra írtam egy rutint:
A gondom az, hogy ha ICMPv4-re használom, akkor jól működik, ha IPv4-re akkor a számítás során valahol elveszíti a 0xFFFF-nél nagyobb biteket/értékeket. Pl.: 0x0006ab6b helyett csak 0x0000ab6b-t kapok. Általában mi okozhatja ezt?
Elég nehéz megérteni a kódot, de
itoa - integer to ascii ltoa - long integer to ascii Az itoa AVR alatt 2 byte-os. Azt javaslom, hogy az itoa-t nézd végig, ha kell cseréld le ltoa-ra. A hozzászólás módosítva: Szept 11, 2014
Ilyet én nem szoktam használni, mert halvány gőzöm sincs arról, hogy mi a végeredmény. Ezt a leginkább a C guruk tudják, de még arra a szintre nem jutottam el. - A 8-as shiftelést vajon az unsigned char típusú array[i]-n végzi el, vagy előtte mindent konvertál unsigned long-ra? Már öregszem, ezért inkább kiírok mindent, mielőtt aknára lépnék:
Be kell valljam, nem ismerem a C standardot, ezért a leghalványabb fogalmam sincs, hogy a fenti rész miképpen fog lefordulni.
Köszi a választ!
Az itoa-t csak az UART-on való küldésre használom, hogy HyperTerminal-ban szövegként jelenhessen meg, hibakeresés céljából. Az ltoa-t még nem ismertem, ki is próbáltam és segített tisztábban látni. A problémám beigazolódott. Az egyik esetben(ICMP) a rutin így ad össze: c59e + 6566 = 12b04 (ez ok). A másikban(IPv4) meg így: 9bad + c0a8 = 5c55 (15C55 helyett) (ez már nem jó).
Hogy tisztább legyen a helyzet:
Itt a wikipediás magyarázat is: Checksum számítása
A checksum += (array[i] << 8); azt csinalja, hogy az array[i]-t eloszor int-re konvertalja, balra shifteli 8 bittel, majd a checksum += miatt unsigned long int-re konvertalja es hozzaadja checksum-hoz. Ennek jol kellene osszeadnia.
A C az egy muveletben szereplo ket operandusbol a kisebb bitszamu operandust konvertalja a nagyobb bitszamura. Ha unsigned es signed keveredik, akkor a signedbol lesz unsigned. Ha egesz es lebegopontos keveredik, akkor az egeszet konvertalja lebegopontossa. Ezen felul a char, unsigned char, short tipusokat mindig int-re konvertalja. A float-ot mindig double-re konvertalja. A konverzioknal az elojelnek szerepe van: pl, ha van egy signed char valtozo, aminek az erteke 0x81, az int-re konvertalva 0xff81 lesz. unsigned char eseteben 0x0081 lesz belole. Tehat a checksum = checksum + valami eseteben a valamit atkonvertalja 32 bitesre, mert a checksum is az. Viszont nem ertek valamit. Ha neked 1db 16 bites szamot kell hozzaadni a checksum-hoz, akkor miert 2db 8 bitest adsz hozza: checksum += (array[i] <<8) | array[i+1]; lenne a korrekt sor. Ha egy ciklusban meg lehet sporolni egy 16 bites osszeadast (kulonosen egy 8 bites processzoron), akkor azt meg is kell sporolni. Es par aprosag: a for( ; ; ) barmelyik reszet elhagyhatod, felesleges az i = i; Ha a kozepsot hagyod el, akkor vegtelen ciklust kapsz. Ha jot akarsz magadnak, akkor nem hasznalsz i, j, stb nevu globalis valtozokat, mert ezek tipikusan lokalis valtozok nevei, es rutul meg tudja viccelni az embert, amikor egy for(i = 0; i < ...) ciklusbol hivsz egy olyan fuggvenyt, ami elrontja a globalis 'i'-t. Es mondjuk elfelejtetted deklaralni a lokalis 'i'-t, amiert a fordito nem szol, mert van egy globalis 'i'. Egyebkent sem szerencses ugyanolyan nevu lokalis es globalis valtozot deklaralni. Abbol csak a baj van. De a problemadra nem latom a valaszt, mert annak 32 bitesen kellene osszeadnia. Akarhonnan is szedi a byte-okat. Idézet: „A checksum += (array[i] << 8); azt csinalja, hogy az array[i]-t eloszor int-re konvertalja” Az elmélet és a gyakorlat AVR alatt nem mindig találkozik.
A gcc régi verziói valóban int-re konvertáltak. Lehetett látni a lefordított kódban, hogy a fenti shift-elés 16 biten történt. Az új gcc-kben már nem. Nézd meg ezt a bug reportot. Amikor 2k-s chipekre írnak programot, akkor a nép elvárja, hogy a 16 bit csak indokolt esetben legyen. A hozzászólás módosítva: Szept 12, 2014
Az termeszetes, hogy csak akkor konvertal 16 bitere, ha ez muszaj. Azaz, ha az eredmeny szempontjabol jelentosege van. Ez is resze az optimalizacionak. A te peldadban nem kell 16 biten shifteljen, mert az eredmeny felso 8 bitjet eldobja. Viszont az array-os sorban 16 bitre kell konvertalja, mert aztan az eredmenyt meg fel is kell bovitenie 32 bitre, nem dobhat el semmit. Persze, vannak gcc bug-ok, szivtam vele en is eleget. Kulonosen long-okkal. De altalaban csak optimalizacio mellett teved. De ettol fuggetlenul erdekes, hogy a problemas kod egyszer jol szamol, egyszer meg nem (ICMP/IPv4). Kicsit magikus a dolog.
Ez a bug report is csak arrol szol, hogy nem optimalizal rendesen, tehat akkor is 16 biten szamol, amikor eleg lenne a 8. Raadasul 2008-as a felvetes...
Fentebb írtam, hogy már jól működik a gcc. Most, 2014-ben nem tudok olyan esetről, hogy az avr-gcc szószátyárkodna, pedig mindig megnézem, hogy mit ügyködött.
Gyakorlatilag ha én magam írnám meg assembly-ben, több helyet foglalna a kód, mert az avr-gcc jobban tud nálam optimalizálni. A hozzászólás módosítva: Szept 12, 2014
Üdv!
A checksum-ot azért, írtam így, mert így sikerült Még nem vagyok valami összeszedett a kódok írásában, így néha összetettebb sorokat írok, néha darabokban, lépésekben írom le. A for(;-nál is azért hagytam meg az i=i-t, mert könnyebben megértem, hogy mit is csináltam vagy akartam csinálni. Mellékelem a kód letisztított változatát, amiben megvan minden rész ahol a void CheckSum() rutin megjelenik. Amiket kihagytam: SPI, UART, ENC28J60... stb. saját készítésű könyvtárak(header files), az említett hiba szempontjából nem relevánsak nemde? Ill. a txt-ben a void CheckSum() rutin eredményeit nyomtattam ki.
Csak az egyertelmuseg kedveert: a header files az nem konyvtarak. A header file, az C forras kod. A konyvtar pedig mar leforditott kod (akarmilyen nyelven is irodott) es a linker dolgozik vele. Az igaz, hogy a bennuk levu fuggvenyek deklaracioi altalaban ilyen .h header file-okban vannak. Pl. a memcpy() meg a memcmp(), amik hasznalataval helybol a felere csokkenne a programod merete. Idézet: „az említett hiba szempontjából nem relevánsak nemde?” Azt nem lehet tudni. A globalis valtozok hasznalata komoly odafigyelest igenyel. Fokepp, ha a valtozo neve 'i'. Ha esetleg egy masik file-ban is hasznalsz 'i' nevu globalis valtozot, es tortenetesen egy interrupt rutin is hasznalja, akkor abbol barmi is lehet. Ugyanis a kulonbozo file-okban deklaralt azonos nevu valtozok csak egyszer keletkeznek, es ugyanazok lesznek. Szoval semmi nem garantalt ilyen esetekben. Ha olyan globalis valtozot akarsz, amit csak az adott forras file-ban hasznalsz, akkor deklarald static-nak. Es ez igaz a file-on beluli fuggvenyekre is. Ha egy fuggvenyt nem akarsz mas forrasbol meghivni, akkor jobb, ha static. De a problemadra a megoldast meg mindig nem tudom. Nem nagyaon latom okat annak, hogy ugyanaz a fuggveny ket meghivasbol maskepp mukodik. Es ugy mukodik maskepp, hogy hibasan szamol egy teljesen egyszeru ciklusban.
Bevallom, nekem nem jött be az ENC28J60.
Az internet szabvány szerint nem kellene problémát jelentenie annak, ha egy eszköz fordított polaritással küld, azaz az TPIN+ és TPIN- felcserélődik. A chip dokumentációja le is írja, hogy az ENC28J60 képes fordított polaritással fogadni az adatokat, csak az maradt ki, hogy 60-70%-os packet loss mellett. Szóval nem árt kétféle ethernet kábelt tartani otthon, az egyik legyen egyenes polaritású, a másik pedig fordított. Ha éppen egyenes polaritású routerrel beszélsz, akkor az egyik kábelt használod, ha a másik félével, akkor fordítottat.
Itt van nálad a megoldás.
Ezt kicseréltem:
Erre:
Így már működik. Azért még most is zavar, hogy az első verzió mért ment és miért nem ment... |
Bejelentkezés
Hirdetés |