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
Ha világít egy sor, akkor a LöCöDöd működik, csak nem jól inicializálod. A hiba az önkészülékében van .
Egy forráskódot kérnénk.
Jó tanács: te határozd meg delay függvényekkel, hogy mikor jöhet a következő parancs, mert ha Busy Flag-t használod az érdekes módon nem mindig működik ahogy azt az ember elgondolta.
Az ATTiny2313-ban csak 2 időzítő van, mindkettőnek 2 kimenete, saját komparátor-regiszterrel(OCR).
Három, teljesen független PWM csatornát nem tudsz kezelni, de ha ebből kettőnél a PWM-frekvencia lehet azonos
akkor nincs akadálya. Esetleg ATMega48-at ajánlom amibe 3 timer van 2+2+2 OCR regiszterrel.
Kitöltési százalékot sehol nem lehet megadni, maximum azt hogy a számláló milyen állásainál(értékeinél) történjen valami. Először a frekvenciát kell beállítani: 2000+20000us=22ms ~45.4545Hz. Ebből, és az AVR órajeléből kell kisakkozni a számláló maximális értékét. Én 8MHz-vel számolok ha nem gond, azt beépítve tudja az ATTiny2313 és az ATMega48 is(CKDIV8 FUSE bit kikapcsolásával).
És a Timer1-el számolok, ott pontosabb értékeket meg lehet adni. Az előosztónak 64-et választom mivel 8MHz/64=125kHz, azaz a számláló pontosan 125-öt számol minden ezredmásodpercben. Ugye 22*125=2750, ebből 1-et ki kell vonni és azt kell megadni, mint a számláló TOP értéke. Az 1-es időzítőnél az ICR1-et állítsd be 2749-re!
Most jön a PWM. Az OCR1A-t állítsd be (125*2)-1=149-re! Ezután a kimenetet kell beállítanod a TCCR1A-n a COM1A1:0 biteken hogy az OCR1A eléréséig logikai 1, utána a számláló újraindításáig logikai 0 legyen. A timert a megfelelő módba kell kapcsolni olyan PWM módba, hogy a TOP az ICR1 legyen! A számlálót a TCCRB-ben az előosztó beállításával indítod el.
Hogy ne legyen kínai, leírom a beállításokat ATTiny2313-ra és ATMega48-ra ugyanúgy jó a kód:
//Plafon beállítátsa - 22ms:
ICR1 = 2749;
//Kitöltés beállítása - 2ms:
OCR1A = 249;
//időzítő mód beállítása és a timer indítása - előosztó=64 :
TCCR1B = 1<<WGM13 | 1<<WGM12 | CS11 | CS10;
//időztő mód(WGM11 és WGM10 marad 0-ban), és kimenet(OC1A) beállítása:
TCCR1A = 1<<COM1A1;
A logikai 1 és 0 értékeket felcserélheted, 2-féleképpen is, én a legegyszerűbbet írom le:
OCR1A = 2499; //(125*20)-1
Megjegyzés: PWM módoknál az értékek a timer újraindulásakor(TOP elérésekor) érvényesülnek.
Másik megoldás a kimenet polaritásváltása(COM1A1:0 átállíátsa), de a változtatás azonnal életbe lép!
Működik!! Találtam itthon egy másik 2313-mat mert gondoltam hátha jó lesz. A régi chip-nek is kiolvassa rendesen a signatúráját, de azzal nem jó. Köszönöm szépen mindenki segítségét
De igen azt írtam bele utoljára most ki is írja hogy Hello Sz. Dani. csak gondtam elküldöm neki azt a projektet amit direkt 2313hoz írt valaki és én azzal is próbáltam.
valami nem akar működni... Szoftveresen tökéletesen működik a pwm, de sajnos ezzel sem(próbáltam pár netes jódot is...), ezt a kódot égettem be:
#define F_CPU 8000000
#include <avr/io.h>
int main(void){
DDRB = (1<<PINB3);
//Plafon beállítátsa - 22ms:
ICR1 = 2749;
//Kitöltés beállítása - 2ms:
OCR1A = 249;
//időzítő mód beállítása és a timer indítása - előosztó=64 :
TCCR1B = 1<<WGM13 | 1<<WGM12 | CS11 | CS10;
//időztő mód(WGM11 és WGM10 marad 0-ban), és kimenet(OC1A) beállítása:
TCCR1A = 1<<COM1A1;
}
A jel egy RC szervóhoz és egy ledhez megy, a led nem is világít, így valami gond van, a kimenet az OC1A, azaz a PB3 ha jól gondolom... Végignéztem a többi kimenetet is, de sehol semmi...
Egész délután ezzel az egyszerű dologgal küszködök, sajnos elég hiányos az elérhető dokumentáció is a neten...
Pontosan mit szeretnél csinálni a szevóval? Mert én régebben töltöttem le egy rajzot, attini2313-ra van kötve egy szervó, 4 nyomógomb amivel vezérled, meg van egy lcd-je ami kiírja mi történik de az nem lényeg rá. Ha valami ilyet szeretnél eltudom küldeni
Egyenlőre csak annyit, hogy hardweres pwm-el elő tudjam állítani a megfelelő vezérlőjelet, és értsem is hogyan működik... Utána egy ADC-vel rákötnék egy potit, majd azzal vezérelném az egészet, végül jönne az lcd is... Már msp430 as kittel megcsináltam az egészet, de most váltottam nem rég AVR-re...
Bocsánat! CTC módban fut az időzítőd, rossz értéket adtam meg. Bár ettől még működhetne...
De ejtettél egy végzetesebb hibát: a program futása soha nem érhet véget, a main() fv. végére tegyed be:
while(1);
Illetve mondom a helyes timer beállítást. Egyedül a TCCR1A-s sort kell módosítani:
Két hiba is van, este nem vettem észre. Egyiket Te ejtetted, másikat én, és pont ugyanaz a hiba.
Persze ilyenkor mindenki arra gondol kínjában hogy talán az AVR nem jó(én is).
Az ISP inkább egy programozási felület, nem szokás bootloadernek hívni. Ha a RESETDISBL vagy az ISPEN nevű FUSE bitek valamelyike el lett állítva, az csak nagyfeszen(HVPP) javítható.
A legegyszerűbb ilyen eszköz a HVPP Fuse bit Doctor, erre rákeresve meglesz a kapcsrajz is.
Ezen kívül a gyári STK500(és HVPP-képes klónjai, pl. a sajátom vagy a der-hammer féle), illetve AVR Dragon.
Bootloader nem szokott SPI-n kommunikálni. Általában Rx/TX-en, mint pl. az Arduino vagy az Evertool.
Vagy USB-n (pl. USBBOOT), illetve hardveres USB-vel rendelkező AVR-ek esetében a FLIP bootloader.
ATMega8 esetében a Doper nem lesz jó HVPP-re, azzal csak HVSP-t lehet(ami a kisebb Tiny-khoz jó).
A legegyszerűbb amit építhetsz erre, az egy HVPP Fusebit Doctor, kb. ugyanannyira bonyolult mint a Doper.
Egyfajta program az AVR-ben ami bizonyos feltételek esetén kommunikál valamilyen csatornán(lehet USART, SPI, I2C, USB), és rajta keresztül betölti azt a kódot amit a boot-feltétel nem-teljesülése esetén futtatni fog.
Persze a bootloadert is be kell égetni és a BOOTRST-t meg a kezdőcímet beállítani.
Meg is kell írni/módosítani a bootloader kódját ha pl. az induló feltételt állítanád be.
A legjobb példa erre az Arduino és a JTAG-ben használt Evertool.
A legtöbb AVR-hez elérhető a szintén avr910-kompatíbilis bootloader(pl. az Evertool is az).
Ha már avr910: általában lefoglal egy portlábat, és bekapcsoláskor azt figyeli hogy le van-e húzva.
Ha nincs akkor a bootloader a kezdőcímre ugrik(magyarul: kilép), ha igen akkor avr910-es programozóként viselkedik és önmagát programozza.
A programozás végén általában újra kell indítani az AVR-t, és a bootloader aktiválásához is kézzel RESET-elni kell tehát nem lesz egyszerűbb.
Olyan eszközöknél használnak bootloadert amelyeket néha(inkább nagyon ritkán vagy soha) frissíteni is kell, és azt a meglévő(tehát RS-232, USB, CAN-busz, stb.) csatlakozáson egy egyszerű program lefuttatásával külső segédeszköz(pl. AVR-programozó) nélkül lehet megejteni.
Nekem is lenne egy kérdésem a GSM-modullal, mert éppen egy konzolos eszközt(PC interfész) kellene programoznom. A GSM-modul esetében az AT parancsokat vagy egy ENTER(azaz , 13-as ASCII-kód) zárja ha kézzel programozod, de automata(pl. AVR-ből) programozásnál már egy \n (ez egy , 10-es ASCII-kóddal).
A kérdésem hogy lényegében mindkettő zárhat egy utasítást?
Gyönyörű! Az első változatom megépítése is tovább tartott és csak drótoztam, tervezésre nem futotta(1. kép).
De végül 2 hét alatt csak-csak elkészült egy maratott verzió 3 darab foglalattal(2. kép).
Betölteni egy szűz AVR-re csak programozóval(ISP, JTAG) lehet.
A bootloader elvileg felülírhatja magát, de minden pillanatban csak olyan szektort írhat amin
éppen nem fut a program. Egy szektor mérete jelen ismereteim szerint a BOOTSZ nevű FUSE bitek által legkisebb értékre beállítható terület. Hülye megfoglamazás tudom, ATMega32-nél ez 256 bájt. Tehát a maximális, 2048 bájtos bootloader esetében bármely, megadott állapotban 7 darab bootloaderes szektort írhatsz...
A kommunikációs rész is lecserélhető ha az új programkódot a kommunikációs rész az SRAM-ba vagy EEPROM-ba tárolja le, egy másik szektorba pedig lehet az a kód ami onnan kiolvassa és flasheli...