Fórum témák
- • Erősítő mindig és mindig
- • Mosogatógép hiba
- • Audiofil, High End Audio
- • Vicces - mókás történetek
- • Biciklilámpa / bringalámpa
- • Vegyes barkácsfogások
- • Számítógép hiba, de mi a probléma?
- • Hűtőgép probléma
- • Mobiltelefon 50 évig
- • LED-es világítás
- • Frekvenciaváltó
- • Arduino
- • Műhelyünk felszerelése, szerszámai
- • Erősítő építése elejétől a végéig
- • Érdekességek
- • Eredményjelző
- • Sütő javítás
- • PC hűtés fordulatszám szabályzott ventilátorral
- • LCD TV probléma
- • RC távirányítás modellekhez
- • Sárga Kazettás Piaci Nintendo (8bit)
- • Inverteres hegesztőtrafó
- • Elektromos kerékpár akkumulátorának helyettesítése
- • Analóg oszcilloszkóp javítása
- • Házilag építhető fémkereső
- • Fejhallgató erősítő
- • Ultrahangos párásító
- • Elektronikai témájú könyvek újságok
- • Akkumulátoros fúró
- • Vásárlás, hol kapható?
- • Retro számítógépek
- • Tranzisztor teszter
- • Tranzisztorok helyettesítése
- • BEKO Mosó/Szárító gép
- • Vezeték nélküli hangátvitel
- • Muzeális készülékek-alkatrészek restaurálása
- • Mobiltelefon hiba
- • Li-Ion saját akkucsomag készítése
- • FOK-GYEM TR9178 tápegység
- • Háromfázisú aggregátor
- • Autós erősítős kérdések, problémák
- • Távirányító javítás
- • VF3 - 6 végerősítő
- • Lemezjátszó beállítása, javítása
- • Padlófűtés vezérlés
- • Számítógépes áramkörszimuláló programok
- • Videoton EA-7386-s erösítő
- • Kombikazán működési hiba
- • Felajánlás, azaz ingyen elvihető
- • Suzuki Swift elektronika
- • Páraérzékelő szenzor
- • VIDEOTON RT (RA) 6380S
- • Nextion érintőképernyős HMI, UART kommunikációval
- • Hangsugárzó építés, javítás - miértek, hogyanok
- • Alternativ HE találkozó(k)
» Több friss téma
|
Fórum » AVR - Miértek hogyanok
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
Lényegében erre. Még annyi, hogy programozni simán az RX-TX-en keresztül soros porton lehet így?
Milyen programozo? Nekem az AVR-Doper STK500V2 kompatibilis programozommal volt ilyen gondom a napokban. Windows7 alatt nem volt jo a gyari Doper driver. Ez a driver megoldotta a problemat azonnal. De annyi lenyegi kulonbseggel, hogy en 32biten csinaltam. Win8 alatt nekem az AVR doper 64 bit-en eddig sehogy sem kelt eletre.
Nem jellemző. Belső órajel esetén a soros kommunikáció bizonytalan...
Huh, ez a 60 nap alatt arduino ez nagyon csábító és valószínűleg összeszedem magam pár napon belül és elkezdem. Köszönöm szépen.
Esetleg tudnál tippet adni hogyan lehet megoldni a programozást a lehető legegyszerűbben?
És most mit értesz programozás alatt?
Jelenleg egy Arduino kitem van. Ezen van USB-RS232 átalakító alapból. Szeretnék több ilyet készíteni ipari felhasználásra. Azt nem tudom hogy kéne majd az IC-kbe a programot tölteni? Mindegyik panelre tervezzem rá az USB-RS232 átalakítót?
Köszi, kipróbáltam de sajnos így sem akar sikerülni .
Legalábbis az avrcdc_inf.zip az nem.
A számítógép kiírja, hogy a driver naprakész, csak hát ugye nincsennek elektronikus aláírások.
Ez eddig a windows xp-nél nem volt követelménx és sikerült is.
Külső STK500-assal és Arduino 1.x...
Ipari felhasználás? Maga az Arduino szoftverkörnyezet alkalmatlan a 24/7 üzemre. A Hardware -ről nem is beszélve... .
PLC programozó vagyok. Sok olyan "gépet" készítek ahova sok esetben nagyon drága és felesleges a PLC, bőven elég volna egy arduino. Itt maximum heti 5 napot üzemelne és max 12órát naponta.
Hát határeset. De mind a HW, mind a szoftver elég jelentős átdolgozást igényelne....
_nem_ ilyen feladatra találták ki...
(#) |
Ami hozzászólása |
Máj 11, 2013 |
|
/ |
|
|
Atmega8-cal szeretnék egy kivezérlés jelzőt. Ami működik is, csak a "peak" funkciót nem tudom valahogy megoldani. Már sok mindennel próbálkoztam. Hogyan lehet megoldani, hogy az utolsó led égve maradjon pár másodpercig.
Mellékelve a X akarhanyadik verzió kódja.
#define F_CPU 8000000UL
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#define LEDH (1<<PIND7)
#define LEDG (1<<PIND6)
#define LEDF (1<<PIND5)
#define LEDE (1<<PIND4)
#define LEDD (1<<PIND3)
#define LEDC (1<<PIND2)
#define LEDB (1<<PIND1)
#define LEDA (1<<PIND0)
#define TCNT1 _SFR_IO16(0x2C)
int val = 0, var = 10, adc = 0, peak_on = 1, dot_on = 0;
// =============================================================
void kesleltet(unsigned char val)
{
for(uint8_t i=0; i<var; i++)
{
_delay_ms(val);
}
}
// =============================================================
unsigned char Beolvas8bitADC(unsigned char csatorna)
{
ADMUX = (ADMUX & 0b11110000) | csatorna; // ADC csatorna kivalasztasa
ADCSRA |= (1<<ADSC); // ADC konverzio elinditasa
while (ADCSRA & (1<<ADSC)); // varas az atalakitasra
ADCSRA |= (1<<ADSC); // konverzió elindítás
while (ADCSRA & (1<<ADSC)); // varas az atalakitasra
return (ADCH); // ADC ertek visszaadasa (csak a felso 8 bit (ADCH), az also 2 zajos bit elhagyasa)
}
// =============================================================
void kijelez(unsigned int adc)
{
int level=0x00, dot=0x00, peak=0x00;
// Timer
TCCR1B |= (1<<WGM12)|(1<<CS11)|(1<<CS10); // CTC mode, preselect ratio : 64
//TCNT1 = 0; // timer1 szamlaloja legyen 0
OCR1A = 31249; // timer1 Compare A (31250) 1Hz ! 0...31249 az pont 31250
TIMSK |= (1<<OCIE1A); // timer1 Compare Match A megszakitas bekapcsolas
sei(); //megszakítás bekapcsolás
if ( adc < 1 ) { level=0b00000000; dot=0b00000000; }
else if ( adc < 32 ) { level=0b00000001; dot=0b00000001; }
else if ( adc < 64 ) { level=0b00000011; dot=0b00000010; }
else if ( adc < 96 ) { level=0b00000111; dot=0b00000100; }
else if ( adc < 128 ) { level=0b00001111; dot=0b00001000; }
else if ( adc < 160 ) { level=0b00011111; dot=0b00010000; }
else if ( adc < 192 ) { level=0b00111111; dot=0b00100000; }
else if ( adc < 224 ) { level=0b01111111; dot=0b01000000; }
else { level=0b11111111; dot=0b10000000; }
if ( peak<dot ) { peak=dot; }
if ( TCNT1>5 ) { peak=dot; TCNT1=0; }
if ( dot_on == 1 ) { PORTD = dot; } else { PORTD = level; }
if ( peak_on == 1 ) { PORTD |= peak; }
//PORTD &= ~0b11111111-peak;
}
// =============================================================
int main(void)
{
DDRD=0xFF; // Összes D port Kimenet (Függőleges 8)
DDRB=0XFF; // Összes D port Kimenet (Vízszintes 6)
DDRC &= ~(1<<PC0); // PC0-as lab bemenet ADC
/*DDRC &= ~(1<<PC1); // PC1-es lab bemenet ADC
DDRC &= ~(1<<PC2); // PC2-as lab bemenet ADC
DDRC &= ~(1<<PC3); // PC3-as lab bemenet ADC
DDRC &= ~(1<<PC4); // PC4-as lab bemenet ADC*/
//DDRC &= ~(1<<PC5); // PC5-as lab bemenet ADC
PORTC = 0x00; // PORTC osszes laban a felhuzoellenallasok kikapcsolva
PORTB = 0x00; // PORTC osszes laban a felhuzoellenallasok kikapcsolva
PORTD = 0x00; // PORTC osszes laban a felhuzoellenallasok kikapcsolva
// 8 bit ADC beallitas lefuttatasa
ADMUX |= (1<<REFS0)|(1<<ADLAR); // Vcc mint referencia, balra rendezett ADC eredmeny
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // ADC engedelyezese, ADC eloosztas = 8 (125 KHz)
while(1)
{
adc = Beolvas8bitADC(0); PORTB=0x01; kijelez(adc);
/*
adc = Beolvas8bitADC(1); PORTB=0x02; kijelez(adc);
adc = Beolvas8bitADC(2); PORTB=0x04; kijelez(adc);
adc = Beolvas8bitADC(3); PORTB=0x08; kijelez(adc);
adc = Beolvas8bitADC(4); PORTB=0x10; kijelez(adc);
*/
//adc = Beolvas8bitADC(5); PORTB=0x20; kijelez(adc);
/* */
}
return (0);
}
Én valahogy így csinálnám:
int old_dot = 0 // előző érték tárolása
….
// =============================================================
void kijelez(unsigned int adc)
{
int level=0x00, dot=0x00, peak=0x00;
// Timer
TCCR1B |= (1<<WGM12)|(1<<CS11)|(1<<CS10); // CTC mode, preselect ratio : 64
//TCNT1 = 0; // timer1 szamlaloja legyen 0
OCR1A = 31249; // timer1 Compare A (31250) 1Hz ! 0...31249 az pont 31250
TIMSK |= (1<<OCIE1A); // timer1 Compare Match A megszakitas bekapcsolas
sei(); //megszakítás bekapcsolás
if ( adc < 1 ) { level=0b00000000; dot=0b00000000; }
else if ( adc < 32 ) { level=0b00000001; dot=0b00000001; }
else if ( adc < 64 ) { level=0b00000011; dot=0b00000010; }
else if ( adc < 96 ) { level=0b00000111; dot=0b00000100; }
else if ( adc < 128 ) { level=0b00001111; dot=0b00001000; }
else if ( adc < 160 ) { level=0b00011111; dot=0b00010000; }
else if ( adc < 192 ) { level=0b00111111; dot=0b00100000; }
else if ( adc < 224 ) { level=0b01111111; dot=0b01000000; }
else { level=0b11111111; dot=0b10000000; }
if (old_dot > dot) {dot += old_dot; old_dot = dot} // Régi Max érték hozzáadása, Új érték tárolása.
if ( peak<dot ) { peak=dot; }
if ( TCNT1>5 ) { peak=dot; TCNT1=0; }
if ( dot_on == 1 ) { PORTD = dot; } else { PORTD = level; }
if ( peak_on == 1 ) { PORTD |= peak; }
//PORTD &= ~0b11111111-peak;
}
// =============================================================
Üdv!
MEgoldottam a korábbi "morse kódolás" problémát zombee javaslata alapján. PC-n működik is az elgondolás, ATmega8-on viszont az istenért sem... Azt vettem észre, hogy ott borul a dolog, hogy a cw_chars tömbből való adatkinyerésnél mindig 0xff jön, bármelyik elemre. Mi okozhatja ezt szerintetek? Így próbáltam ellenőrizni UART-on és soros porton keresztül. Az 'A' betű helyett pedig a soros terminálon csak egy 0xff jelenik meg. A soros beállítások biztos, hogy jók, mert ha UARTDataSend('A'); -t írok az szépen átmegy. Hol lehet a hiba?
Hali
Szeretnék segítséget kérni. Atmega 128-on kódolok. Már egy létező könyvtárat is használok. Így sajnos szükségem lett olyan változóra ami átjárást biztosít két C file között. Erre tudtok nekem ajánlani valami megoldást?
main-ből szeretnék elérni egy másikat. A hozzászólás módosítva: Máj 11, 2013
Sajnos nem úgy működik ahogy kellene. 6 oszlop van. mindegyiknek külön peak-ja van. De egysoron sem úgy működik, ahogy szeretném. amúgy a dot, és level mód jól megy csak a peakkal van gond. 5-10 másodpercig tartani kéne a legfelső led-et. tud valaki valami hasonló linket vagy ötletet?
#define F_CPU 8000000UL
#include <avr/interrupt.h>
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#define TCNT1 _SFR_IO16(0x2C)
int val = 0, var = 10, adc = 0, peak=0, peak_on = 1, dot_on = 0;
// =============================================================
void kesleltet(unsigned char val)
{
for(uint8_t i=0; i<var; i++)
{
_delay_ms(val);
}
}
// =============================================================
unsigned char Beolvas8bitADC(unsigned char csatorna)
{
ADMUX = (ADMUX & 0b11110000) | csatorna; // ADC csatorna kivalasztasa
ADCSRA |= (1<<ADSC); // ADC konverzio elinditasa
while (ADCSRA & (1<<ADSC)); // varas az atalakitasra
ADCSRA |= (1<<ADSC); // konverzió elindítás
while (ADCSRA & (1<<ADSC)); // varas az atalakitasra
return (ADCH); // ADC ertek visszaadasa (csak a felso 8 bit (ADCH), az also 2 zajos bit elhagyasa)
}
// =============================================================
void kijelez(unsigned int adc)
{
int level=0, dot=0;
if ( adc < 1 ) { level=0b00000000; dot=0b00000000; }
else if ( adc < 32 ) { level=0b00000001; dot=0b00000001; }
else if ( adc < 64 ) { level=0b00000011; dot=0b00000010; }
else if ( adc < 96 ) { level=0b00000111; dot=0b00000100; }
else if ( adc < 128 ) { level=0b00001111; dot=0b00001000; }
else if ( adc < 160 ) { level=0b00011111; dot=0b00010000; }
else if ( adc < 192 ) { level=0b00111111; dot=0b00100000; }
else if ( adc < 224 ) { level=0b01111111; dot=0b01000000; }
else { level=0b11111111; dot=0b10000000; }
if ( peak<dot ) { peak=dot; }
if ( TCNT1>10 ) { peak=dot; TCNT1=0; }
if ( dot_on == 1 ) { PORTD = dot; } else { PORTD = level; }
//if ( peak_on == 1 ) { PORTD = peak; }
}
// =============================================================
int main(void)
{
DDRD=0xFF; // Összes D port Kimenet (Függőleges 8)
DDRB=0XFF; // Összes B port Kimenet (Vízszintes 6)
DDRC &= ~(1<<PC0); // PC0-as lab bemenet ADC
DDRC &= ~(1<<PC1); // PC1-es lab bemenet ADC
DDRC &= ~(1<<PC2); // PC2-as lab bemenet ADC
DDRC &= ~(1<<PC3); // PC3-as lab bemenet ADC
DDRC &= ~(1<<PC4); // PC4-as lab bemenet ADC
DDRC &= ~(1<<PC5); // PC5-as lab bemenet ADC
PORTC = 0x00; // PORTC osszes laban a felhuzoellenallasok kikapcsolva
PORTB = 0x00; // PORTB osszes laban a felhuzoellenallasok kikapcsolva
PORTD = 0x00; // PORTD osszes laban a felhuzoellenallasok kikapcsolva
// 8 bit ADC beallitas lefuttatasa
ADMUX |= (1<<REFS0)|(1<<ADLAR); // Vcc mint referencia, balra rendezett ADC eredmeny
ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0); // ADC engedelyezese, ADC eloosztas = 8 (125 KHz)
// Timer indítása
TCCR1B |= (1<<WGM12)|(1<<CS11)|(1<<CS10); // CTC mode, preselect ratio : 64
TCNT1 = 0; // timer1 szamlaloja legyen 0
OCR1A = 31249; // timer1 Compare A (31250) 1Hz ! 0...31249 az pont 31250
TIMSK |= (1<<OCIE1A); // timer1 Compare Match A megszakitas bekapcsolas
sei(); //megszakítás bekapcsolás
while(1)
{
adc = Beolvas8bitADC(0); PORTB=0x01; kijelez(adc);
adc = Beolvas8bitADC(1); PORTB=0x02; kijelez(adc);
adc = Beolvas8bitADC(2); PORTB=0x04; kijelez(adc);
adc = Beolvas8bitADC(3); PORTB=0x08; kijelez(adc);
adc = Beolvas8bitADC(4); PORTB=0x10; kijelez(adc);
adc = Beolvas8bitADC(5); PORTB=0x20; kijelez(adc);
}
return (0);
}
"TCNT1" Nem működik jól. Vagyis nem tudom beállítani. Kell neki valami külső órajel? Hogy kell használni? Mit kell bekötni? Atmega8
A kóddal kapcsolatban lenne néhány kérdésem:
#define TCNT1 _SFR_IO16(0x2C)
Miért nem bízod a gcc-re, hogy beállítsa a TCNT1-et, miért kell felüldefiniálni, ahelyett, hogy TCNT1L-t használnál?
Miért kapcsolod be a megszakítást, ha ISR nincs hozzá definiálva? A viselkedés C fordító függő, de akár a RESET-re is ugorhat definiálatlan interruptnál.
//if ( peak_on == 1 ) { PORTD = peak; }
Ez ki van kommentezve, így nem fog működni.
Egyébként valamikor nullázni is kellene, mert beáll maximumra, utána szevasz. Az sem teljesen világos, hogy a 6 ADC-re egy peak-et akarsz-e, vagy 6-ot? A hardvert nem ismerjük. Jelenleg a 6 ADC közül a legnagyobbra rááll és úgymarad. A hozzászólás módosítva: Máj 13, 2013
A "TCNT1"-et még nem nagyon ismerem, mert még nem használtam.
Végül kihagytam a kódból. Másképp oldottam meg. int n = 0, val = 0, var = 1, adc = 0, peak=0, peak_on = 1, dot_on = 0;
int peak0 = 0, peak1 = 0, peak2 = 0, peak3 = 0, peak4 =0, peak5 =0;
Lejebb a kijelezben:
if ( peak<dot ) { peak=dot; }
if ( n>10 ) { peak=dot; n = 0; }
if ( dot_on == 1 ) { PORTD = dot; } else { PORTD = level; }
if ( peak_on == 1 ) { PORTD |= peak; }
Aztán a mainban:
if ( i < 320 ) { i = i++; } else { n = n++; i = 0; } // 8Mhz-nál kb 1 másodperc
A 320 Kb 1 másodperc n értéke mondjuk 5 akkor az kb 5 másodperc. Nem pontos, de az itt most nem is fontos.
egyel mostmár működik Sőt a többivel is csak még a peak nincs szétválasztva 1 peak van az egészen a legmagasabb érték.
A hardver egyszerű: 1db ATmega8 6db bc549c (Bázisra záró nyitó ellenálás.) az oszlopoknak, a Bport vezérli. Sorokat a dport vezérli ellenáláson keresztül. 6x8as Led mátrix. egyszerre 1 oszlop világít, de folyamatosnak látszik még kamerán is. Bemenet DRC=PC0-PC5 Persze még kell gomb a módváltáshoz. Ja meg a peakok szétválasztása.
A kód azért össze vissza mert sok kisérletezés benne maradt.
Úgy látom, a C-vel is vannak gondjaid.
int peak[6];
void kijelez(unsigned int adc, unsigned char peakIndex)
{
...
peak[peakIndex]
...
}
kijelez(adc,0);
int main(void)
{
int j;
for( j=0; j < 6; j++ )
peak[j] = 0;
...
}
A tömböket érdemes használni, olvass utána. A hozzászólás módosítva: Máj 13, 2013
Meg ugye a for ciklus + shift művelet (1<<3, ami pontosan kettő a harmadikon).
Érdemes lenne elolvasni egy alap C könyvet és a programodat ennek megfelelően átírni.
while(1)
{
int i;
for(i=0; i < 6; i++)
{
adc = Beolvas8bitADC(i); PORTB=1 << i; kijelez(adc);
}
}
Sziasztok!
Egy kristállyal hogyan lehet ellátni több avr-et óralellel?
Mit kell beállítani azon az avr-en amin van a kristály, és azokon amelyeken nincs? Melyik lábat kell összekapcsolni melyikekkel, amelyeken nincs kristály, illetve amelyiken van?
1: a "forrás" AVR-en a "CKOPT" nevű FUSE bitet kell beállítani, ha nincs akkor "Full-Swing" legyen!
2: a "cél" AVR-eket külső órajelre kell beállítani, azaz "ext. clock".
3: az XTAL2 kimenet(forrás), az XTAL1 bemenet(cél).
4: maximum 4-5 "cél" AVR lehet, ha több kell akkor használj erősítőt!
5: ha az XTAL1-2 portláb, ilyen a beállításnál az XTAL2-t sem tudod használni. A hozzászólás módosítva: Máj 13, 2013
Rendben, Köszönöm. Hát igen nem tudok még mindent. ATmega8 belső órájáráiról van valami magyar nyelvű leírás?
Könnyebb lenne, ha elmondanád, hogy mire szeretnéd az órát használni, túl sok magyar leírás nincs.
Emellett megfelelően bonyolult is kezdőknek.
- lehet előosztást beállítani, hogy lassabban számoljon (adott értékekre)
- beállíthatod, hogy 0-tól meddig számoljon
- két lábat irányíthatsz egy timerrel PWM (impulzusszélesség moduláció), definiálhatod, hogy a lábak az IC-n hogyan változzanak túlcsordulásnál, adott szint elérésénél
- beállíthatsz megszakításokat, hogy a timer bizonyos eseményeknél a programszámlálót ugrassa máshová
- számolhatsz külső éleket is (felfutó/lefutó)
- leálíthadod / elindíthatod
Elég ravasz dolgokat lehet velük csinálni. A vasúti átjáró váltakozó piros villogását egy timerrel megcsinálhatod hardverből, úgy hogy a program semmit sem csinál, kizárólag az IC hardvere végez mindent.
Pl órakészítésre. De minden érdekelhet. AVR-eknél minden működik ami a C-ben álltalában?
Itt egy magyar nyelvű C könyv.
A printf, scanf, fájlkezelés, szöveges képernyő és grafika értelemszerűen nem fog menni AVR alatt. A könyv középiskolásoknak íródott, nem okozhat problémát.
A C nyelv egyébként ugyanaz, csak másképpen használják AVR alatt. Amikor 8GB memóriád van, másképpen programozol, mint amikor csak 512 byte. Ráadásul 32/64 bites processzor alatt is minden más, mint 8 bites alatt.
A lebegőpontos (float/double) típusokkal AVR alatt csak óvatosan. Lassú és nagy kódot fog eredményezni, lehet, hogy jobban megéri mindent egészként számolni, de ahol tizedes kellene, ott megszorzod 100-zal, így 2 számjegyes pontosságot kapsz. PC-n mindez hardverből megy, ezért ott nyugodtan használhatsz ilyen típusokat, AVR alatt csak módjával. A hozzászólás módosítva: Máj 14, 2013
|
|