Při zapojování MCU 1. zapojte všechny napájecí piny a všechny vybavte 100nF kondenzátorm ci nejblíže 2. nepřehoďte napájení 3. nepřehoďte napájení 4. nepřehoďte napájení Bitové operace: | - OR "ořítko" - bitový součet & - AND ("andítko") - bitový součin ~ - NOT - bitová negace ^ - XOR (bitový XOR) >> - itová rotace vpravo << - bitová rotace vlevo neplést s logickými operátory jako jsou || && ! == != termín "nastavení" (SET) znamená zapsat do bitu hodnotu 1 termín "nulování" (CLEAR) znamená zapsat do bitu hodnotu 0 Příklady: x = x | (1<<6); // nastavení 6.bitu v proměnné x x |= (1<<6); // zkrácený zápis téhož // nastavení 3. a 4. bitu v proměnné x x |= 0b00011000; // nepřehledně x |= (1<<3) | (1<<4); // přehledněji x |= MACRO_bm | MACRO_bm; // nejpřehledněji pokud jde o registry - viz slovní komentář // vynulování 2.bitu v proměnné x x &= 0b11111011; // nepřehledně x &= ~(1<<2); // přehledněji x &= ~MACRO_bm; // nejpřehledněji pokud jde o registry - viz slovní komentář // vynulování tří nejnižších bitů v proměnné x x &= ~0b111; // nepřehledně, zkráceně x &= ~0b00000111; // nepřehledně zdlouhavě x &= ~MACRO_gc; // přehledně v registrech - viz slovní komentář Přepsání kombinace více bitů v registru nelze udělat jedním příkazem. Nejbezpečnější cesta je následující: 1. načíst obsah registru do proměnné 2. vynulovat v proměnné všechny bity (skupinu) které chceme přepsat 3. nastavit ve skupině ty bity které mají mít hodnotu 1 4. zapsat obsah proměnné zpět do registru Makra končící: _bm - Bit Mask, slouží k nastavení nebo nulování jednoho bitu (ČASTO POUŽÍVANÉ) _bp - Bit Position, typicky nepoužijete, obsahují pořadové číslo bitu _gm - Group Mask, slouží k nulování skupiny bitů _gc - Group Combination, slouží k zápisu hodnot do skupiny bitů (ČASTO POUŽÍVANÉ) _gp - Group Position, typicky nevyužijete, obsahují pořadové číslo nejnižšího bitu skupiny způsob pojmenování bitových masek je následující NazevPeriferie_NazevBitu_bm NazevPeriferie_NazevSkupinyBitu_gc Například: USART_TXEN_bm - USART, bit TXEN CLKCTRL_MCLKCTRLB_PDIVxxxx_gc - kombinace skupiny bitů PDIV v registru MCLKCTRLB Přístupy k registrům: NazevPeriferie.NazevRegistru Například: PORTF.OUTSET = xxxxxx; ADC0.CTRLA |= ADC_ENABLE_bm; // nastavuje bit ENABLE v registru CTRLA v ADC0 USART0.CTRLB &=~USART_TXEN_bm; // nuluje bit TXEN v registru CTRLB v USART0 Některé registry jsou chráněné proti přepisu a je nutné je odemčít (ideálně s využitím makra _PROTECTED_WRITE) Makra pro piny jsou vyjímkou a neobsahují na začátku text PORT_ a jsou jen: PIN0_bm PIN1_bm ... Práce s porty (ukázky píšu pro PORTA) PORT reflektuje stav registrů OUT a DIR, registry OUTSET,OUTCLR,OUTTGL,DIRSET, DIRCLR,DIRTGL slouží jen k manipulaci s registry OUT a DIR PORTA.DIR = PIN0_bm; // nastaví PA0 jako výstup a ostatní piny (PA1 až PA7) jako vstup !!! PORTA.DIR |= PIN0_bm; // nastaví PA0 jako výstup a ostatní piny nijak nemění - neoptimální postup PORTA.DIRSET = PIN0_bm; // nastaví PA0 jako výstup, ostatní piny nemění - optimální postup PORTA.DIRSET = PIN0_bm | PIN1_bm; // nastaví PA0 a PA1 jako výstup, ostatní piny nemění PORTA.DIRCLR = PIN1_bm; // nastaví PA1 jako vstup, ostatní piny nemění PORTA.OUTSET = PIN1_bm; // Zapíš na pin PA1 úroveň "1" (pokud je pin nastaven jako výstup) PORTA.OUTCLR = PIN0_bm | PIN1_bm; // Zapíše na pin PA0 a PA1 úroveň "0" (pokud je pin nastaven jako výstup) PORTA.OUTTGL = PIN0_bm; // změní hodnotu na pinu PA0 na opačnou PORTA.OUT = 0b11110001; // zapíše stav výstupů celého PORTA (relevantní jen na pinech, které jsou nastaveny jako výstup) x=PORTA.IN; // přečte stav celého portu (všech pinů) do proměnné x if(PORTA.IN & PIN1_bm){} // vykoná tělo podmínky pokud je na pinu PA1 hodnota "1" PORTA.PIN0CTRL |= PORT_PULLUPEN_bm; // aktivuje vnitřní pullup na pinu PA0 PORTA.PIN0CTRL |= PORT_INVEN_bm; // invertuje pina PA0 PORTA.PORTCTRL = PORT_SRL_bm; // aktivuje "slew rate limit" na PORTA Rady: Dávejte pozor na rozdíl mezi = a |= při konfiguraci registrů. Vyhýbejte se nečitelným zápisům ve stylu REG = 123 (používejte makra) Komentáře: // - řádkový komentář (používejte častěji) /* víceřádkový komentář */ Komentujte a dělejte to smysluplně, například následující komentáře je "nahovno" PORTA.OUTSET = PIN0_bm; // nastavuje PA0 do úrovně "1" To totiž každý vidí už z kódu. Mnohem smysluplnější je třeba PORTA.OUTSET = PIN0_bm; // zapíná Relé čerpadla Přemýšlejte u komentářů, buďte struční, ale výstižní. Své komentáře budete číst za pár let sami a vůbec si nebudete pamatovat jak program fungoval. Příklady nastavení clocku: _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB,CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm); // Zapnout děličku (PEN) a Dělit clock 16ti _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA, CLKCTRL_FRQSEL_16M_gc); // přepnutí frekvence oscilátoru na 16MHz (u čipů, které mají přepínatelnou frekvenci) _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKOUT_bm | CLKCTRL_CLKSEL_OSCHF_gc); // aktivace funkce "Clock out" a volba zdroje clocku (interní "High Frekvenci" oscilátor) Některá MCU mají jen děličku (Atmega, Attiny), jiné mají děličku a ještě navíc přepínatelnou frekvenci oscilátoru (AVR DA, AVR DB...). Vždy sledujte datasheet. Stručný popis registrů o kterých jsme se bavili: CLKCTRL.MCLKCTRLA - kontroluje zdroj clocku a funkci "Clock out" (výstup clocku na pin) bit CLKOUT - aktivuje funkci clockout bity CLKSEL - volí zdroj clocku (prozatím výhradně OSCHF - interní "high Frequency" oscilátor) CLKCTRL.MCLKCTRLB - nastavuje parametry (před)děličky clocku bit PEN - aktivuje děličku bity PDIV - volí dělící poměr CLKCTRL.OSCHFCTRLA - nastavuje frekvenci interního oscilátoru (některá MCU tento registr nemají) bity FRQSEL - volí frekvenci oscilátoru bit AUTOTUNE - nechat nulové bit RUNSTDBY - nechat nulové Seznam MCU které mají UPDI - a umíte je programovat: Atmega 0-series Atmega 808 / 1608 / 3208 / 4808 (DIP40 a TQFP48) Atmega 809 / 1609 / 3209 / 4809 (DIP28 a TQFP32) Attiny 0-series Attiny 202 / 402 (SOIC8) Attiny 204 / 404 / 804 / 1604 (SOIC14) Attiny 406 / 806 / 1606 (SOIC20) Attiny 807 / 1607 (QFN?) Attiny 1-series Attiny 212 / 412 (SOIC8) Attiny 214 / 414 / 814 / 1614 (SOIC14) Attiny 416 / 816 / 1616 / 3216 (SOIC20) Attiny 417 / 817 / 1617 / 3217 (QFN?) Attiny 2-series Attiny 424 / 824 / 1624 / 3224 (SOIC14) Attiny 426 / 826 / 1626 / 3226 (SOIC20) Attiny 427 / 827 / 1627 / 3227 (QFN?) Všechny čipy rodin: AVR DA AVR DB AVR DD AVR DU AVR EA AVR EB (např AVR128DA28, AVR32DB64 ...) rozstřel mezi Attiny x-series http://www.technoblogy.com/show?3UKF tabulka od Microchipu: https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/Brochures/AVR-Microcontrollers-Peripheral-Integration-30010135.pdf materiály ke studiu: http://www.technoblogy.com/ http://www.elektromys.eu/avr1.php