====== PB171 (2018) ====== * Taught in english/czech * 2 + 1 credits (colloquium) - home preparation supposed * Attendance - up to one unjustified absence * Defence - practical tasks + consultations * Contact: Zdeněk Matěj, xmatej@fi.muni.cz, B401 ===== Content ===== * Architecture of 8-bit controllers (PIC18 family). * Assembly language for target platform. * General purpose I/O. * Timers and interrupt handling. * EEPROM handling. * Applications of the analog-digital converter. * C language compiler for 8-bit platforms. * Using C language for target platform- * Controlling shift register. * Bus drivers: UART, SPI, I2C. * Advanced peripherals. * Semestral project. ===== Dokumentation ===== * [[http://ww1.microchip.com/downloads/en/DeviceDoc/50002053E.pdf|XC8 dokumentace]] * Seznámení s kitem YuniPIC - {{ :pb171:yunipic_1.1_scheme.pdf | YuniPIC 1.1 - schéma}} * [[http://ww1.microchip.com/downloads/en/DeviceDoc/40001412G.pdf|Datasheet PIC18f46k22]] ===== 1. lecture ===== * {{ :pb171:mcu_intro.pdf | Introduction}} ===== 2. lecture ===== * MPLAB + XC8 * ++ Basic configuration PIC18f46k22| #pragma config WDTEN = OFF #pragma config FOSC = INTIO7 #pragma config MCLRE = EXTMCLR #pragma config FCMEN = ON ++ * I/O - TRISx, PORTx, LATx * {{ :pb171:02_hodina.zip |Example project}} * Ex. 1 - rozblikejte LED diodu pomocí blokujícího čekání * Ex. 2 - vytvořte světelného hada * Ex. 3 - pomocí tlačítka řeště přepínání LEDek mezi dvěma stavy (použijte debouncing) * ++ Reseni| void main(void) { char stav = 0; char stisknuto = 0; char smer = 1; init(); LATD = 1; while(1){ if (!PORTBbits.RB0){ DelayMs(10); if (!PORTBbits.RB0){ if (!stisknuto){ if (stav == 0) stav = 1; else stav = 0; stisknuto = 1; } } else stisknuto = 0; } if (stav) LATD = 255; else LATD = 0; /* if (smer) LATD = LATD << 1; else LATD = LATD >> 1; DelayMs(200); DelayMs(200); if (LATD == 0b10000000) smer = 0; if (LATD == 1) smer = 1; */ } } ++ ===== 3. lecture ===== * Timer0, 1, 2 * HW a SW Debug * Ex. 1 - blink LED0 with TMR0 (TMR0IF) * Ex. 2 - blink LED1 with TMR1 * Ex. 3 - blink LED2 with TMR2 ===== 4. lecture ===== * Debug * Interrupts * Ex. 1 - blink LED0 with TMR0 with interrupt * Ex. 2 - blink LED1 with TMR1 with interrupt low * Ex. 3 - blink LED2 with TMR2 with interrupt high * Ex. 4 - change blikning frequencies with BUTTON and interrupt ===== 5. lecture ===== * EEPROM * [[pb171:UART|UART]] * [[pb171:STD IO|Standardni vsup a výstup]] * [[pb171:PIC_UART|PIC UART]] * [[pb171:PIC18_UART|Ex. UART]] ===== 6. lecture ===== * ADC * DAC * Ex. 1: Pomocí POT0 ovládejte počet rozsvícených LED. Na maximum všechny na minimum žádná rozsvícena. * Ex. 2: Posílejte pomocí UART2 hodnoty načtené na potenciometrech POT0 a POT1. * Ex. 3: Podle nastavení potenciometru POT1 generujte výstupní napětí pomocí DAC. ===== 7. lecture ===== * PWM * Ex. 1: Pomocí TMR ovládejte intenzitu svitu LED diody (zhasnuto-rozsvíceno-zhasnuto...) * Ex. 2: Pomocí PWM modulu ovládejte intenzitu obdobně jako v Ex. 1 * Ex. 3: Podle nastavení potenciometru POT1 generujte nastavujt eintenzitu svitu LED diody ===== 8. lecture ===== * Display * ++ Display.c| /* * LCD interface example * Uses routines from delay.c * This code will interface to a standard LCD controller * like the Hitachi HD44780. It uses it in 4 bit mode, with * the hardware connected as follows (the standard 14 pin * LCD connector is used): * * PORTC bits 0-3 are connected to the LCD data bits 4-7 (high nibble) * PORTC bit 4 is connected to the LCD EN bit (enable) * PORTC bit 5 is connected to the LCD RW input (register write) * PORTC bit 6 is connected to the LCD RS input (register select) * * To use these routines, set up the port I/O (TRISC) then * call lcd_init(), then other routines as required. * */ #include //#include "delay18.h" //#include "delays.h" #include "simdelay.h" #define DelayUs(x) {_delay(x);} //static bit LCD_RS @ ((unsigned)&PORTA*8+3); // Register select //#static bit LCD_EN @ ((unsigned)&PORTA*8+5); // Enable //#static bit LCD_EN @ ((unsigned)&PORTA*8+5); // Enable //#define LCD_EN LATCbits.RC4 //#define LCD_RW LATCbits.RC5 //#define LCD_RS LATCbits.RC6 volatile static int LCD_RS_flag; //#define LCD_STROBE ((LCD_EN = 1),(LCD_EN=1),(LCD_EN=0)) // #define LCD_STROBE() { DelayUs(2); LATC |= 0x10; DelayUs(2); LATC = LATC & 0x0F; DelayUs(2); } #define LCD_RS(x) {if(x == 1) LATC |= 0x40; else LATC &= 0x0F;} //#define LCD_CHK() {LCD_RW = 1; LCD_RS = 0; DelayUs(2); LCD_STROBE() ; DelayUs(2); LCD_STROBE();LCD_RW = 0;DelayUs(2)} /* * write a byte to the LCD in 4 bit mode */ void lcd_write(unsigned char c) { LATC = (c >> 4); LCD_RS(LCD_RS_flag); LCD_STROBE(); DelayUs(2); LATC = c & 0xF; LCD_RS(LCD_RS_flag); LCD_STROBE(); DelayUs(50); } /* * Clear and home the LCD */ void lcd_clear(void) { LCD_RS_flag = 0; // write characters lcd_write(0x1); DelayMs(2); } /* * write a byte to the LCD in 4 bit mode */ #define lcd_putc(x) lcd_putchar(x) #define lcd_putch(x) lcd_putchar(x) void lcd_putchar(char s){ LCD_RS_flag = 1; // write characters lcd_write(s); } /* * write a string of chars to the LCD */ void lcd_puts(const char * s) { LCD_RS_flag = 1; // write characters while(*s){ lcd_write(*s++); } } /* void lcd_putsr(const rom char * s) { LCD_RS_flag = 1; // write characters while(*s){ lcd_write(*s++); } } */ /* * write byte (hex) */ void lcd_puthex(unsigned char i) { unsigned char c; LCD_RS_flag = 1; // write characters c = i >> 4; if (c>9) { lcd_write('A'-10+c); } else { lcd_write('0'+c); } c = i & 0x0F; if (c>9) { lcd_write('A'-10+c); } else { lcd_write('0'+c); } } /* * Go to the specified position */ void lcd_goto(unsigned char pos) { LCD_RS_flag = 0; lcd_write(0x80+pos); } /** * initialise the LCD - put into 4 bit mode * 4 bit mode, 2 lines */ void lcd_init(void) { LCD_RS(0); // write control bytes LCD_RS_flag = 0; DelayMs(60); // power on delay LATC = 0x03; // FN set 1 LCD_STROBE(); DelayMs(10); LCD_STROBE(); // fn set 2 DelayUs(50); LCD_STROBE(); // FN set 3 DelayUs(50); LATC = 0x2; // FN set #4 set 4 bit mode LCD_STROBE(); DelayUs(50); lcd_write(0x29); // 4 bit mode, lcd_write(0x1D); // int osc freq lcd_write(0x79); // contrast set lcd_write(0x50); // power / icon / contrast ctrl lcd_write(0x6C); // follower control lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font, radkovani lcd_write(0x0E); // display on, blink curson on lcd_write(0x01); // entry mode set lcd_write(0x06); // entry mode set return; } void lcd_init33(void) { LCD_RS_flag = 0; LCD_RS(0); // write control bytes DelayMs(60); // power on delay LATC = 0x03; // FN set 1 LCD_STROBE(); DelayMs(10); LCD_STROBE(); // fn set 2 DelayUs(50); LCD_STROBE(); // FN set 3 DelayUs(50); LATC = 0x2; // FN set #4 set 4 bit mode LCD_STROBE(); DelayUs(50); lcd_write(0x29); // 4 bit mode, //lcd_write(0x1D); // int osc freq lcd_write(0x1F); // int osc freq lcd_write(0x79); // contrast set lcd_write(0x50 + 0x04); // power / icon / contrast ctrl lcd_write(0x6E); // follower control lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font, radkovani lcd_write(0x0f); // display on, blink curson on lcd_write(0x01); // clear lcd_write(0x06); // cursor autoincrement return; } ++ * ++ Display.h | /* * LCD interface header file * See lcd.c for more info */ /* write a byte to the LCD in 4 bit mode */ extern void lcd_write(unsigned char); /* Clear and home the LCD */ extern void lcd_clear(void); /* write a string of characters to the LCD */ extern void lcd_puts(const char * s); /* ... from static string */ //extern void lcd_putsr(const rom char * s); /* Go to the specified position (second line starts at 40) */ extern void lcd_goto(unsigned char pos); /* intialize the LCD - call before anything else */ extern void lcd_init(void); /* intialize the LCD - 3.3V version */ extern void lcd_init33(void); /* print a character */ extern void lcd_putchar(char s); /* print a byte in hexa */ extern void lcd_puthex(unsigned char i); ++ * Ex. 1 - vytvořte program kde na sipleji bude zobrazeno 4 radkove menu (s rolovanim) kde bude mozne mezi polozkami listovat pomoci tlacitek a oznacovat jednotlive polozky (radio button) * Ex. 2 - doplňte příklad 1 o možnou změnu intenzity podsvícení displeje pomocí potenciometru ===== 9. lecture ===== * SPI * I2C ===== 10. lecture ===== * Keyboard 4x4 * Ex. 1 - načítejte znaky z maticové klávesnice 4x4 a načtený znak vypište na displej * Ex. 2 - vytvořte s pomocí maticové klávesnice 4x4 a displeje jednoduchou kalkulačku * Ex. 3 (bonus) - vytvořte program umožňující rozpoznávat na maticové klávesnici stisknuté dvě tlačítka současně a ty pak zobrazujte na displeji ===== 11. lecture ===== * projekt * RTC * {{:pb171:02.03.i2c.zip |Ukázka z použití na procesoru ATmega128}} * {{ :pb171:pcf8583.pdf |Datasheet RTC PCF8583}} ===== Projekty ===== * Mozer - akcni hra s displejem, potenciometry a LED * Katkin - binarni hodiny s letsim displejem a RTC * Benarova - IQRF virtualni seriova linka