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   641 / 837
(#) kapu48 válasza rasty hozzászólására (») Jan 24, 2015 / 1
 
Ez a fajta programozó a bizonytalan működése miatt, már kiment a divatból!
A biztos működéshez sorsportnak általában kel a 10V.
Mindenesetre a szalagkábelt vedd a lehető legrövidebbre!

(Bár 3. hazavágott Mega után bizonnyal álló szőrszálakkal vágod a kukába!)
(#) kapu48 válasza kapu48 hozzászólására (») Jan 24, 2015 / 1
 
És a Reset láb 10K felhúzás + 100n szűrés nagyon kel!
A Tápfesz lábakra a 100n kerámia kondi is kötelező!
(#) rasty hozzászólása Jan 24, 2015 /
 
Rendben köszi.
(#) Gj válasza kapu48 hozzászólására (») Jan 24, 2015 / 1
 
DC motorokat vezérelnék vele. Szoftveres PWM-mel megoldható, hogy miközben kommunikál az AVR UART-on, aközben is működjön a PWM? Több szállal kéne gondolom. Lehet AVR-eken több szálat használni?
(#) kapu48 válasza Gj hozzászólására (») Jan 24, 2015 / 1
 
Ahogy csabeszq is írja megoldható!

Ha ragaszkodsz az ATtiny87-hez assemblerben írnám, Így szabadon használhatók a belső regiszterek. (5V, 16MHz-en) egészen gyors lenne.

UART kezelése mehet megszakításban.
(#) kapu48 válasza Gj hozzászólására (») Jan 24, 2015 / 2
 
Ki indulásnak ez is megteszi:
PWM: why does COM1A0 need to be set before PWM B will work

És a: while (1) {
Ki egészíteném a SW-PWM kezeléssel.}
(#) kovacsj hozzászólása Jan 24, 2015 /
 
Sziasztok!
Egy ltc1864-es modulból szeretnék adatokat nyerni, egyelőre sikertelenül. A kontroller még mindig az Atmega2561. Az SS = PB0, SCK = PB1, MOSI = PB2, MISO = PB3 lábakkal rendelkező chip-et a következőképpen inicializáltam:

  1. void spi_init() {
  2.        
  3.        
  4.         DDRB |= (bitset(PB0) | bitset(PB1) | bitset(PB2));
  5.         DDRB &= bitreset(PB3);
  6.         PORTB |= bitset(PB1) | bitset(PB2) | bitset(PB3);
  7.        
  8.         DDRG |= bitset(PG0);
  9.        
  10.         SPCR = ((1<<SPE) | (1<<SPIE) |(1<<MSTR)  | (1<<CPOL) |(1<<CPHA) | (1<<SPR0));
  11.        
  12. }


A PG0 láb végzi az ltc1864-es megszólítását, így az SS-nek tulajdonképpen semmi szerepe nincs. Bármennyit is kerestem, sehol nem találok olyan leírást, amikor a master olvas a slave egységről.
Nekem a MISO konfigurálásra lenne szükségem, és minden bizonnyal nem jól csinálom, mert a modulról semmi nem jön át.

Az ltc1864 modul adatlapja itt érhető el:

lct1864

Minden segítséget előre is nagyon szépen köszönök!
(#) kovacsj válasza kovacsj hozzászólására (») Jan 24, 2015 /
 
Lehet, hogy itt a hiba, mert az utána következő sorok nem jönnek át a bluetooth kapcsolaton.
  1. char SPI_MasterTransmit(char cData)
  2. {
  3.        
  4.         SPDR = cData;
  5.        
  6.         while(!(SPSR & (1<<SPIF)));
  7.        
  8.         return SPDR;
  9. }


Olvasni pedig így próbálom:

  1. while(1)
  2.     {
  3.        start_conversion();
  4.            _delay_ms(10);
  5.            stop_conversion();
  6.            char betu = SPI_MasterTransmit(0x01);
  7.            
  8.                 USART1_String(betu+"\n\r");
  9.                 _delay_ms(1000);
  10.     }


A start_conversion() és a stop_conversion makrók a PG0 lábat mozgatják. A stop alacsony szintre húzza a lábat.
A hozzászólás módosítva: Jan 24, 2015
(#) kovacsj válasza kovacsj hozzászólására (») Jan 24, 2015 /
 
Próbálom slave-ként inicializálni az adatlap szerint, de úgy sem jönnek az adatok. Az órajelet mindig a master adja, úgy tudom. Javítsatok ki, ha tévedek! Nekem arra lenne szükségem, hogy az Atmega2561 által adott ütemben az ltc1864-ről átjöjjenek az adatok a MISO lábon át. És nem jön semmi.
(#) killbill válasza kovacsj hozzászólására (») Jan 24, 2015 1 /
 
Idézet:
„USART1_String(betu+"\n\r");”
Ez egesz biztosan nem lesz igy jo, mert ez a betu erteket hozzaadja a "\r\n" szovegre mutato memoriacimhez es az igy kapott cimet adja at az USART_String fuggvenynek. Tehat, ha betu 0, akkor a \n\r-t irja ki, ha betu 1, akkor csak a \r-t, ha betu 2, akkor semmit, viszont, ha betu erteke tobb, mint 2, akkor akarmit is kiirhat.

Ha az SPI-n nem lathato karakter kodja erkezik, akkor a terminalon sem fog latszani.

  1. char text[4];
  2.  
  3.     ...
  4.     strcpy(text, " \r\n");
  5.     ...
  6.  
  7.     text[0] = SPI_MasterTransmit(0x01);
  8.    USART_String(text);
A hozzászólás módosítva: Jan 24, 2015
(#) kovacsj válasza killbill hozzászólására (») Jan 24, 2015 /
 
Az a baj, hogy nem jön semmi. És nem is lép tovább. Az utána következő bármit nem írja ki. Ha kiveszem az SPI-re vonatkozó sorokat, akkor a kiírás átjön. A fő problémám az lenne, hogy hogyan tudok masterként beolvasni a MISO lábra adatokat úgy, hogy az órajelet a kontroller adja, mert ezt a modult nem lehet másképp kiolvasni. Nagyon köszönöm, hogy foglalkozol a problémámmal!

  1. ISR(SPI_STC_vect) {
  2.  
  3.   byte adat;
  4.  
  5.   adat = SPDR;
  6.  
  7.  }


Most ilyesmivel próbálkozom, de ez sem hozott eddig eredményt.
A hozzászólás módosítva: Jan 24, 2015
(#) killbill válasza kovacsj hozzászólására (») Jan 24, 2015 1 /
 
Milyen tipusu AVR-t hasznalsz? Valami nem jo. Vagy hasznalsz ISR-t, es akkor ne figyeld az SPIF bitet, vagy ne engedelyezd az interruptot (SPIE), es akkor figyeld az SPIF-et. A ketto egyutt nem lesz jo. Az SPI orajel sebesseget hol allitod be?
A hozzászólás módosítva: Jan 24, 2015
(#) kovacsj válasza killbill hozzászólására (») Jan 24, 2015 /
 
  1. SPCR = ((1<<SPE) | (1<<SPIE) |(1<<MSTR)  | (1<<CPOL) |(1<<CPHA) | (1<<SPR0));


Az (1<<SPR0) fck/16-ot állít be. A kontroller órajele 7372800 Hz.

Amikor az SPDR-be adatot írok, az átvitel során ide jönnek a fogadott adatok? Jól gondolom? Körbeforgatja? Ebben az esetben interrupt is lehetne a megoldás. Most kivettem, de ugyanúgy nem jön semmi.
A hozzászólás módosítva: Jan 24, 2015
(#) killbill válasza kovacsj hozzászólására (») Jan 24, 2015 / 1
 
Ja, az jo. Akkor egyszeruen vedd ki az SPIE-t, felteve, hogy az SPI_MasterTransmit() fuggvenyed nem valtozott;
(#) rolandgw válasza kovacsj hozzászólására (») Jan 24, 2015 1 /
 
Nem 16 bitet kéne olvasnod a PG0 váltások közt ?
(#) kovacsj válasza rolandgw hozzászólására (») Jan 24, 2015 /
 
De annyit. Ám arra gondoltam, hogy a felét is meg lehet jeleníttetni. De lehet, hogy neked lesz igazad! Lehet, hogy a felső byte üres.
(#) kovacsj hozzászólása Jan 24, 2015 /
 
Úgy sem jó. Nem vigasztal, de másnak sem sikerült.

LTC1864 AVR FREAKS


Most néztem oszcilloszkóppal (kár, hogy eddig nem jutott az eszembe) és a MISO a lábon van jel.
A hozzászólás módosítva: Jan 24, 2015
(#) kovacsj válasza kovacsj hozzászólására (») Jan 24, 2015 /
 
Csak nem értékelhető.
(#) kapu48 válasza kovacsj hozzászólására (») Jan 24, 2015 1 /
 
  1. char SPI_MasterTransmit(char cData)
  2. {
  3.        itt kel PORTG0 reset, hogy aktiváld a slavet.
  4.         SPDR = cData;      
  5.         while(!(SPSR & (1<<SPIF)));
  6. ha 2 Byte a válasz? Akor a 2.-at is veni kellene
  7. itt kel PORTG0 set, hogy inaktiváld a slavet
  8.        return SPDR; Esetleg Wordot kellene vissza adni?
  9. }
(#) kovacsj válasza kapu48 hozzászólására (») Jan 24, 2015 /
 
Ígéretesnek tűnik. Köszönöm szépen! Majd holnap kipróbálom. Már elég fáradt vagyok, és így is ltc1864-ekkel fogok álmodni. A hétvégém ezzel fog elmenni, hétközben pedig nincs ilyesmire időm. Nagyon köszönöm mindannyiatoknak!
(#) Kovidivi válasza kovacsj hozzászólására (») Jan 25, 2015 1 /
 
Szerintem inkább olvasd ki az egész adatot, és dobd el, ami nem kell. ADC-nél is van olyan, hogy addig nem lép tovább, míg ki nincs olvasva a felső és alsó byte is, így akadályozza meg, hogy két különböző mérés alsó és felső byte-ját kapd vissza.
(#) killbill válasza Kovidivi hozzászólására (») Jan 25, 2015 / 1
 
Van ilyen is, van olyan is... Ugy kell kezelni, ahogy az adatlap irja!
(#) Gj válasza kapu48 hozzászólására (») Jan 25, 2015 /
 
Ilyen felépítésű program akkor megfelelő lenne, igaz?
  1. Main()
  2. {
  3.         //Kimeneti lábak beállítása
  4.         //Kitöltési tényezők beállítása
  5.         //Timerek konfigurálása
  6.         //UART konfigurálása
  7.         //TimerX indítása
  8.         //TimerY indítása
  9.        
  10.         while(1)
  11.         {
  12.                 For(Kitöltésitényezők száma)
  13.                 {
  14.                         if(TimerX<= Kitöltésitényezők[n])
  15.                             PORT? |= (1<<P?n);
  16.                         else
  17.                             PORT? &= (0<<P?n);
  18.                 }
  19.         }
  20. }
  21.  
  22. Megszakítás TimerY túlcsordulás
  23. {
  24.         //Néhány érték elküldése UART-on
  25.         //TimerY újraindítása
  26. }
  27.  
  28. Megszakítás UART fogadás
  29. {
  30.         //Kitöltési tényezők beállítása
  31. }
A hozzászólás módosítva: Jan 25, 2015
(#) killbill válasza Gj hozzászólására (») Jan 25, 2015 / 2
 
Idézet:
  1. PORT? &= (0<<P?n);

A nullat hiaba shifteled, az nulla marad.
  1. PORT? &= ~(1 << P?n);
(#) kapu48 válasza Gj hozzászólására (») Jan 25, 2015 / 1
 
Az elv jó, a gyakorlat kicsit bonyolultabb!

Ha maradunk az ATtiny87-nél, és szeretnénk magasabb külső órajelről meghajtani?
Akkor megnézve a lábkiosztást nem lesz 1 portón összefüggő 8 bitünk.
Sajnos a Pin címzés számítás bonyolultabb lesz az n++-nál

Esetleg ha kristály helyett oszcilátórt használsz, felszabadul
(#) killbill válasza kapu48 hozzászólására (») Jan 25, 2015 / 2
 
A leirt kod nem tul bonyolult, legfeljebb ami fordul belole.

  1. typedef struct {
  2.   unsigned int kitoltesi_tenyezo;
  3.   volatile unsigned char *port;
  4.   unsigned char mask;
  5. } portpin_t;
  6.  
  7. portpin_t kimenetek[] = {
  8.   {0, &PORTA, 1<<0},
  9.   {0, &PORTA, 1<<2},
  10.   {0, &PORTB, 1<<0}
  11. };
  12.  
  13. portpin_t *p;
  14.  
  15.   for(p = kimenetek; p < kimenetek + sizeof(kimenetek)/sizeof(portpin_t); ++p){
  16.     if(p->kitoltesi_tenyezo >= TimerX)
  17.       *(p->port) |= p->mask;
  18.     else
  19.       *(p->port) &= ~(p->mask);
  20.   }
  21. }
A hozzászólás módosítva: Jan 25, 2015
(#) Gj válasza kapu48 hozzászólására (») Jan 25, 2015 /
 
Lehet, hogy a dinamikus pincímzéstől eltekintek, végül is adott számú portról van szó.
Ha szoftveres PWM-et használok, akkor már ATMega8-ra gondoltam, mert sok leírás van hozzá.
(#) kovacsj hozzászólása Jan 25, 2015 /
 
Sziasztok!

Szerintetek az jó megoldás egy 16-bites számláló két csatornáját használva, ha:
  1. OCR3A = 2580;
  2. OCR3B = 5160;


És a TIMER3_COMPA_vect és TIMER3_COMPB_vect rutinjaiban kezelném le a dolgokat?
(#) Zaustuv hozzászólása Jan 25, 2015 /
 
Hi!

Ismertek esetleg olyan ingyenes programot, ami a nem szöveges fájlok adatait meg tudja jeleníteni bináris és hexadecimális formátumban?

Bocsánat ha nem pont ebbe a csoportba való a kérdés. Nem vagyok nagy fórumozó.
(#) kovacsj válasza kovacsj hozzászólására (») Jan 25, 2015 /
 
Valamit nem értek.
Ha az
  1. OCR3A = 2580;


értéket eléri, a TCNT3 nem nullázódik le?
Ebben az esetben az
  1. OCR3B = 5160;


hogyan fog teljesülni? CTC módról van szó. Output Compare.
A hozzászólás módosítva: Jan 25, 2015
Következő: »»   641 / 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