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   627 / 837
(#) Massawa válasza benjami hozzászólására (») Nov 7, 2014 /
 
Sajnos kell, sokkal megbizhatobb igy - igaz csak 5x ismétlem.
(#) zsolt58 válasza kapu48 hozzászólására (») Nov 7, 2014 /
 
Nekem a Link nem müködik!
És ez a programozo jo hozzá? kép
Erre a hexre gondolsz?
Nekem AVR studio 4-em van de STK200 nem mutat de AVRisp-t mutat!
Idézet:
„Ezért a kapott *.hex állományt feltölteni pl.: régebbi Bascom IDE-vel tudod.”

És eztet AVRisp-vel lehet?
A hozzászólás módosítva: Nov 7, 2014

avrisp.gif
    
(#) kapu48 válasza zsolt58 hozzászólására (») Nov 7, 2014 /
 
Valószínűleg lehet, ha már azt írják!
Bár én még sosem használtam ilyet!

Mert mivel nincsen LPT-röl leválasztó közbenső fokozat, állandóan szét kel húzogatni, programozás és tesztelés között, ha másra is használod a SPI pineket.

(A link elejéröl töröld a "http//" részt!)
A hozzászólás módosítva: Nov 7, 2014
(#) kapu48 válasza zsolt58 hozzászólására (») Nov 7, 2014 /
 
(#) zsolt58 válasza kapu48 hozzászólására (») Nov 7, 2014 /
 
PonyProg-al lehet LPT porton programozni?
És ha lehet akkor hogyan?
C++-ba?
(#) kapu48 válasza zsolt58 hozzászólására (») Nov 8, 2014 /
 
Én inkább az oldal „AVR ISP (STK200/300) parallel port interface” bekezdésére gondoltam.

De inkább át irányítlak ide:
TavIR STK200 programozó

Kevés ismertető itt.
(#) videokartyab hozzászólása Nov 9, 2014 /
 
Sziasztok

Tudna segíteni valaki, pontosan hogyan működik az A/D konverternél a csatorna kiválasztás.
ADMUX = (ADMUX & 0b11110000) | csatorna; //pontosan ez a sor érdekellne
A cikket írónak Atmega 8 van abban pedig 3db MUX bit van az ADMUX regiszterben.
Atmega 16-ban 4db ilyen bit van a kiválasztáshoz. Mi ez a 0b11110000 amit ráésel. A MUX bitek pont az alsó 4 biten vannak.
Ebből a cikkből van: cikk //az oldal alsó fele

Két potit is szeretnék csatlakoztatni az Atmega16-ra, de csak egyet tudok működésre bírni.
Hiába írom át a függvény meghíváskor a ()-lévő számot nálam mindig ugyanaz a poti marad.
A hozzászólás módosítva: Nov 9, 2014
(#) vzoole válasza videokartyab hozzászólására (») Nov 9, 2014 /
 
(#) killbill válasza videokartyab hozzászólására (») Nov 9, 2014 /
 
Idézet:
„Mi ez a 0b11110000 amit ráésel. A MUX bitek pont az alsó 4 biten vannak.”

Szetszedem azt a sort ketfele:
  1. ADMUX = (ADMUX & 0b11110000) | csatorna;
  2. // helyett:
  3. temp = ADMUX & 0b11110000;  // eloszor levesszuk a regi MUX biteket
  4. ADMUX = temp | csatorna;        // aztan hozzatesszuk az uj MUX biteket
(#) videokartyab válasza killbill hozzászólására (») Nov 9, 2014 /
 
Köszönöm szépen! Volt egy pár hibám amit nem értettem.
Neked is vzoole!
(#) Sick-Bastard hozzászólása Nov 9, 2014 /
 
Üdv!

Az alábbi for() ciklussal van egy komoly bajom:

  1. for(unsigned char w=0;w<=7;w++)
  2. {
  3.         if(relay[w] == 1)
  4.        {
  5.         relay[8] |= (1<<(w+1));
  6.         }
  7.         else if(relay[w] == 0)
  8.         {
  9.         relay[8] &= ~(1<<(w+1));
  10.         }
  11. }


A gondom, hogy nem áll meg a w=7 után, hanem tovább megy, mintha végtelen ciklusba lépett volna.

Az ISR(TIMER2_COMPA_vect) használatban van a RTC-hoz.
(#) killbill válasza Sick-Bastard hozzászólására (») Nov 10, 2014 /
 
A relay tomb hogyan van deklaralva?
(#) kapu48 válasza Sick-Bastard hozzászólására (») Nov 10, 2014 /
 
Az ilyen rejtélyes hiba oka általában verem túlcsordulás szokott lenni!
(#) Kovidivi válasza Sick-Bastard hozzászólására (») Nov 10, 2014 /
 
Szia.
Kettö dolgot próbálj meg: ne char legyen a w, nekem gyanùs. A másik: a tömb 8. elemével kezdesz valamit. Ezt helyettesítsd mondjuk sorosporti kiírással. A char lehet unsigned? Szerintem nem tud negatív számot sehogy sem tárolni. Hagyd el az unsigned-et is próbaképpen. Remélem ez segít.
A hozzászólás módosítva: Nov 10, 2014
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Nov 10, 2014 /
 
killbill:
  1. unsigned char relay[9] = {1,0,1,1,0,1,0,1};

A main() előtt. Értékük csak 0 és 1 lehet.

kapu48:
A túlcsordulás alatt azt érted, hogy kifogytam volna az AVR RAM-jából?
ATmega1284P-t használok 16KB RAM-mal amiből 4KB-ot foglalatam le a main() előtt.

Kovidivi:
A relay[8] arra, kell, hogy az egyes reléket az MCP23S17 egyik portján megjelenítsem, valahogy így:
  1. relay[0] -> MCP PORTA PIN0
  2. relay[1] -> MCP PORTA PIN1
  3. ...
  4. relay[7] -> MCP PORTA PIN7

Az unsigned char w-t kicseréltem unsigned int i-re és így megy is.

Az interreupton kívül még ami fontos lehet:
Van egy globális unsigned int i-m, eredetileg azért, hogy ne kelljen minden for() ciklushoz egy helyi változót létrehozni (lustaságom, tapasztalatlanságom). Okozhat ez is valami hibát?
(#) Kovidivi válasza Sick-Bastard hozzászólására (») Nov 10, 2014 /
 
Szia. Mikor írtam, hogy a relazy(8)-at helyettesítsd sorosportos kiírással, ott arra gondoltam, hátha a tömbbel van gondod, pl. csak 8 elemre érhetö el, ami a relay(7), te pedig a következöt szeretnéd megváltoztatni, és ezzel a teszttel kitudódna a turpisság. Szerintem ha simán chart használsz, unsigned nélkül, akkor is menni fog. Fele annyi RAM-ot igényel.
(#) killbill válasza Sick-Bastard hozzászólására (») Nov 10, 2014 / 1
 
Ha a relay unsigned char (vagy signed, tok mindegy), akkor az 8 bites. Namarmost az a kifejezes, hogy
  1. 1 << (w+1)
az w=7 eseten olyan erteket eredmenyez, ami nem is fer el 8 biten (256). Tehat a (w+1)-ekenek semmi ertelme. Sot, az egyik reled sosem fog bekapcsolni. Ha a relay erteke csak 0 es 1 lehet, akkor az else agban nem kell az ujabb if.

Amit te szeretnel:
  1. func(..)
  2. {
  3. char w, mask;
  4.  
  5.  for(w = 0, mask = 1; w < 8; ++w, mask <<= 1)
  6.   if(relay[w])
  7.     relay[8] |= mask;
  8.  else
  9.     relay[8] &= ~mask;
  10. }

Ennyi az egesz.

Es egy orok jotanacs: SOHA ne csinalj globalis 'i', 'j' es hasonlo rovid nevo valtozokat!


Ha az unsigned char w helyett unsigned int-tel jol mukodik, akkor nem ebben a fuggvenyben van a hiba. Forditasi hiba, esetleg egyeb turpissag, stack tulcsordulas. A teljes forras sokat tud segiteni.
A hozzászólás módosítva: Nov 10, 2014
(#) killbill válasza killbill hozzászólására (») Nov 10, 2014 / 1
 
kicsit meg egyszerubben:
  1. unsigned char relay[9] = {1, 0, .... };
  2.  
  3. func(..)
  4. {
  5. unsigned char *p, mask, tmp;
  6.  
  7.  tmp = 0;
  8.  for(p = relay, mask = 1; p < relay + 8; mask <<= 1)
  9.    if(*p++)
  10.      tmp |= mask;
  11.  
  12.  relay[8] = tmp;
  13. }

Ha index helyett eleve mutatot hasznalsz, altalaban gyorsabb kodot eredmenyez. De a lenyeg a fenti megoldasban az, hogy nem kell feleslegesen nyolcszor a relay[8] valtozot felvenni, or-olni vagy and-olni, hanem csak egy atmeneti valtozoban kell osszerakni az aktiv biteket. Ettol is gyorsabb es egyszerubb kodot kapsz. Latszolag nem egyszerubb, de futasidoben jobb, mert a ciklusbol kikerult valami. Marpedig a ciklust nyolcszor hajtja vegre, tehat ott erdemes sporolni. Ha nem nyul interrupt a relay[8] valtozohoz, akkor meg a temp valtozo hasznalata sem kell, hanem a for() elott ki kell nullazni a relay[8]-at, es a for-ban meg csak beallitgatni a kivant biteket:
  1. unsigned char relay[9] = {1, 0, .... };
  2.  
  3. func(..)
  4. {
  5. unsigned char *p, mask;
  6.  
  7.  relay[8] = 0;
  8.  for(p = relay, mask = 1; p < relay + 8; mask <<= 1)
  9.    if(*p++)
  10.      relay[8] |= mask;
  11. }

Ezek a dolgok mutatjak, hogy a C nem BASIC.
(#) Sick-Bastard válasza killbill hozzászólására (») Nov 10, 2014 /
 
Köszönöm szépen az észrevételeket, megoldásokat, tanácsokat!

Azt sejtettem, hogy az én megoldásom biztos nem lesz gyors, a sok shiftelés miatt.

A funkciókat(kódokat) meg külön nagyon szépen köszönöm!
Még annyira kezdő vagyok, hogy olyannal még nem nagyon találkoztam, hogy pl. a for()-ba több változó is felvehető.

Idézet:
„Es egy orok jotanacs: SOHA ne csinalj globalis 'i', 'j' es hasonlo rovid nevo valtozokat!”


Igen ezt már valaki tudatta velem. Mivel így működött nekem, azért így hagytam, de már neki láttam e hiba kijavításának.

A teljes forráskód meg 2-3000 sor körül van jelenleg. Még van benne bőven csak teszteli célokra írt funkció is.
(#) janikukac hozzászólása Nov 12, 2014 /
 
Sziasztok!
Érdekes kérdéssel fordulok hozzátok (mielőtt még belevágnék, én abszolút nem konyítok ezekhez a mikrovezérlőkhöz): van ez a cikk s a kedves cikkírótól érdeklődtem felőle. Ő sajnos elmondta, hogy egész jó ez a szerkezet, csak olyan hiba lépett fel nála, hogyha pl. minden potmétert feltekert akkor kiakadt az eszköz, nem küldött jeleket, vagy valami hasonló. Valaki tudna segíteni, hogy ha már meg akarom építeni, akkor ne legyen hibás? Ha akadna olyan, aki kijavítaná a programot, azt igazán megköszönném.
Üdv!
(#) killbill válasza Sick-Bastard hozzászólására (») Nov 12, 2014 / 2
 
Idézet:
„Még annyira kezdő vagyok, hogy olyannal még nem nagyon találkoztam, hogy pl. a for()-ba több változó is felvehető.”

Idézet:
„A teljes forráskód meg 2-3000 sor körül van jelenleg.”

Ha kezdo vagy es mar 2-3000 ezer soros programokat irsz, akkor lehet, hogy rossz iranybol kozelited meg a tanulast. Esetleg egy direkt C nyelv oktatasara szant konyvet erdemes lenne forgatni. A C-ben nagyon sok jo dolog van, erdemes utanaolvasni. Speciel a for()-nal nincs olyan, hogy tobb valtozo is felveheto.
A for()-nak nincsen valtozoja. A for() egy olyan utasitas, amiben harom kifejezes szerepel ponytyozsvesszővel elvalasztva. Az elsot kiertekeli akkor, amikor belep a for utasitasba. A masodikat kiertekeli minden ciklus elejen, es ha az erteke nulla, akkor kilep a for()-bol, ha a kifejezes erteke nem nulla, akkor vegrehajtja a cilustorzset majd a for() utasitas harmadik kifejezeset is, es ujbol megy a masodik kif. kiertekelesere. Szoval a for a C-ben igy van definialva, szo sincs valtozokrol. Az egy mas teszta, hogy a legtobb esetben az elso reszben egy valtozot inicializalunk, a masodikban vizsgaljuk, hogy elert-e egy bizonyos erteket, a marmadikban pedig tobbnyire noveljuk azt a valtozot. De ez nem kotelezo. A harom kifejezesbol barmelyik elhagyhato. Ha a kozepsot hagyod el, akkor definicio szerint a for ciklusod vegtelen ciklus lesz. A ciklusbol a break utasitassal ki lehet ugrani, es a continue utasitassal a for() harmadik kifejezesre lehet ugrani.

A 'kifejezes' a C nyelv lelke, es nagyon fontos tudni, hogy mi az. Kifejezes lehet egy egyszeru valtozo, egy fuggveny hivas vagy konstans (alma; 10; "text"; printf()), vagy egy muvelet, amiben operatorok es kifejezesek vannak (a + 3; a >= 10; a = 10, b = 20; a = b = 10; a = b + 10; *z++; a > 10 ? 1 : 3). Minden kifejezesnek van erteke es tipusa. Ezalol kivetel a void tipusu fuggveny, mert annak nincs erteke. A legtobb operator vilagos, osszeadas, kivonas, stb. Ez ket erekkel csinal valamit es az eredmeny a kifejezes erteke. A kifejezes tipusa mar nem mindig egyertelmu, ez is megerne par mondatot. De speciel a C-ben a vizsgalatok is ugyanolyan operatorok, mint az osszeadas. Pl. az '==' operator a ket operandusat osszehasonlitja es az eredmeny tipusa mindig int, az erteke pedig 1, ha egyformak az operandusok, es 0, ha kulonboznek. Tehat az == != < > <= >= operatorok nem az if(), for() es while() specialis dolgai, mint BASIC-ben vagy Pascal-ban, hanem egyszeru muveletek. Annyira egyszeruek, hogy akar igy is hasznalhatod oket:
a = (b < c);
Ha b kisebb, mint c, akkor a 1 lesz, kulonben 0. Meg fuggvenynek is atadhatod. func(b < c);
Amit viszont tudni kell, az az operatorok precedenciaja, azaz, hogy amikor tobb operator van egy muveletben, pl a = 1 + 2 * 3; akkor milyen sorrendben lesz ez kiszamolva. Mert nem balrol jobbra, hanem elobb a szorzas, aztan az osszeadas.

A for(i = 0, mask = 1; ..) peldara visszaterve, a C nyelvben van a vesszô operátor, ami nem tesz mast, mint a vesszovel elvalasztott kifejezeseket balrol jobbra haladva szepen 'kiertekeli' es az egesz erteke es tipusa az utolso kifejezes erteke es tipusa lesz. De! Ez a vesszo nem keverendo ossze a fuggvenyek parameteratadasanal hasznalt vesszovel, sem a tombok inicializalasanal hasznalt vesszovel. Ott is hasznalhato, de akkor be kell zarojelezni: func(a, (t = 2, t + 3), c); ez harom parametert ad at a func() fuggvenynek, eloszor 'a'-t, majd 5-ot, es vegul c-t. Kozben 't' vatozot beallitja kettore.

De ezeket sokkal egyszerubb megtanulni egy C konyvbol (pl. K&R), mint masok altal irt programokbol. Lehet elni ezek ismerete nelkul is, csak akkor tizedet sem tudod kihasznalni a nyelv adottsagainak. Lehet, hogy ha ezeket ismerned, akkor csak 1000 sor lenne az a program
(#) videokartyab hozzászólása Nov 12, 2014 /
 
Sziasztok


Olvasgatom az A/D konverteres cikket. A cikk írója azt mondja, hogy mindig az alsó 2 bit zajos. Ezt honnan veszi? Vagy ez csak egy tapasztalat, mert egyelőre pl az Atmega 16 datasheet-ben ilyesmire utaló szöveget nem találtam. El tudná magyarázni valaki miről is van szó pontosan?
Cikk
(#) holex válasza videokartyab hozzászólására (») Nov 12, 2014 /
 
5V 10 biten az 5/1024=4,88mV egy kvantum. Ennyi zajt simán összeszed a környezetéből,szóval a mért érték ugrálni fog. Ha csak az első 8 bitet nézed, akkor annál már gyakorlatilag nem játszik be a zaj, hiszen itt ahhoz, hogy eggyel megváltozzon az ADC kimenete, már közel 20 mV-nyi zavart kell összeszednie, de azért ennyit nem szokott (hacsak nem olyan környezetben van és hosszúak a vezetékek is).
A hozzászólás módosítva: Nov 12, 2014
(#) rolandgw válasza killbill hozzászólására (») Nov 12, 2014 /
 
Biztosan buta a kérdésem,nemrég kezdtem a K&R könyvvel foglalkozni.Miért int típusban határozták meg az összehasonlítás eredményét,tekintettel az 1 vagy 0 eredményre ?
Csak a kíváncsiság,gondolom ez esetben,mármint a fordítás után nincs jelentősége,mert valamelyik CP utasítás lesz belőle.
(#) holex válasza rolandgw hozzászólására (») Nov 12, 2014 /
 
A kérdés nem nekem szólt és lehet, hogy rosszul gondolom a dolgot, de szerintem az az oka, hogy amikor a program lefordul gépi kódra, a gépi kódban az összehasonlítások eredményei mindig a a státuszregiszterben tárolódnak el, mégpedig úgy, hogy ha teszem azt egyenlő a két szám akkor a státuszregiszter zero bitje 1-es lesz. Utána pedig egy olyan gépi kódú utasítás jön ami azt jelenti, hogy ha 1-es a zero bit akkor ugorj (JZ) egy bizonyos memóriacímre és onnan folytasd az utasításvégrehajtást. Ha nem nulla, akkor meg nem csinál semmit a JZ, lép tovább a programszámláló és jöhet az a programrész, aminek akkor kell lefutnia, ha 0 került a zero bitre.

Namost egy nem összehasonlító műveletnél is ugyanez játszódik le. Ha kivonok 10-ből 10-et, akkor az eredmény 0 lesz, és ugyanúgy 0-ra vált a zero bit a státuszregiszterben. Egyszerűen így van fizikailag bedrótozva a processzor, hogy ennek a bitnek az értéke minden műveletvégzés után változik hogy nulla-e vagy sem.

Tehát a lényeg az, hogy gépi kód szintjén a két műveletet ugyanúgy kell kezelni, ezért csinálja ezt a C is, és pont a hardverközelisége miatt tud ennyire hatékony lenni.

Még egyszer mondom, ezt nem kell készpénznek venni, lehet, hogy nem így van, de én régebben programoztam assemblyben, és azon tapasztalatok alapján ez egy logikus magyarázatnak tűnik.
(#) videokartyab válasza holex hozzászólására (») Nov 12, 2014 /
 
Köszi a felvilágosítást. Esetleg nem tudsz valami leírást, akár könyvet amiben ez le van írva feketén fehéren?
(#) rolandgw válasza holex hozzászólására (») Nov 12, 2014 /
 
Tényleg buta volt a kérdésem,mentségemre legyen mondva,az asm után nem könnyű C-ül gondolkodni,valószínűleg fordítva is igaz. A CP is kivonási művelet,csak az eredmény nem tárolódik,csupán a flag-ek változnak.
(#) benjami válasza rolandgw hozzászólására (») Nov 12, 2014 / 1
 
Gondolom azért, mert az int mindig az adott architektúra legoptimálisabb egésze, tehát azzal tud a leggyorsabban dolgozni, valamint arra tudja a legrövidebb gépi kódot előállítani a fordító.
(#) benjami válasza benjami hozzászólására (») Nov 12, 2014 /
 
Kicsit jobban belegondolva, a 8 bites mikrovezérlőknél ez nem biztos, hogy mindig igaz, mert az int általában ott is 16 bites.
(#) killbill válasza benjami hozzászólására (») Nov 13, 2014 /
 
Azert int, mert az az 'alaptipus' a C-ben. A C nyelv minden char-t es short-ot int-re konvertal mielott valami muveletet vegez vele. Persze ez a mai optimalizalo forditokra nem igaz, ha a muvelet eredmenyehez nem fontos. Tehat pl. ha egy char valtozot csak megnovelunk eggyel, akkor azt valoszinuleg 8 biten vegzi, nem konvertal 16-ra. De az a sor, hogy:

  1. unsigned char a;
  2.  
  3.  if(a + 1 == 256)
  4.     ...

Az mar ugye 8 bites a-t hasznalva sosem lenne igaz, marpedig a valosagban a 255 utan 256 fog jonni.

Amikor a C-t kitalaltak, akkor nem nagyon voltag még 8 bites gepek. PDP-11 es tarsai azok 16, 32 meg 36 (!) bites gepek voltak.
A hozzászólás módosítva: Nov 13, 2014
Következő: »»   627 / 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