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   562 / 840
(#) matheattila válasza mps hozzászólására (») Szept 19, 2013 / 1
 
Szia, a PIND5-nek egy előre meghatározott értéke van a fordító könyvtárában, ez az érték 0x05, vagyis egy konstans nem nulla szám, azaz minden esetben igaz, így a LED mindig világít, mivel, hogy a program soha nem jut az else ágra, ami amúgy is hibás
Esetleg próbáld így:
  1. if (!(PIND & (1<<PD5)))  PORTB |=  (1<<PB2); else  PORTB &=  ~(1<<PB2);

Feltételezem, hogy a gombot a földre húzod amikor megnyomod.
(#) mps válasza matheattila hozzászólására (») Szept 19, 2013 /
 
Neked is köszi!
Szóval szokjam meg, hogy nem fog menni olyan egyszerűen.
(#) vzoole válasza mps hozzászólására (») Szept 19, 2013 /
 
Miért? Ez teljesen egyszerű.
MCU programozás 1x1 (csak szokni kell a nyelvet)

Még annyit szoktam és, hogy beteszem define-ba.
  1. #define btn1_ON      !(PIND & (1<<PIND5))
  2.  
  3. if(btn1_ON) {PORTB = PORTB |  (1<<PINB2);}
  4. else        {PORTB = PORTB & ~(1<<PINB2);}
A hozzászólás módosítva: Szept 19, 2013
(#) matheattila válasza mps hozzászólására (») Szept 19, 2013 /
 
Szivesen.
Nekem sem tetszik ez a megoldás az AVR-eknél, de ezzel kell élnünk. Én örök PIC fan vagyok, csak a meló miatt foglalkozok AVR-el is
(#) mps válasza vzoole hozzászólására (») Szept 19, 2013 /
 
Nekem is ez jutott eszembe
Matheattila: nekem is furcsa a pic után, de ha más megszokta én sem nyavalygok
(#) csabeszq válasza karika200 hozzászólására (») Szept 19, 2013 /
 
Feltételezem, hogy a cikk alapján Atmega8-at használsz, ahhoz illesztettem a D9 CF-et.

Az órajel jelentése: http://www.engbedded.com/fusecalc

Nálad jelenleg az Ext. Low Freq Crystal van kiválasztva, ha Atmega8-at használsz.

A 7.32 MHz nem tűnik számomra Low freq-nak.

http://www.atmel.com/images/atmel-2486-8-bit-avr-microcontroller-at...et.pdf
27. oldal.

Semmilyen számot nem mondok a fuse bitekre, mert a te felelősséged beállítani és semmi garanciát nem vállalok értük, hogy rendesen menni fog-e. Leírtam, hogy nálad most jelenleg mi van.
(#) csabeszq válasza matheattila hozzászólására (») Szept 19, 2013 /
 
Különbözőek vagyunk. Én is PIC-cel kezdtem, de valahol az assembly szegmentálásos részénél, meg az ingyenesen használható C fordító hiányánál besokalltam.
(az ingyenes MPLAB 4-szeres méretű kódot generál, de ez nem hatott meg, mert ha 4k-ra van szükségem nem szívesen veszek 16k-s IC-t).

Az avr-gcc sem egyszerű eset, mert magad választod meg az optimalizációt és az idők folyamán pusztán a beállítások változtatásával feleztem a kód méretét.

Hosszas bűvészkedés után a meg nem hívott metódusok kikerültek a kódból, az enum mérete 16 bites helyett akkora lett, amekkora szükséges, a call/jmp utasítások helyett a feleakkora rcall-t és rjmp-t használatát beállítottam a fordítónak és megdöbbentem a végeredményen. Mindenesetre legalább ingyenes és a lehetőség nincs elzárva, hogy normálisan fordítsak.
(#) szalaisanyi hozzászólása Szept 19, 2013 /
 
Sziasztok!
Arduino-ra írt programot át lehet valahogy írni AVR-re?
Üdv Sanyi!
(#) killbill válasza karika200 hozzászólására (») Szept 20, 2013 /
 
Ha az AVR-ed USART kimenetet visszavezeted a bemenetere, es azon nezed, hogy mit kapsz, akkor az orajel problemat ki tudod zarni. (Mert ugyanaz lesz az adonak es a vevonek) Ezzel a modszerrel tudsz kovetkeztetni HW es SW hibakra. Ehhez persze meg kell irnod az USART vetelt is.

Amikor azt mondod, hogy byte-onkent kuldve jo, akkor mennyi ido telik el a kuldesek kozott? Es mit kuldesz?

Ezt a jelenseget, amit leirsz, szerintem harom dolog okozhatja. Vagy valami hardver bizonytalansag, vagy C forditasi hiba, vagy egyeb olyan sw hiba, ami elrontja a memoriaban az 'Ez egy teszt sor' szoveget (a szoveg RAM-ban van, annak ellenere, hogy konstans string). Ennek vizsgalatara ezt a tesztet javaslom:

  1. rs232_send_line(const char *str)
  2. {
  3.  while(*str++)
  4.   rs232_send_byte('A');
  5. }
  6.  
  7. rs232_send_line("ez egy teszt sor...");

De irhatod igy is:
  1. rs232_send_line(const char *str)
  2. {
  3.  while(*str)
  4.   rs232_send_byte((*str++, 'A'));
  5. }
  6. Fontos a dupla zarojel!!!


Ha ebbol nem csupa A betuk lesznek a terminalon, akkor HW vagy sebesseg beallitas, bar utobbiban en nem hiszek. Kiveve, hogy ha olyan fuse bit beallitasi problema, amitol mondjuk az oszcillatorod mukodese bizonytalan.

Milyen HW illeszto van az AVR es a PC kozott. MAX232? Ha igen, mekkorak a kondik? Tapja rendben?
A hozzászólás módosítva: Szept 20, 2013
(#) karika200 válasza csabeszq hozzászólására (») Szept 20, 2013 /
 
Üdv!

Igen, ATmega8-al dolgozom, írtam az első hozzászólásomban. Természetesen megértem, hogy nem szeretnél mondani semmit a fuseokkal kapcsolatban, de én meg vagyok annyira következetes, hogy ha én baszom el akkor én hibáztam..

Megnéztem újra a fuseokat. A doksi 26. oldalát ha megnézed ott a 4-es táblázatot követve stimmel a CKOPT és CKSEL3..1 bitem, miszerint 3 és 8 MHz közé eső nem low frequency kvarcot használok. A CKSEL0 és SUT0 SUT1 bitjeim lehetnek esetleg kérdőjeles dolgok az én olvasatomban, mert a 28. oldal 5-ös számú táblázatát nézve a CKSEL0 bitem 1 és SUT bitjem 0 és 0 értékei együttesen azt határozzák meg, hogy KERÁMIA rezonátort használok és lassan emelem a feszt.

Tehát, amit még megpróbálnék, hogy a két SUT-ot átbillenteném 1-re, így az alsó byte 0xff lenne, a felső pedig maradna 0xd9.

Én ezt látom most, de lehet benézek valamit nagyon. Ha van valami konkrét észrevételed kérlek mondd, mert nekem már nincs. Nyilván ha "tönkrevágom" az ATmega8-amat az az én felelőségem, ennek tudatában mondj bármit legjobb tudásod szerint.

Köszönöm!

u.i.: Az oldalszámok a pdf file oldalaira vonatkoznak, nem a doksi oldalszámozására.
(#) karika200 válasza killbill hozzászólására (») Szept 20, 2013 /
 
Szia!

Igen, ezt próbáltam, annyi különbséggel, hogy PC-re szórtam az áldást. Így ha a send_line fgv. mindig egy adott karaktert szór ki, pl. 'a'-t, akkor csupa 'a'-t kapok a másik oldalon is. MAX232-vel van illesztve és kondik pedig akkorák, mint a fentebbi hozzászólásomban linkelt cikkben is. Fordítási hibán agyalok már én is, de ott sincs semmi extra. Ha otthon leszek bemásolom a fordítási paramétereimet, hátha. Tápom stabil 5V 700mA, azzal nincs gond szerintem.
(#) killbill válasza karika200 hozzászólására (») Szept 20, 2013 /
 
Ha szunet nelkul, hivod a send_byte()-ot valami fix karakterrel, es akkor jol ir, akkor szinte biztos, hogy sw hiba. Vagy forditas, vagy megserul a .const a RAM ban.

for(i = 'A' ; i < 'X'; ++i)
rs232_send_byte(i);

Itt meg csak nem is egyformak a karakterek.

A tap alatt nem a tapegyseget magat ertettem, hanem az IC tapjat. Rendes fold, rendes 5V, hidegitok... Lattam en mar 7805 kimeneten 4 es 6 volt kozott oszcillalo 1MHz-et, amit a 'mester' 5V-nak mert a multimeterrel, es kijelentette, hogy a tap jo. A ket darab keramia 100nF meg még jobb... Nem tudom, hogy mennyire vagy szaki, csak probalok segiteni, es feltetelezek mindent, ami gondot okozhat
(#) karika200 válasza killbill hozzászólására (») Szept 20, 2013 /
 
Sajnos szaki egyáltalán nem vagyok, így könnyen elképzelhető, hogy valami HW-esen nem jó. Kondenzátoraim pl. csak a kvarcnál vannak az ATmega8 környékén. Hova mekkora értékeket javasolsz még? Az a baj, hogy nekem a legkomolyabb műszerem egy alap multiméter. Sajnos se szkópom se semmim. Megpróbálok majd ciklusból karaktereket szórni a terminálra, azt még nem próbáltam azt hiszem. Mesélek majd azzal mire jutottam. Köszi.
(#) csabeszq válasza karika200 hozzászólására (») Szept 20, 2013 /
 
A D9 CF az nem jó, viszont a CF D9 az igen.

Felcseréltem a low/high fuse byte-okat. A hiba akkor valószínűleg nem itt van, maradhat úgy, ahogy van.
A hozzászólás módosítva: Szept 20, 2013
(#) csabeszq válasza killbill hozzászólására (») Szept 20, 2013 /
 
Erről írtam, hogy nem látjuk a másik oldalt, ezért segíteni se sokat tudunk. Az első karakter ugye rendben megérkezik.

- ez lehet azért, mert a legelső betű végén 000 vagy 111 bitek vannak és az időelcsúszás nem okoz benne problémát, csak a következőben
- lehet azért, mert a stop bitek nem stimmelnek, a vevőnek több idő kell a következő start jelig (ez PC-n nem hiszem, hogy gáz)
- a PC paritást vár, mialatt a küldőnél nincs paritás bekapcsolva és a következő start jel lesz a paritás, utána meg elcsúszik minden
- a PC 7 biten várja az adatokat, az AVR 8 biten küld
...
(#) killbill válasza csabeszq hozzászólására (») Szept 20, 2013 /
 
Speciel az elso betu 'E', ami ugye 0x45, a sorosvonalon: 0 10100010 1.
De azt irta, hogy ha egyforma karaktereket kuld, akkor az jo, es azt is mondta, hogy a terminalt jol allitotta be. Csak nem kerek egy screenshot-ot a terminalrol is. Tetelezzuk fel, hogy amit kulon magatol leirt, azt nem rontotta el. De, ha mondjuk az adasbol adodo terhelestol (ezt magam sem hiszem) megrogyik a tapja, abbol barmi is lehet. Multkor szivott egy ismerosom egy WiFi modullal, amibol a rovid packetek jol atmentek a PC-re, de 300 byte-os csomagok mar nem erkeztek meg a tuloldalra. Kerlek szepen, a panelon felepitett tapegyseg aramkorlatja behatarolt, amikor a WiFi modul elkezdett 2..300mA-t felvenni. Az elso 10-20 byte idejere meg volt eleg craft az elkokban, de aztan elfogyott. Ilyenkor egy tarolos szkop tobbet er minden okoskodasnal.
(#) vzoole válasza mps hozzászólására (») Szept 20, 2013 /
 
Itt van még egy megoldás haladóknak
Bővebben: Link
(#) csabeszq válasza killbill hozzászólására (») Szept 20, 2013 /
 
Túlterhelés esetén nem jönnek krix-kraxok, hanem karaktereket veszít.

Krix-krax akkor jön, ha a hardver elveszíti a start jelet.

Volt szerencsém adatvesztéshez, azóta PC oldalon egy szál kizárólag azzal foglalkozik, hogy az RS-232-esen csüng. Ha jön valami infó, akkor átdobja egy másik szálnak, amelyik feldolgozza.

Viszont adatvesztés nem 15 karakteres sztringeknél jött elő.
(#) killbill válasza csabeszq hozzászólására (») Szept 20, 2013 /
 
Erre inkabb nem nem valaszolok, mert sosem lenne vege, es nem akarok offolni...
(#) karika200 válasza killbill hozzászólására (») Szept 20, 2013 /
 
Nos, megpróbáltam a-tól z-ig ciklussal kiszórni pár byteot, az eredmény: siker. Tehát ha fogok egy for ciklust és 'a'-tól 'z'-ig pörgetem szépen kijönnek a byteok a másik oldalon. Tehát olyan, mintha a pointer eleve krix-kraxokra mutatna. Csináltam egy screenshotot a pointerből kiíratásról és ezen egyúttal látszanak a terminál beállítások is. A screenshot itt érhető el.

Annyi változott időközben, hogy nem USB-RS232 konverteres majomságra van dugva, hanem natív soros portra. Ez nem javított vagy rontott a helyzeten semmit. Jelen esetben működnie kell USB-s konverterrel is, mivel csak az RX, TX lábak vannak használva, az meg átmegy az összes USB-s vackon. De a továbbiakban maradok a natív sorosportnál, ezzel is csökkentve a hibák lehetőségét.

Most még megpróbálok ráakasztani egy másik tápegységet és jól megpufferelni valami böszme kondival, hátha...
(#) csabeszq válasza karika200 hozzászólására (») Szept 20, 2013 /
 
Idézet:
„ha fogok egy for ciklust és 'a'-tól 'z'-ig pörgetem szépen kijönnek a byteok a másik oldalon.”


Az RS232 vagy megy, vagy nem megy. Ha 'a'-'z'-ig mindenféle sleep nélkül átpörgeted a bájtokat és a túloldalon még meg is jelenik, akkor szoftverhibáról beszélünk.

Nem férek innen hozzá a kódodhoz, de ha használsz PROGMEM-et, PSTR-t és társait (flash-ben tárolni a string-et), ezek után szimpla char * pointerrel olvasod ki, akkor ehhez hasonló hibát fogsz kapni: a pointer a flash-re mutat, de a kiolvasás SRAM-ból történik.
A hozzászólás módosítva: Szept 20, 2013
(#) killbill válasza karika200 hozzászólására (») Szept 20, 2013 /
 
Nem a tappal van itt baj, es nem is az USB/nativ sorosvonallal. Hardveresen csak annyit az elozo kerdesedre, hogy 100nF keramia vagy inkabb multilayer kondenzatort tegyel az AVR es a tobbi IC tap labaira. A leheto legrovidebb labbal (1-2 centis drottal mar nem biztos, hogy van haszna, de ez frekvencia- es aramfuggo dolog.) Ez azert kell, mert nagyfrekvencias szempontbol a tapokhoz vezeto foliak altalaban nem kivanatos soros induktivitasa csunya feszultsegugrasokat produkal az IC-k tap labain a hirtelen aramvaltozasok miatt. Ez alapveto dolog, de meg analog technikaban is (erositoknel, komparatoroknal), hogy a tapot hidegitik. Ez persze csak akkor er valamit, ha legalabb a fold garantaltan kisimpedancias. Egybefuggo felulet. Ketretegu paneloknal az egyik reteget tobbnyire a fold vezetesere illik hasznlani, a tapokat meg jo vastagon, es kondi minden IC melle.

A problemad szerintem sw-es jellegu. Szerintem az inicializalt adat nem jo a RAM-ban. Arrol van szo, hogy a "szoveg" bent van a flash-ben, hiszen valahol lennie kell, de amikor a program fut, akkor a pointerek mar csak RAM cimeket tartalmazhatnak, mert az AVR a flash-t nem tudja ugy olvasni, mint a RAM-ot (Harvard arch.). Ezert az osszes inicializalt adat es const adat a program indulasa elott bekerul a RAM-ba. Ezt a legtobb modern fejlesztorendszeren elrejtik eloled, altalaban a programodhoz linkelt crt0 megoldja. Ha a reset vektortol kezdve te irod az egesz kodot, es a gcc linkere sem ad hozza a kododhoz extra _init_bss es egyeb magikus dolgokat, akkor az a te dolgod, hogy inicializald a bss es a data szegmenseket.

A programod csinal barmit, mielott ezt a send_line()-t meghivja? Arra gondolok, hogy esetleg valami felulirja a RAM-ban a szoveget. Ha jol latom, ez Linux (/dev/ttyS0). Milyen compiler, kornyezet, stb?
(#) csabeszq válasza csabeszq hozzászólására (») Szept 20, 2013 /
 
Végre megnézhettem a kódodat. Amit találtam az nem hiba, de azért megemlítem:

Amit te írtál:
  1. #define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * 16UL)) - 1)


Amit én használok:
  1. UBRR0 = (uint8_t)( (F_CPU + BAUD_RATE * 8L) / (BAUD_RATE * 16L) - 1 );


Minthogy 7.3728MHz-es kristályt használsz, kerekítési hibád nem lesz, a két hívás ugyanazt fogja visszaadni. De: ha eszedbe jutna más kristályt használni, ahol még véletlenül sem egész számok jönnek ki, okozhat problémát, amikor a 11.9-et mondjuk 11-re kerekíted 12 helyett.
(#) csabeszq válasza csabeszq hozzászólására (») Szept 20, 2013 /
 
Emellett Arduino-ra feltöltöttem a kódodat (16MHz Atmega328P módosításokkal) és ment. Nálam nem volt baj, még a kerekítési hibával sem.
(#) karika200 válasza killbill hozzászólására (») Szept 20, 2013 /
 
Nem csinál semmit. Csak egy init hívás van aztán send_byte. Fejlesztő örnyezetről nem nagyon beszélhetünk, egy gedit-et(közönséges plain text editor) használok és avr-gcc-t, így:

Idézet:

avr-gcc -mmcu=atmega8 -pedantic -Wall -O4 -D F_CPU=7372800UL -o thermometer.elf thermometer.c
avr-objcopy -j .text -O ihex thermometer.elf thermometer.hex


A fordítás során se warning se error nem keletkezik. Utána avrdude-al és egy stk200 programozóval felírom.

Nem használok PROGMEM-et és semmi hasonlót, simán konstanst próbálok meg átadni a függvényemnek, de úgy sem akarja az igazat... Kezdem kicsit misztikusnak találni a hibát, pláne, ha megy másik MCU-n. Már lövésem sincs mire gondoljak. Esetleg ha van valami kész kódotok elfekvőben, ami csak UART-ot rángatja és meg tudnátok osztani, annyit megtennék, hogy kipróbálom azt. Esetleg hogyan paraméterezitek a fordítót?
(#) mps válasza karika200 hozzászólására (») Szept 20, 2013 /
 
Tegnap szórakoztam vele, így ez kéznél van, elsősorban innen összeollózva:
  1. #include <avr/io.h>
  2.         #include <avr/interrupt.h>
  3.         #include <inttypes.h>
  4.     #include <util/delay.h>
  5.        
  6.     //-------------------------------------
  7.     void m_delay_10ms(unsigned char val) {
  8.     //-------------------------------------
  9.     //a _delay_ms max 65.535 ms-et képes sleepelni,
  10.     // tehát nagyobb időzítést többől lehet "összerakni"
  11.         unsigned char i;
  12.         for(i=0;i<val;i++) {
  13.             _delay_ms(10);
  14.         }
  15.     }  
  16.        
  17.        
  18. void UARTAdatKuld(char data)  // Ez a fuggveny a kuldendo adatot beirja az UDR regiszter kimeno pufferjebe
  19. {
  20.    while(!(UCSRA & (1<<UDRE))) // Varakozas amig az Ado kesz nem lesz az adatkuldesre
  21.    {
  22.       //   Varakozas
  23.    }
  24.    // Az Ado mar kesz az adatkuldesre, a kuldendo adatot a kimeno pufferjebe irjuk
  25.    UDR=data;
  26. }      
  27.        
  28.  
  29. int main(void)  // Foprogram
  30. {      
  31.         //PORTD = 0x2C;
  32.         //DDRD = 0x02;
  33.         UCSRB = 0x08;   // (1<<TXEN)
  34.         UBRRL = 0x40;
  35.  
  36.  while(1)
  37.    {
  38.                                 UARTAdatKuld('u');
  39.                                 UARTAdatKuld('\n');     // Kovetkezo sor
  40.                                 UARTAdatKuld('\r');
  41.    
  42.    m_delay_10ms(200);
  43.    
  44.    }
  45.  
  46.  
  47.        
  48. return 0;
  49. }

10MHz kvarrcal, Atmega8.
A hozzászólás módosítva: Szept 20, 2013
(#) Szabi1 hozzászólása Szept 20, 2013 /
 
AVR-el ADC vel feszültséget mérnék Bővebben: Link

1.Nekem egy aksit kell mérjen és % ban kéne kifejezzem, az adott hogy 21,84v on kéne mutasson 10% ot , 24v on 100%-ot milyen képlettel lehet megoldani?

2. LCDWriteIntXY() függvénynél ha változóértéket irnák ki pl: LCDWriteIntXY(1,1,percent,2); akkor milyen típusú változó lehet?
(#) killbill válasza karika200 hozzászólására (») Szept 20, 2013 /
 
Eh! Hol vannak a vektrok? Es ki linkeli ezt le?
Lehet, hogy valamit nem jol tudok, de ebbol nekem hianyzik egy avr-ld.
Szerintem az a gond,hogy a stringed szerintem nem a .text szegmensben lesz, hanem valami .const vagy .rodata vagy egyebben. Nem beszelve a C support fuggvenyekrol. Nem a szabvany konyvtarrol beszelek, hanem pl. ha irsz egy long szorzast, akkor a C fordito mindenfele _mul.. fuggvenyhivasokat fordit be. Azokat adjak a gcc-vel, ahogy a header-eket is.

avr-gcc --version mit mond?
(#) karika200 válasza mps hozzászólására (») Szept 20, 2013 /
 
Köszönöm, de ez szintén byteonként küld adatot, ami nálam is oké. A gondok nálam akkor kezdődnek mikor egy stringet szeretnék kiküldeni.
(#) mps válasza karika200 hozzászólására (») Szept 20, 2013 /
 
A Te kvarcodra:
  1. UCSRB = 0x08;   // (1<<TXEN)
  2.         UBRRL = 0x2F;

Ha minden igaz
9600bpm
Következő: »»   562 / 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