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   504 / 840
(#) zombee válasza Syrius hozzászólására (») Jan 5, 2013 /
 
Valamit félreértesz, nagyon is! Az egység egy szó(2 bájt).
A flash tartománya így 0x0000-0x7fff.
(#) Robi98 hozzászólása Jan 5, 2013 /
 
Sziasztok!
Szerettem volna készíteni egy olyan programot ami szoftveres PWM segítségével egy másodpercenként megváltoztatja egy led fényerejét. A a TCNTx-et és az OCRx-et két változó helyettesíti. A program nem sikerült, a led nem világít. Az áramkört ATmega8 mikroprocesszorral és 1MHz órajellel készítettem el.
A kód:
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3. #include <avr/interrupt.h>
  4.  
  5. volatile int szamlalo=0,ledertek=0;
  6.  
  7. ISR(TIMER2_COMP_vect)
  8. {
  9. szamlalo++;
  10.    if(szamlalo==256)
  11.    {
  12.    szamlalo=0;
  13.    }
  14.    
  15.    if(szamlalo<=ledertek)
  16.    {
  17.    PORTB|=(1<<PB1);
  18.    }
  19.   if(szamlalo>ledertek)
  20.    {
  21.    PORTB&=~(1<<PB1);
  22.    }
  23. }
  24.  
  25. int main(void)
  26. {
  27. DDRB|=(1<<PB1);// PB1 kimenet
  28. TCCR2|=(1<<WGM21);//CTC mód
  29. TCCR2|=(1<<CS20);//előosztás 1
  30. TIMSK|=(OCIE2);//megszakítás a párosodás végén
  31. OCR2=1;//        1/1000000 masodpercenként megszakítás
  32. sei();// globális interrupt engedélyezése
  33.  
  34.     while(1)
  35.         {
  36.         ledertek=50;
  37.         _delay_ms(1000);
  38.         ledertek=200;
  39.         _delay_ms(1000);
  40.         }
  41. }
A hozzászólás módosítva: Jan 5, 2013
(#) blackdog válasza Robi98 hozzászólására (») Jan 5, 2013 /
 
Szia!

Puskázz innét: Bővebben: Link
(#) neptunes4you hozzászólása Jan 6, 2013 /
 
Üdv! Szeretnék készíteni egy egyszerű I2C-s eszközt vezérlő programot a TWI interrupt vektor kihasználásával. Van valami ötletetek erre? Az ADC interrupt vektor már megy, de ezzel még nem tudtam zöld ágra vergődni. Minden válaszért köszönet!
(#) TavIR-AVR válasza neptunes4you hozzászólására (») Jan 6, 2013 /
 
Arduino alatt nagyon egyszerű:
wire.begin(cím)

A mögöttes függvénykönyvtárból mindent ki lehet puskázni, ha natív C-ben akarod...
(#) neptunes4you válasza TavIR-AVR hozzászólására (») Jan 6, 2013 /
 
Simán C-ben szeretném. Köszönöm szépen, megnézem.
(#) zombee válasza neptunes4you hozzászólására (») Jan 6, 2013 /
 
A "normál" I2C megy? Egy egyszerű(pl. nyomógombos vagy időzítős) interrupt is?
Ha bármelyikre NEM a válasz akkor az garantált szívás lesz az elejétől a végéig.
De a legtöbb esetben értelme sincsen, mert az a "szokás" hogy a program bevárja az I2C eszközt.
Talán EEPROM égetőnél. Egyszerűbb ott is ha egyedül csak az USART-ra van interrupt,
meg két ringbuffer. A "főciklus" meg mást nem csinál mint bevárogatja a TWI-t.
(#) csabeszq válasza neptunes4you hozzászólására (») Jan 6, 2013 /
 
Felmész a www.atmel.com-ra.

Rákeresel az AVR310, AVR311, AVR312, AVR315-re. Ráklikkelsz a download software-re.

Ezek mintapéldák.
Attiny: TWI slave USI-ra, TWI master USI-ra
Atmega: TWI slave, TWI master

Az Attiny hardverből kevésbé támogatja a TWI-t, oda kell az USI és egy kicsit több szoftver.
A hozzászólás módosítva: Jan 6, 2013
(#) Istvanpisti válasza neptunes4you hozzászólására (») Jan 6, 2013 /
 
Szia !
Fizikus fórumtárs cikke itt aHE-n elérhető I2C témában (is).
Bővebben: Link
(#) neptunes4you válasza zombee hozzászólására (») Jan 6, 2013 /
 
A normál I2C megy, Peter Fleury I2C libraryjével, ahol megvárja a TWI-t. A timeres interrupt is okés, épp most írtam meg hozzá egy progit. Lehet jobban járok ha maradok annál, hogy szépen megvárja a TWI-t...
(#) zombee válasza neptunes4you hozzászólására (») Jan 6, 2013 /
 
Ha nincs FELTÉTLEN szükség az interruptolásra, akkor a bevárást ajánlom.
Nagyon sok művelet - és most nem csak AVR-ről beszélek - arra épül hogy az I2C kommunikáció
sikeressége vagy eredménye (válaszul kapott érték) határozza meg a későbbi teendőket.

Persze lehet olyan alkalmazás - pl. webszerver - ahol az I2C kommunikáció mellékes,
de ezek már a felépítésükből fakadóan jóval bonyolultabbak mint egy mezei hőmérő vagy EEPROM égető.
(#) Syrius válasza zombee hozzászólására (») Jan 6, 2013 /
 
Áhhh, tudtam, hogy elsiklottam valami felett...

Köszi! Így már tiszta.
(#) zoltan0801 hozzászólása Jan 6, 2013 /
 
Helo!
Remélem jó topic-ba teszem fel a kérdést, hol tudok beszerezni AVR Pocket programmer-t, és hozzá azt a kisebb panelt, ami a szalagkábel másik oldalára megy, és 6 tüske van rajta. Most kezdem a programozást AVR-el, úgyhogy elnézést ha valamit hülyén írtam le.
(#) neptunes4you válasza zombee hozzászólására (») Jan 6, 2013 /
 
Ez igaz, itt ADC és DAC lesz majd rajta, egy DAC-rel vezérelt labortápot szeretnék összerakni. Na majd meglátjuk mi sül ki belőle. Tanáraim segítenek a suliban az analóg részét összerakni, azzal ugyanis kicsit hadilábon állok...
(#) Sick-Bastard válasza Istvanpisti hozzászólására (») Jan 6, 2013 /
 
Köszönöm szépen mindenkinek a segítséget!

Most már tudok haladni a kódommal.
Tesztelni még nem tudom, várok pár alkatrészt HS-ból, aztán meglátom mit is alkottam.

SB
(#) kurosaki hozzászólása Jan 6, 2013 /
 
Sziasztok.Az elözö probléma megoldodott véletlen rosszul néztem a bekötést pedig ugyan ugy volt a fej ahogy a képen is... na szoval kérdésem az hogyan tudom üresen jaratni az AVR mig nem kap 1 jelet él lefut a program?irok egy példát:
PB1 en kap egy pillanatnyi jelet erre elindul a program.
azonositasi példa:
PB1 jel be észleli hogy 1 esre vált vagy épp az indito mezö 1 ekkor az indito parancs lefut.

Erre tudtok kod részletet? mert a neten nem nagyon találtam Előre is köszönöm.
(#) zombee válasza kurosaki hozzászólására (») Jan 7, 2013 /
 
Sajnos a kérdésed második részét nem értem, az első meg olyan egyszerű hogy már le se merem írni:
  1. #include<avr/io.h>
  2. int main(void)
  3. {
  4.   while(PINB&1);
  5.    //itt jön a kódod...
  6. }
(#) kurosaki válasza zombee hozzászólására (») Jan 7, 2013 /
 
Köszönöm igen sajna ^^ bonyolultan fogalmazok. Nekem csak a bemenet vizsgalat kellet köszönöm a segitséget. Irok majd ha sikerült a projectem.Köszönöm.
(#) zombee válasza zoltan0801 hozzászólására (») Jan 7, 2013 /
 
Őszintén megvallom, az "AVR Pocket programmer" kifejezést most hallom először,
általában ilyen kompakt klónokat érdemes keresni: STK500, AVRISP(-mkII), JTAG ICE, stb.
IC-s adaptert szerintem elég könnyű építeni, lévén csak 6 vezetéket kell bekötni.
(#) zombee válasza kurosaki hozzászólására (») Jan 7, 2013 /
 
Ha esetleg meg is akarnád ismételni a leállítást akkor interrupt kell.
Pl. az INT0-t beállítod FEL-futó élre, az interrupt kezelőjében ugyanezt a lekérdezős várakozást
teszed be, így LE-futó élnél folytatódik a program. Újabb FEL-futó élre megint meg fog állni.
Hadd ne írjam le a kódot, plusz 3 sor!
(#) kurosaki válasza zombee hozzászólására (») Jan 7, 2013 /
 
Rendben nem kell megoldom köszönöm a segitséget még1 szer.
(#) bzsombix hozzászólása Jan 7, 2013 /
 
Sziasztok!

A segítségeteket szeretném kérni.

Atmega16a-val egy sinusz jel digitalizálása.

void adc_init()
{
ADCSRA=0b10000111;
}


int read_voltage()
{
ADMUX=0b01000000;
ADCSRA|=(1<<6);
while(ADCSRA & (1<<6));
return ADC;
}

Az interrupt:

SIGNAL(SIG_OUTPUT_COMPARE2){
y=read_voltage();
x=(y*5000)/1023;


}

Valakinek otlete? Sajnos nem mukodik.>>>>
A hozzászólás módosítva: Jan 7, 2013
(#) csabeszq válasza bzsombix hozzászólására (») Jan 7, 2013 /
 
Én konkrétan ISR-t szoktam használni interruptra.

ISR(TIMER2_COMP_vect)
{
...
}

Milyen megfontolásból használod a SIGNAL formát?
Van itt egy link, ami szerint állítólag ez régi jelölés.

Mindenesetre ha a lefordított kódot megnézed, láthatod benne, hogy ki van-e töltve az interrupt vektor rendesen. Ha nincs, akkor az a baj.

És miért nem az ADC_vect-et használod, amit akkor küld, amikor az ADC-t befejezte?
A hozzászólás módosítva: Jan 7, 2013
(#) bzsombix hozzászólása Jan 7, 2013 /
 
Hát ez így sem jó. Leírom az egész kódot. A display() függvény 4 darab 7 szegmentesre ír ki....
  1. #include <avr\io.h>
  2. #include<stdlib.h>
  3. #include<avr\interrupt.h>
  4. #include <util\delay.h>
  5.  
  6. volatile int x,p,c,y;
  7.  
  8.  
  9. void display(int p, int c){
  10.  
  11.   PORTC=0b00000000;
  12.   PORTB=0b11111111;
  13.   switch (p){
  14.     case 1: PORTC=~(0b00000001);
  15.     break;
  16.     case 2: PORTC=~(0b00000010);
  17.     break;
  18.     case 3: PORTC=~(0b00000100);
  19.     break;
  20.     case 4: PORTC=~(0b00001000);
  21.     break;
  22.  
  23.     }
  24.   switch (c){
  25.     case 0: PORTB=0b11000000;
  26.     break;
  27.     case 1: PORTB=~(0b00000110);
  28.     break;
  29.     case 2: PORTB=~(0b01011011);
  30.     break;
  31.     case 3: PORTB=~(0b01001111);
  32.     break;
  33.     case 4: PORTB=~(0b01100110);
  34.     break;
  35.     case 5: PORTB=~(0b01101101);
  36.     break;
  37.     case 6: PORTB=~(0b01111101);
  38.     break;
  39.     case 7: PORTB=~(0b00000111);
  40.     break;
  41.     case 8: PORTB=~(0b01111111);
  42.     break;
  43.     case 9: PORTB=~(0b01101111);
  44.     break;
  45.     }
  46. }
  47.  
  48.  
  49.  
  50. void adc_init()
  51. {
  52.     ADCSRA=0b10000111;
  53. }
  54.  
  55.  
  56. int read_voltage()
  57. {
  58.     ADMUX=0b01000000;
  59.     ADCSRA|=(1<<6);
  60.     while(ADCSRA & (1<<6));
  61.     return ADC;
  62. }
  63.  
  64. timer0_init()
  65. {
  66.     TCCR0=0b00001010;
  67.  
  68.     TIMSK|=1<<1;
  69.     OCR0=200;
  70. }
  71.  
  72. timer2_init()
  73. {
  74.     TCCR2=0b00001101;
  75.  
  76.     TIMSK|=1<<7;
  77.     OCR2=125;
  78. }
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89. ISR(ADC_vect){
  90.         y=read_voltage();
  91.         x=(y*5000)/1023;
  92.  
  93.    
  94. }
  95.  
  96.  
  97. SIGNAL(SIG_OUTPUT_COMPARE0){
  98.     _delay_ms(300);
  99.         p++;
  100.                 switch(p)
  101.     {
  102.         case 1: c=(x/1000)%10;
  103.         display(p,c);
  104.         break;
  105.         case 2: c=(x/100)%10;
  106.         display(p,c);
  107.         break;
  108.         case 3: c=(x/10)%10;
  109.         display(p,c);
  110.         break;
  111.         case 4: c=x%10;
  112.         display(p,c);p=0;
  113.         break;
  114.        
  115.        }
  116.  
  117.  
  118. }
  119. int main(){
  120.     DDRC=0b01111111;
  121.     DDRB=0b01111111;
  122.     DDRA=0b00000000;
  123.         adc_init();
  124.     timer0_init();
  125.     timer2_init();
  126.  
  127.     sei();
  128.     while(1);
  129. }


Az ISR-ven abszolút nem megy.
(#) bzsombix hozzászólása Jan 7, 2013 /
 
Na így működik, csak nem mutat helyes értéket.
  1. #include <avr\io.h>
  2. #include <stdlib.h>
  3. #include <avr\interrupt.h>
  4. #include <util\delay.h>
  5.  
  6. volatile int x,p,c,y;
  7.  
  8.  
  9. void display(int p, int c){
  10.  
  11.   PORTC=0b00000000;
  12.   PORTB=0b11111111;
  13.   switch (p){
  14.     case 1: PORTC=~(0b00000001);
  15.     break;
  16.     case 2: PORTC=~(0b00000010);
  17.     break;
  18.     case 3: PORTC=~(0b00000100);
  19.     break;
  20.     case 4: PORTC=~(0b00001000);
  21.     break;
  22.  
  23.     }
  24.   switch (c){
  25.     case 0: PORTB=0b11000000;
  26.     break;
  27.     case 1: PORTB=~(0b00000110);
  28.     break;
  29.     case 2: PORTB=~(0b01011011);
  30.     break;
  31.     case 3: PORTB=~(0b01001111);
  32.     break;
  33.     case 4: PORTB=~(0b01100110);
  34.     break;
  35.     case 5: PORTB=~(0b01101101);
  36.     break;
  37.     case 6: PORTB=~(0b01111101);
  38.     break;
  39.     case 7: PORTB=~(0b00000111);
  40.     break;
  41.     case 8: PORTB=~(0b01111111);
  42.     break;
  43.     case 9: PORTB=~(0b01101111);
  44.     break;
  45.     }
  46. }
  47.  
  48.  
  49.  
  50. void adc_init()
  51. {
  52.     ADCSRA=0b10000111;
  53. }
  54.  
  55.  
  56. int read_voltage()
  57. {
  58.     ADMUX=0b01000000;
  59.     ADCSRA|=(1<<6);
  60.     while(ADCSRA & (1<<6));
  61.     return ADC;
  62. }
  63.  
  64. timer0_init()
  65. {
  66.     TCCR0=0b00001010;
  67.  
  68.     TIMSK|=1<<1;
  69.     OCR0=200;
  70. }
  71.  
  72. timer2_init()
  73. {
  74.     TCCR2=0b00001101;
  75.  
  76.     TIMSK|=1<<7;
  77.     OCR2=125;
  78. }
  79.  
  80.  
  81. ISR(TIMER2_COMP_vect){
  82.         y=read_voltage();
  83.         x=(y*5000)/1023;
  84.  
  85.    
  86. }
  87.  
  88.  
  89. SIGNAL(SIG_OUTPUT_COMPARE0){
  90.     _delay_ms(300);
  91.         p++;
  92.                 switch(p)
  93.     {
  94.         case 1: c=(x/1000)%10;
  95.         display(p,c);
  96.         break;
  97.         case 2: c=(x/100)%10;
  98.         display(p,c);
  99.         break;
  100.         case 3: c=(x/10)%10;
  101.         display(p,c);
  102.         break;
  103.         case 4: c=x%10;
  104.         display(p,c);p=0;
  105.         break;
  106.        
  107.        }
  108.  
  109.  
  110. }
  111. int main(){
  112.     DDRC=0b01111111;
  113.     DDRB=0b01111111;
  114.     DDRA=0b00000000;
  115.         adc_init();
  116.     timer0_init();
  117.     timer2_init();
  118.  
  119.     sei();
  120.     while(1);
  121. }
(#) bzsombix hozzászólása Jan 7, 2013 /
 
Megvan! Működik. Csak sajnos a szinusz jel negatív értékeire. A pozitívakra miért nem?
Lehet hogy a (Vpoz-Vneg)*GAIN*512/Vref konverziot kellene hasznalni?

(#) kiborg hozzászólása Jan 7, 2013 /
 
Hali!

Leakadtam az ADC használatával.
Adott egy 25kOhmos poti, közepe ADC0 csatorna, két vége GND és +UT=4,8V.
A ADC0-án mérek 1,825V-t. Nálam AREF=AVCC= RC szűréssel +UT.
ADMUX-ban csak ADLAR=1, és REFFS1=1, és REFS0 =1,többi 0. Tehát referenciafeszültségem 2,56V. Kimeneten ott a 100nF kondi.
Ezáltal a ADC értékének (ADC=Vin*1024/Vref) 2DA hex-nek kellene lennie. Viszont nálam 1D8 hex az érték. Miért nem annyi, mint amennyinek lenne kellene? Máskor már használtam azt a szerencsétlen ADC-t és nem volt ilyen problémám. Tud valaki valami okosat mondani? Kipróbáltam azt is, hogy AREF-t vagy AVCC-t állítottam be, az eltérés akkor is megvolt az előírttól. Másik kérdés: AVCC és AREF össze van kötve és 10kOhmos ellenállás +UT-re húzva és egy 100nF kondival GND felé hidegítve. Okozhat ez gondot?
Üdv Kiborg
ui: ATMEGA16 az alany
A hozzászólás módosítva: Jan 7, 2013
(#) csabeszq válasza kiborg hozzászólására (») Jan 7, 2013 /
 
Nálam azzal ment el három nap, hogy ADC0 helyett ADC5-öt mértem. Az áthallás meglehetősen jó volt, csak sok volt hozzá a zaj.

Reagált a potméterre rendesen.

(#) kiborg válasza csabeszq hozzászólására (») Jan 7, 2013 /
 
Köszi, de ezt kizártam már.
Több csatornát is használok, ahol ugyanez a jelenség van. Csak egyet írtam le az egyszerűség kedvéért.
(#) Istvanpisti válasza kiborg hozzászólására (») Jan 7, 2013 /
 
Szia !
Idézet:
„Nálam AREF=AVCC= RC szűréssel +UT.”

Szerintem az AREF láb és a test közé 100nF kondenzátor kell, ha az UREF=AVCC, vagy, ha az UREF=Internal reference (2,56V). Ha külső referencia feszültséget akarsz használni , akkor azt kell oda kötni. Az AREF és az AVCC ellenállással való összekötése eltolhatja a referencia feszültségét az ADC-nek. Kérdés : miért kötöd össze az AVCC és az AREF lábat ?
A mellékelt első kép nagyon beszédes, ha REFS0 értéke 0, akkor külső referencia feszültségről megy az ADC.
Ha a REFS0 értéke 1 akkor, vagy AVCC a referencia, vagy a belső 2,56 V (a REFS0-hoz tartozó FET vezet), ekkor REFS1 értéke dönti el melyik, ekkor nem célszerű az AREF lábat külső potenciálra kötni.

A második képen az AVCC szűrése látható.
A hozzászólás módosítva: Jan 7, 2013
Következő: »»   504 / 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