====== 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